blob: 56ba07b35297ebcce3280a88a291f140c5a47e4b [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
17#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18#define LOG_TAG "hwc-drm-two"
19
Sean Paulac874152016-03-10 16:00:26 -050020#include "drmdisplaycomposition.h"
21#include "drmhwcomposer.h"
Sean Pauled2ec4b2016-03-10 15:35:40 -050022#include "drmhwctwo.h"
Sean Paulac874152016-03-10 16:00:26 -050023#include "platform.h"
24#include "vsyncworker.h"
25
26#include <inttypes.h>
27#include <string>
Sean Pauled2ec4b2016-03-10 15:35:40 -050028
John Stultz9057a6f2018-04-26 12:05:55 -070029#include <log/log.h>
Sean Paulac874152016-03-10 16:00:26 -050030#include <cutils/properties.h>
31#include <hardware/hardware.h>
Sean Pauled2ec4b2016-03-10 15:35:40 -050032#include <hardware/hwcomposer2.h>
33
34namespace android {
35
Sean Paulac874152016-03-10 16:00:26 -050036class DrmVsyncCallback : public VsyncCallback {
37 public:
38 DrmVsyncCallback(hwc2_callback_data_t data, hwc2_function_pointer_t hook)
39 : data_(data), hook_(hook) {
40 }
41
42 void Callback(int display, int64_t timestamp) {
43 auto hook = reinterpret_cast<HWC2_PFN_VSYNC>(hook_);
44 hook(data_, display, timestamp);
45 }
46
47 private:
48 hwc2_callback_data_t data_;
49 hwc2_function_pointer_t hook_;
50};
51
Sean Pauled2ec4b2016-03-10 15:35:40 -050052DrmHwcTwo::DrmHwcTwo() {
Sean Paulac874152016-03-10 16:00:26 -050053 common.tag = HARDWARE_DEVICE_TAG;
54 common.version = HWC_DEVICE_API_VERSION_2_0;
Sean Pauled2ec4b2016-03-10 15:35:40 -050055 common.close = HookDevClose;
56 getCapabilities = HookDevGetCapabilities;
57 getFunction = HookDevGetFunction;
58}
59
Sean Paulac874152016-03-10 16:00:26 -050060HWC2::Error DrmHwcTwo::Init() {
Alexandru Gheorghec5463582018-03-27 15:52:02 +010061 int ret = resource_manager_.Init();
Sean Paulac874152016-03-10 16:00:26 -050062 if (ret) {
Alexandru Gheorghec5463582018-03-27 15:52:02 +010063 ALOGE("Can't initialize the resource manager %d", ret);
Sean Paulac874152016-03-10 16:00:26 -050064 return HWC2::Error::NoResources;
65 }
66
Alexandru Gheorghec5463582018-03-27 15:52:02 +010067 DrmDevice *drm = resource_manager_.GetDrmDevice(HWC_DISPLAY_PRIMARY);
68 std::shared_ptr<Importer> importer =
69 resource_manager_.GetImporter(HWC_DISPLAY_PRIMARY);
70 if (!drm || !importer) {
71 ALOGE("Failed to get a valid drmresource and importer");
Sean Paulac874152016-03-10 16:00:26 -050072 return HWC2::Error::NoResources;
73 }
74
Sean Paulac874152016-03-10 16:00:26 -050075 displays_.emplace(std::piecewise_construct,
76 std::forward_as_tuple(HWC_DISPLAY_PRIMARY),
Alexandru Gheorghec5463582018-03-27 15:52:02 +010077 std::forward_as_tuple(drm, importer, HWC_DISPLAY_PRIMARY,
Sean Paulac874152016-03-10 16:00:26 -050078 HWC2::DisplayType::Physical));
79
Alexandru Gheorghec5463582018-03-27 15:52:02 +010080 DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(HWC_DISPLAY_PRIMARY));
Sean Paulac874152016-03-10 16:00:26 -050081 if (!crtc) {
82 ALOGE("Failed to get crtc for display %d",
83 static_cast<int>(HWC_DISPLAY_PRIMARY));
84 return HWC2::Error::BadDisplay;
85 }
86
87 std::vector<DrmPlane *> display_planes;
Alexandru Gheorghec5463582018-03-27 15:52:02 +010088 for (auto &plane : drm->planes()) {
Sean Paulac874152016-03-10 16:00:26 -050089 if (plane->GetCrtcSupported(*crtc))
90 display_planes.push_back(plane.get());
91 }
92 displays_.at(HWC_DISPLAY_PRIMARY).Init(&display_planes);
93 return HWC2::Error::None;
94}
95
Sean Pauled2ec4b2016-03-10 15:35:40 -050096template <typename... Args>
97static inline HWC2::Error unsupported(char const *func, Args... /*args*/) {
98 ALOGV("Unsupported function: %s", func);
99 return HWC2::Error::Unsupported;
100}
101
Sean Paulac874152016-03-10 16:00:26 -0500102static inline void supported(char const *func) {
103 ALOGV("Supported function: %s", func);
104}
105
Sean Pauled2ec4b2016-03-10 15:35:40 -0500106HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height,
107 int32_t *format,
108 hwc2_display_t *display) {
109 // TODO: Implement virtual display
Sean Paulac874152016-03-10 16:00:26 -0500110 return unsupported(__func__, width, height, format, display);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500111}
112
113HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) {
Sean Paulac874152016-03-10 16:00:26 -0500114 // TODO: Implement virtual display
Sean Pauled2ec4b2016-03-10 15:35:40 -0500115 return unsupported(__func__, display);
116}
117
118void DrmHwcTwo::Dump(uint32_t *size, char *buffer) {
Sean Paulac874152016-03-10 16:00:26 -0500119 // TODO: Implement dump
Sean Pauled2ec4b2016-03-10 15:35:40 -0500120 unsupported(__func__, size, buffer);
121}
122
123uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
Sean Paulac874152016-03-10 16:00:26 -0500124 // TODO: Implement virtual display
Sean Pauled2ec4b2016-03-10 15:35:40 -0500125 unsupported(__func__);
126 return 0;
127}
128
129HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
Sean Paulac874152016-03-10 16:00:26 -0500130 hwc2_callback_data_t data,
131 hwc2_function_pointer_t function) {
132 supported(__func__);
133 auto callback = static_cast<HWC2::Callback>(descriptor);
134 callbacks_.emplace(callback, HwcCallback(data, function));
135
136 switch (callback) {
137 case HWC2::Callback::Hotplug: {
138 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(function);
139 hotplug(data, HWC_DISPLAY_PRIMARY,
140 static_cast<int32_t>(HWC2::Connection::Connected));
141 break;
142 }
143 case HWC2::Callback::Vsync: {
144 for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &d :
145 displays_)
146 d.second.RegisterVsyncCallback(data, function);
147 break;
148 }
149 default:
150 break;
151 }
152 return HWC2::Error::None;
153}
154
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +0100155DrmHwcTwo::HwcDisplay::HwcDisplay(DrmDevice *drm,
Sean Paulac874152016-03-10 16:00:26 -0500156 std::shared_ptr<Importer> importer,
Sean Paulac874152016-03-10 16:00:26 -0500157 hwc2_display_t handle, HWC2::DisplayType type)
Andrii Chepurnyi1d224e82018-05-17 18:34:01 +0300158 : drm_(drm), importer_(importer), handle_(handle), type_(type) {
Sean Paulac874152016-03-10 16:00:26 -0500159 supported(__func__);
160}
161
162HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
163 supported(__func__);
164 planner_ = Planner::CreateInstance(drm_);
165 if (!planner_) {
166 ALOGE("Failed to create planner instance for composition");
167 return HWC2::Error::NoResources;
168 }
169
170 int display = static_cast<int>(handle_);
171 int ret = compositor_.Init(drm_, display);
172 if (ret) {
173 ALOGE("Failed display compositor init for display %d (%d)", display, ret);
174 return HWC2::Error::NoResources;
175 }
176
177 // Split up the given display planes into primary and overlay to properly
178 // interface with the composition
179 char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
180 property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1");
181 bool use_overlay_planes = atoi(use_overlay_planes_prop);
182 for (auto &plane : *planes) {
183 if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
184 primary_planes_.push_back(plane);
185 else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY)
186 overlay_planes_.push_back(plane);
187 }
188
189 crtc_ = drm_->GetCrtcForDisplay(display);
190 if (!crtc_) {
191 ALOGE("Failed to get crtc for display %d", display);
192 return HWC2::Error::BadDisplay;
193 }
194
195 connector_ = drm_->GetConnectorForDisplay(display);
196 if (!connector_) {
197 ALOGE("Failed to get connector for display %d", display);
198 return HWC2::Error::BadDisplay;
199 }
200
201 // Fetch the number of modes from the display
202 uint32_t num_configs;
203 HWC2::Error err = GetDisplayConfigs(&num_configs, NULL);
204 if (err != HWC2::Error::None || !num_configs)
205 return err;
206
207 // Grab the first mode, we'll choose this as the active mode
208 // TODO: Should choose the preferred mode here
209 hwc2_config_t default_config;
210 num_configs = 1;
211 err = GetDisplayConfigs(&num_configs, &default_config);
212 if (err != HWC2::Error::None)
213 return err;
214
215 ret = vsync_worker_.Init(drm_, display);
216 if (ret) {
217 ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
218 return HWC2::Error::BadDisplay;
219 }
220
221 return SetActiveConfig(default_config);
222}
223
224HWC2::Error DrmHwcTwo::HwcDisplay::RegisterVsyncCallback(
225 hwc2_callback_data_t data, hwc2_function_pointer_t func) {
226 supported(__func__);
227 auto callback = std::make_shared<DrmVsyncCallback>(data, func);
Adrian Salidofa37f672017-02-16 10:29:46 -0800228 vsync_worker_.RegisterCallback(std::move(callback));
Sean Paulac874152016-03-10 16:00:26 -0500229 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500230}
231
232HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
Sean Paulac874152016-03-10 16:00:26 -0500233 supported(__func__);
Sean Paulac874152016-03-10 16:00:26 -0500234 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
235 l.second.accept_type_change();
236 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500237}
238
239HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
Sean Paulac874152016-03-10 16:00:26 -0500240 supported(__func__);
241 layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer());
242 *layer = static_cast<hwc2_layer_t>(layer_idx_);
243 ++layer_idx_;
244 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500245}
246
247HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
Sean Paulac874152016-03-10 16:00:26 -0500248 supported(__func__);
249 layers_.erase(layer);
250 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500251}
252
253HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(hwc2_config_t *config) {
Sean Paulac874152016-03-10 16:00:26 -0500254 supported(__func__);
255 DrmMode const &mode = connector_->active_mode();
256 if (mode.id() == 0)
257 return HWC2::Error::BadConfig;
258
259 *config = mode.id();
260 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500261}
262
263HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes(
264 uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) {
Sean Paulac874152016-03-10 16:00:26 -0500265 supported(__func__);
266 uint32_t num_changes = 0;
267 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
268 if (l.second.type_changed()) {
269 if (layers && num_changes < *num_elements)
270 layers[num_changes] = l.first;
271 if (types && num_changes < *num_elements)
272 types[num_changes] = static_cast<int32_t>(l.second.validated_type());
273 ++num_changes;
274 }
275 }
276 if (!layers && !types)
277 *num_elements = num_changes;
278 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500279}
280
281HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width,
Sean Paulac874152016-03-10 16:00:26 -0500282 uint32_t height,
283 int32_t /*format*/,
284 int32_t dataspace) {
285 supported(__func__);
286 std::pair<uint32_t, uint32_t> min = drm_->min_resolution();
287 std::pair<uint32_t, uint32_t> max = drm_->max_resolution();
288
289 if (width < min.first || height < min.second)
290 return HWC2::Error::Unsupported;
291
292 if (width > max.first || height > max.second)
293 return HWC2::Error::Unsupported;
294
295 if (dataspace != HAL_DATASPACE_UNKNOWN &&
296 dataspace != HAL_DATASPACE_STANDARD_UNSPECIFIED)
297 return HWC2::Error::Unsupported;
298
299 // TODO: Validate format can be handled by either GL or planes
300 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500301}
302
303HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes,
Sean Paulac874152016-03-10 16:00:26 -0500304 int32_t *modes) {
305 supported(__func__);
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -0800306 if (!modes)
307 *num_modes = 1;
308
309 if (modes)
310 *modes = HAL_COLOR_MODE_NATIVE;
311
312 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500313}
314
315HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
Sean Paulac874152016-03-10 16:00:26 -0500316 int32_t attribute_in,
317 int32_t *value) {
318 supported(__func__);
319 auto mode =
320 std::find_if(connector_->modes().begin(), connector_->modes().end(),
321 [config](DrmMode const &m) { return m.id() == config; });
322 if (mode == connector_->modes().end()) {
323 ALOGE("Could not find active mode for %d", config);
324 return HWC2::Error::BadConfig;
325 }
326
327 static const int32_t kUmPerInch = 25400;
328 uint32_t mm_width = connector_->mm_width();
329 uint32_t mm_height = connector_->mm_height();
330 auto attribute = static_cast<HWC2::Attribute>(attribute_in);
331 switch (attribute) {
332 case HWC2::Attribute::Width:
333 *value = mode->h_display();
334 break;
335 case HWC2::Attribute::Height:
336 *value = mode->v_display();
337 break;
338 case HWC2::Attribute::VsyncPeriod:
339 // in nanoseconds
340 *value = 1000 * 1000 * 1000 / mode->v_refresh();
341 break;
342 case HWC2::Attribute::DpiX:
343 // Dots per 1000 inches
344 *value = mm_width ? (mode->h_display() * kUmPerInch) / mm_width : -1;
345 break;
346 case HWC2::Attribute::DpiY:
347 // Dots per 1000 inches
348 *value = mm_height ? (mode->v_display() * kUmPerInch) / mm_height : -1;
349 break;
350 default:
351 *value = -1;
352 return HWC2::Error::BadConfig;
353 }
354 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500355}
356
357HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
358 hwc2_config_t *configs) {
Sean Paulac874152016-03-10 16:00:26 -0500359 supported(__func__);
360 // Since this callback is normally invoked twice (once to get the count, and
361 // once to populate configs), we don't really want to read the edid
362 // redundantly. Instead, only update the modes on the first invocation. While
363 // it's possible this will result in stale modes, it'll all come out in the
364 // wash when we try to set the active config later.
365 if (!configs) {
366 int ret = connector_->UpdateModes();
367 if (ret) {
368 ALOGE("Failed to update display modes %d", ret);
369 return HWC2::Error::BadDisplay;
370 }
371 }
372
373 auto num_modes = static_cast<uint32_t>(connector_->modes().size());
374 if (!configs) {
375 *num_configs = num_modes;
376 return HWC2::Error::None;
377 }
378
379 uint32_t idx = 0;
380 for (const DrmMode &mode : connector_->modes()) {
381 if (idx >= *num_configs)
382 break;
383 configs[idx++] = mode.id();
384 }
385 *num_configs = idx;
386 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500387}
388
389HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
Sean Paulac874152016-03-10 16:00:26 -0500390 supported(__func__);
391 std::ostringstream stream;
392 stream << "display-" << connector_->id();
393 std::string string = stream.str();
394 size_t length = string.length();
395 if (!name) {
396 *size = length;
397 return HWC2::Error::None;
398 }
399
400 *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size);
401 strncpy(name, string.c_str(), *size);
402 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500403}
404
Sean Paulac874152016-03-10 16:00:26 -0500405HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests,
406 uint32_t *num_elements,
407 hwc2_layer_t *layers,
408 int32_t *layer_requests) {
409 supported(__func__);
410 // TODO: I think virtual display should request
411 // HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
412 unsupported(__func__, display_requests, num_elements, layers, layer_requests);
413 *num_elements = 0;
414 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500415}
416
417HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
Sean Paulac874152016-03-10 16:00:26 -0500418 supported(__func__);
419 *type = static_cast<int32_t>(type_);
420 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500421}
422
423HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
Sean Paulac874152016-03-10 16:00:26 -0500424 supported(__func__);
425 *support = 0;
426 return HWC2::Error::None;
427}
428
429HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
430 uint32_t *num_types, int32_t */*types*/, float */*max_luminance*/,
431 float */*max_average_luminance*/, float */*min_luminance*/) {
432 supported(__func__);
433 *num_types = 0;
434 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500435}
436
437HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
Sean Paulac874152016-03-10 16:00:26 -0500438 hwc2_layer_t *layers,
439 int32_t *fences) {
440 supported(__func__);
441 uint32_t num_layers = 0;
442
443 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
444 ++num_layers;
445 if (layers == NULL || fences == NULL) {
446 continue;
447 } else if (num_layers > *num_elements) {
448 ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements);
449 return HWC2::Error::None;
450 }
451
452 layers[num_layers - 1] = l.first;
453 fences[num_layers - 1] = l.second.take_release_fence();
454 }
455 *num_elements = num_layers;
456 return HWC2::Error::None;
457}
458
459void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) {
460 supported(__func__);
461 if (fd < 0)
462 return;
463
464 if (next_retire_fence_.get() >= 0) {
465 int old_fence = next_retire_fence_.get();
466 next_retire_fence_.Set(sync_merge("dc_retire", old_fence, fd));
467 } else {
468 next_retire_fence_.Set(dup(fd));
469 }
Sean Pauled2ec4b2016-03-10 15:35:40 -0500470}
471
Rob Herring4f6c62e2018-05-17 14:33:02 -0500472HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
Sean Paulac874152016-03-10 16:00:26 -0500473 std::vector<DrmCompositionDisplayLayersMap> layers_map;
474 layers_map.emplace_back();
475 DrmCompositionDisplayLayersMap &map = layers_map.back();
476
477 map.display = static_cast<int>(handle_);
478 map.geometry_changed = true; // TODO: Fix this
479
480 // order the layers by z-order
481 bool use_client_layer = false;
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100482 uint32_t client_z_order = UINT32_MAX;
Sean Paulac874152016-03-10 16:00:26 -0500483 std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
484 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
Rob Herring4f6c62e2018-05-17 14:33:02 -0500485 HWC2::Composition comp_type;
486 if (test)
487 comp_type = l.second.sf_type();
488 else
489 comp_type = l.second.validated_type();
490
491 switch (comp_type) {
Sean Paulac874152016-03-10 16:00:26 -0500492 case HWC2::Composition::Device:
493 z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
494 break;
495 case HWC2::Composition::Client:
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100496 // Place it at the z_order of the lowest client layer
Sean Paulac874152016-03-10 16:00:26 -0500497 use_client_layer = true;
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100498 client_z_order = std::min(client_z_order, l.second.z_order());
Sean Paulac874152016-03-10 16:00:26 -0500499 break;
500 default:
501 continue;
502 }
503 }
504 if (use_client_layer)
505 z_map.emplace(std::make_pair(client_z_order, &client_layer_));
506
Rob Herring4f6c62e2018-05-17 14:33:02 -0500507 if (z_map.empty())
508 return HWC2::Error::BadLayer;
509
Sean Paulac874152016-03-10 16:00:26 -0500510 // now that they're ordered by z, add them to the composition
511 for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
512 DrmHwcLayer layer;
513 l.second->PopulateDrmLayer(&layer);
Andrii Chepurnyidc1278c2018-03-20 19:41:18 +0200514 int ret = layer.ImportBuffer(importer_.get());
Sean Paulac874152016-03-10 16:00:26 -0500515 if (ret) {
516 ALOGE("Failed to import layer, ret=%d", ret);
517 return HWC2::Error::NoResources;
518 }
519 map.layers.emplace_back(std::move(layer));
520 }
Sean Paulac874152016-03-10 16:00:26 -0500521
522 std::unique_ptr<DrmDisplayComposition> composition =
523 compositor_.CreateComposition();
524 composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
525
526 // TODO: Don't always assume geometry changed
527 int ret = composition->SetLayers(map.layers.data(), map.layers.size(), true);
528 if (ret) {
529 ALOGE("Failed to set layers in the composition ret=%d", ret);
530 return HWC2::Error::BadLayer;
531 }
532
533 std::vector<DrmPlane *> primary_planes(primary_planes_);
534 std::vector<DrmPlane *> overlay_planes(overlay_planes_);
Rob Herringaf0d9752018-05-04 16:34:19 -0500535 ret = composition->Plan(&primary_planes, &overlay_planes);
Sean Paulac874152016-03-10 16:00:26 -0500536 if (ret) {
537 ALOGE("Failed to plan the composition ret=%d", ret);
538 return HWC2::Error::BadConfig;
539 }
540
541 // Disable the planes we're not using
542 for (auto i = primary_planes.begin(); i != primary_planes.end();) {
543 composition->AddPlaneDisable(*i);
544 i = primary_planes.erase(i);
545 }
546 for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
547 composition->AddPlaneDisable(*i);
548 i = overlay_planes.erase(i);
549 }
550
Rob Herring4f6c62e2018-05-17 14:33:02 -0500551 if (test) {
552 ret = compositor_.TestComposition(composition.get());
553 } else {
554 AddFenceToRetireFence(composition->take_out_fence());
555 ret = compositor_.ApplyComposition(std::move(composition));
556 }
Sean Paulac874152016-03-10 16:00:26 -0500557 if (ret) {
John Stultz78c9f6c2018-05-24 16:43:35 -0700558 if (!test)
559 ALOGE("Failed to apply the frame composition ret=%d", ret);
Sean Paulac874152016-03-10 16:00:26 -0500560 return HWC2::Error::BadParameter;
561 }
Rob Herring4f6c62e2018-05-17 14:33:02 -0500562 return HWC2::Error::None;
563}
564
565HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
566 supported(__func__);
567 HWC2::Error ret;
568
569 ret = CreateComposition(false);
570 if (ret == HWC2::Error::BadLayer) {
571 // Can we really have no client or device layers?
572 *retire_fence = -1;
573 return HWC2::Error::None;
574 }
575 if (ret != HWC2::Error::None)
576 return ret;
Sean Paulac874152016-03-10 16:00:26 -0500577
Sean Paulac874152016-03-10 16:00:26 -0500578 // The retire fence returned here is for the last frame, so return it and
579 // promote the next retire fence
580 *retire_fence = retire_fence_.Release();
581 retire_fence_ = std::move(next_retire_fence_);
582
583 ++frame_no_;
584 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500585}
586
587HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
Sean Paulac874152016-03-10 16:00:26 -0500588 supported(__func__);
589 auto mode =
590 std::find_if(connector_->modes().begin(), connector_->modes().end(),
591 [config](DrmMode const &m) { return m.id() == config; });
592 if (mode == connector_->modes().end()) {
593 ALOGE("Could not find active mode for %d", config);
594 return HWC2::Error::BadConfig;
595 }
596
597 std::unique_ptr<DrmDisplayComposition> composition =
598 compositor_.CreateComposition();
599 composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
600 int ret = composition->SetDisplayMode(*mode);
Sean Pauled45a8e2017-02-28 13:17:34 -0500601 ret = compositor_.ApplyComposition(std::move(composition));
Sean Paulac874152016-03-10 16:00:26 -0500602 if (ret) {
603 ALOGE("Failed to queue dpms composition on %d", ret);
604 return HWC2::Error::BadConfig;
605 }
606 if (connector_->active_mode().id() == 0)
607 connector_->set_active_mode(*mode);
608
609 // Setup the client layer's dimensions
610 hwc_rect_t display_frame = {.left = 0,
611 .top = 0,
612 .right = static_cast<int>(mode->h_display()),
613 .bottom = static_cast<int>(mode->v_display())};
614 client_layer_.SetLayerDisplayFrame(display_frame);
615 hwc_frect_t source_crop = {.left = 0.0f,
616 .top = 0.0f,
617 .right = mode->h_display() + 0.0f,
618 .bottom = mode->v_display() + 0.0f};
619 client_layer_.SetLayerSourceCrop(source_crop);
620
621 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500622}
623
624HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
625 int32_t acquire_fence,
626 int32_t dataspace,
Rob Herring1b2685c2017-11-29 10:19:57 -0600627 hwc_region_t /*damage*/) {
Sean Paulac874152016-03-10 16:00:26 -0500628 supported(__func__);
629 UniqueFd uf(acquire_fence);
630
631 client_layer_.set_buffer(target);
632 client_layer_.set_acquire_fence(uf.get());
633 client_layer_.SetLayerDataspace(dataspace);
634 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500635}
636
637HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
Sean Paulac874152016-03-10 16:00:26 -0500638 supported(__func__);
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -0800639
640 if (mode != HAL_COLOR_MODE_NATIVE)
641 return HWC2::Error::Unsupported;
642
643 color_mode_ = mode;
644 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500645}
646
647HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
Sean Paulac874152016-03-10 16:00:26 -0500648 int32_t hint) {
649 supported(__func__);
650 // TODO: Force client composition if we get this
Sean Pauled2ec4b2016-03-10 15:35:40 -0500651 return unsupported(__func__, matrix, hint);
652}
653
654HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer,
Sean Paulac874152016-03-10 16:00:26 -0500655 int32_t release_fence) {
656 supported(__func__);
657 // TODO: Need virtual display support
Sean Pauled2ec4b2016-03-10 15:35:40 -0500658 return unsupported(__func__, buffer, release_fence);
659}
660
Sean Paulac874152016-03-10 16:00:26 -0500661HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
662 supported(__func__);
663 uint64_t dpms_value = 0;
664 auto mode = static_cast<HWC2::PowerMode>(mode_in);
665 switch (mode) {
666 case HWC2::PowerMode::Off:
667 dpms_value = DRM_MODE_DPMS_OFF;
668 break;
669 case HWC2::PowerMode::On:
670 dpms_value = DRM_MODE_DPMS_ON;
671 break;
672 default:
673 ALOGI("Power mode %d is unsupported\n", mode);
674 return HWC2::Error::Unsupported;
675 };
676
677 std::unique_ptr<DrmDisplayComposition> composition =
678 compositor_.CreateComposition();
679 composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_);
680 composition->SetDpmsMode(dpms_value);
Sean Pauled45a8e2017-02-28 13:17:34 -0500681 int ret = compositor_.ApplyComposition(std::move(composition));
Sean Paulac874152016-03-10 16:00:26 -0500682 if (ret) {
683 ALOGE("Failed to apply the dpms composition ret=%d", ret);
684 return HWC2::Error::BadParameter;
685 }
686 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500687}
688
689HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
Sean Paulac874152016-03-10 16:00:26 -0500690 supported(__func__);
691 vsync_worker_.VSyncControl(enabled);
692 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500693}
694
695HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
Sean Paulac874152016-03-10 16:00:26 -0500696 uint32_t *num_requests) {
697 supported(__func__);
698 *num_types = 0;
699 *num_requests = 0;
Rob Herring4f6c62e2018-05-17 14:33:02 -0500700 size_t avail_planes = primary_planes_.size() + overlay_planes_.size();
John Stultz76ca20e2018-07-06 10:34:42 -0700701 bool comp_failed = false;
Rob Herring4f6c62e2018-05-17 14:33:02 -0500702
703 HWC2::Error ret;
704
705 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
706 l.second.set_validated_type(HWC2::Composition::Invalid);
707
708 ret = CreateComposition(true);
709 if (ret != HWC2::Error::None)
John Stultz76ca20e2018-07-06 10:34:42 -0700710 comp_failed = true;
Rob Herring4f6c62e2018-05-17 14:33:02 -0500711
Alexandru Gheorghe1542d292018-06-13 16:46:36 +0100712 std::map<uint32_t, DrmHwcTwo::HwcLayer *, std::greater<int>> z_map;
Rob Herring4f6c62e2018-05-17 14:33:02 -0500713 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
714 if (l.second.sf_type() == HWC2::Composition::Device)
715 z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
716 }
717
718 /*
719 * If more layers then planes, save one plane
720 * for client composited layers
721 */
722 if (avail_planes < layers_.size())
723 avail_planes--;
724
725 for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
John Stultz76ca20e2018-07-06 10:34:42 -0700726 if (comp_failed || !avail_planes--)
Rob Herring4f6c62e2018-05-17 14:33:02 -0500727 break;
728 l.second->set_validated_type(HWC2::Composition::Device);
729 }
730
Sean Paulac874152016-03-10 16:00:26 -0500731 for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
732 DrmHwcTwo::HwcLayer &layer = l.second;
733 switch (layer.sf_type()) {
Rob Herring4f6c62e2018-05-17 14:33:02 -0500734 case HWC2::Composition::Device:
735 if (layer.validated_type() == HWC2::Composition::Device)
736 break;
737 // fall thru
Sean Paulac874152016-03-10 16:00:26 -0500738 case HWC2::Composition::SolidColor:
739 case HWC2::Composition::Cursor:
740 case HWC2::Composition::Sideband:
Rob Herringaf0d9752018-05-04 16:34:19 -0500741 default:
Sean Paulac874152016-03-10 16:00:26 -0500742 layer.set_validated_type(HWC2::Composition::Client);
743 ++*num_types;
744 break;
Sean Paulac874152016-03-10 16:00:26 -0500745 }
746 }
Rob Herringee8f45b2017-06-09 15:15:55 -0500747 return *num_types ? HWC2::Error::HasChanges : HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500748}
749
750HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t x, int32_t y) {
Sean Paulac874152016-03-10 16:00:26 -0500751 supported(__func__);
Kalyan Kondapallyda5839c2016-11-10 10:59:50 -0800752 cursor_x_ = x;
753 cursor_y_ = y;
754 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500755}
756
757HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
Sean Paulac874152016-03-10 16:00:26 -0500758 supported(__func__);
759 blending_ = static_cast<HWC2::BlendMode>(mode);
760 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500761}
762
763HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
Sean Paulac874152016-03-10 16:00:26 -0500764 int32_t acquire_fence) {
765 supported(__func__);
766 UniqueFd uf(acquire_fence);
767
768 // The buffer and acquire_fence are handled elsewhere
769 if (sf_type_ == HWC2::Composition::Client ||
770 sf_type_ == HWC2::Composition::Sideband ||
771 sf_type_ == HWC2::Composition::SolidColor)
772 return HWC2::Error::None;
773
774 set_buffer(buffer);
775 set_acquire_fence(uf.get());
776 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500777}
778
779HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t color) {
Sean Paulac874152016-03-10 16:00:26 -0500780 // TODO: Punt to client composition here?
Sean Pauled2ec4b2016-03-10 15:35:40 -0500781 return unsupported(__func__, color);
782}
783
784HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
Sean Paulac874152016-03-10 16:00:26 -0500785 sf_type_ = static_cast<HWC2::Composition>(type);
786 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500787}
788
789HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
Sean Paulac874152016-03-10 16:00:26 -0500790 supported(__func__);
791 dataspace_ = static_cast<android_dataspace_t>(dataspace);
792 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500793}
794
795HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
Sean Paulac874152016-03-10 16:00:26 -0500796 supported(__func__);
797 display_frame_ = frame;
798 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500799}
800
801HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
Sean Paulac874152016-03-10 16:00:26 -0500802 supported(__func__);
803 alpha_ = alpha;
804 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500805}
806
807HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream(
808 const native_handle_t *stream) {
Sean Paulac874152016-03-10 16:00:26 -0500809 supported(__func__);
810 // TODO: We don't support sideband
Sean Pauled2ec4b2016-03-10 15:35:40 -0500811 return unsupported(__func__, stream);
812}
813
814HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
Sean Paulac874152016-03-10 16:00:26 -0500815 supported(__func__);
816 source_crop_ = crop;
817 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500818}
819
820HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
Sean Paulac874152016-03-10 16:00:26 -0500821 supported(__func__);
822 // TODO: We don't use surface damage, marking as unsupported
823 unsupported(__func__, damage);
824 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500825}
826
827HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) {
Sean Paulac874152016-03-10 16:00:26 -0500828 supported(__func__);
829 transform_ = static_cast<HWC2::Transform>(transform);
830 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500831}
832
833HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) {
Sean Paulac874152016-03-10 16:00:26 -0500834 supported(__func__);
835 // TODO: We don't use this information, marking as unsupported
836 unsupported(__func__, visible);
837 return HWC2::Error::None;
Sean Pauled2ec4b2016-03-10 15:35:40 -0500838}
839
Sean Paulac874152016-03-10 16:00:26 -0500840HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) {
841 supported(__func__);
842 z_order_ = order;
843 return HWC2::Error::None;
844}
845
846void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
847 supported(__func__);
848 switch (blending_) {
849 case HWC2::BlendMode::None:
850 layer->blending = DrmHwcBlending::kNone;
851 break;
852 case HWC2::BlendMode::Premultiplied:
853 layer->blending = DrmHwcBlending::kPreMult;
854 break;
855 case HWC2::BlendMode::Coverage:
856 layer->blending = DrmHwcBlending::kCoverage;
857 break;
858 default:
859 ALOGE("Unknown blending mode b=%d", blending_);
860 layer->blending = DrmHwcBlending::kNone;
861 break;
862 }
863
864 OutputFd release_fence = release_fence_output();
865
866 layer->sf_handle = buffer_;
867 layer->acquire_fence = acquire_fence_.Release();
868 layer->release_fence = std::move(release_fence);
869 layer->SetDisplayFrame(display_frame_);
Stefan Schake025d0a62018-05-04 18:03:00 +0200870 layer->alpha = static_cast<uint16_t>(65535.0f * alpha_ + 0.5f);
Sean Paulac874152016-03-10 16:00:26 -0500871 layer->SetSourceCrop(source_crop_);
872 layer->SetTransform(static_cast<int32_t>(transform_));
Sean Pauled2ec4b2016-03-10 15:35:40 -0500873}
874
875// static
876int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) {
877 unsupported(__func__);
878 return 0;
879}
880
881// static
882void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/,
Sean Paulac874152016-03-10 16:00:26 -0500883 uint32_t *out_count,
884 int32_t * /*out_capabilities*/) {
885 supported(__func__);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500886 *out_count = 0;
887}
888
889// static
Sean Paulac874152016-03-10 16:00:26 -0500890hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction(
891 struct hwc2_device * /*dev*/, int32_t descriptor) {
892 supported(__func__);
893 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500894 switch (func) {
895 // Device functions
896 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
897 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
898 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
899 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
900 int32_t*, hwc2_display_t *>);
901 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
902 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
903 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
904 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
905 case HWC2::FunctionDescriptor::Dump:
906 return ToHook<HWC2_PFN_DUMP>(
907 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
908 uint32_t *, char *>);
909 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
910 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
911 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
912 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
913 case HWC2::FunctionDescriptor::RegisterCallback:
914 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
915 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
916 &DrmHwcTwo::RegisterCallback, int32_t,
917 hwc2_callback_data_t, hwc2_function_pointer_t>);
918
919 // Display functions
920 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
921 return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
922 DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
923 &HwcDisplay::AcceptDisplayChanges>);
924 case HWC2::FunctionDescriptor::CreateLayer:
925 return ToHook<HWC2_PFN_CREATE_LAYER>(
926 DisplayHook<decltype(&HwcDisplay::CreateLayer),
927 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
928 case HWC2::FunctionDescriptor::DestroyLayer:
929 return ToHook<HWC2_PFN_DESTROY_LAYER>(
930 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
931 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
932 case HWC2::FunctionDescriptor::GetActiveConfig:
933 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
934 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
935 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
936 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
937 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
938 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
939 &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
940 hwc2_layer_t *, int32_t *>);
941 case HWC2::FunctionDescriptor::GetClientTargetSupport:
942 return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
943 DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
944 &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
945 int32_t, int32_t>);
946 case HWC2::FunctionDescriptor::GetColorModes:
947 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
948 DisplayHook<decltype(&HwcDisplay::GetColorModes),
949 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
950 case HWC2::FunctionDescriptor::GetDisplayAttribute:
951 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(DisplayHook<
952 decltype(&HwcDisplay::GetDisplayAttribute),
953 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t, int32_t *>);
954 case HWC2::FunctionDescriptor::GetDisplayConfigs:
955 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(DisplayHook<
956 decltype(&HwcDisplay::GetDisplayConfigs),
957 &HwcDisplay::GetDisplayConfigs, uint32_t *, hwc2_config_t *>);
958 case HWC2::FunctionDescriptor::GetDisplayName:
959 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
960 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
961 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
962 case HWC2::FunctionDescriptor::GetDisplayRequests:
963 return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
964 DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
965 &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
966 hwc2_layer_t *, int32_t *>);
967 case HWC2::FunctionDescriptor::GetDisplayType:
968 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
969 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
970 &HwcDisplay::GetDisplayType, int32_t *>);
971 case HWC2::FunctionDescriptor::GetDozeSupport:
972 return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
973 DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
974 &HwcDisplay::GetDozeSupport, int32_t *>);
Sean Paulac874152016-03-10 16:00:26 -0500975 case HWC2::FunctionDescriptor::GetHdrCapabilities:
976 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
977 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
978 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
979 float *, float *, float *>);
Sean Pauled2ec4b2016-03-10 15:35:40 -0500980 case HWC2::FunctionDescriptor::GetReleaseFences:
981 return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
982 DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
983 &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
984 int32_t *>);
985 case HWC2::FunctionDescriptor::PresentDisplay:
986 return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
987 DisplayHook<decltype(&HwcDisplay::PresentDisplay),
988 &HwcDisplay::PresentDisplay, int32_t *>);
989 case HWC2::FunctionDescriptor::SetActiveConfig:
990 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
991 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
992 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
993 case HWC2::FunctionDescriptor::SetClientTarget:
994 return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(DisplayHook<
995 decltype(&HwcDisplay::SetClientTarget), &HwcDisplay::SetClientTarget,
996 buffer_handle_t, int32_t, int32_t, hwc_region_t>);
997 case HWC2::FunctionDescriptor::SetColorMode:
998 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
999 DisplayHook<decltype(&HwcDisplay::SetColorMode),
1000 &HwcDisplay::SetColorMode, int32_t>);
1001 case HWC2::FunctionDescriptor::SetColorTransform:
1002 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
1003 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
1004 &HwcDisplay::SetColorTransform, const float *, int32_t>);
1005 case HWC2::FunctionDescriptor::SetOutputBuffer:
1006 return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
1007 DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
1008 &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
1009 case HWC2::FunctionDescriptor::SetPowerMode:
1010 return ToHook<HWC2_PFN_SET_POWER_MODE>(
1011 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
1012 &HwcDisplay::SetPowerMode, int32_t>);
1013 case HWC2::FunctionDescriptor::SetVsyncEnabled:
1014 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
1015 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
1016 &HwcDisplay::SetVsyncEnabled, int32_t>);
1017 case HWC2::FunctionDescriptor::ValidateDisplay:
1018 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
1019 DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
1020 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
1021
1022 // Layer functions
1023 case HWC2::FunctionDescriptor::SetCursorPosition:
1024 return ToHook<HWC2_PFN_SET_CURSOR_POSITION>(
1025 LayerHook<decltype(&HwcLayer::SetCursorPosition),
1026 &HwcLayer::SetCursorPosition, int32_t, int32_t>);
1027 case HWC2::FunctionDescriptor::SetLayerBlendMode:
1028 return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>(
1029 LayerHook<decltype(&HwcLayer::SetLayerBlendMode),
1030 &HwcLayer::SetLayerBlendMode, int32_t>);
1031 case HWC2::FunctionDescriptor::SetLayerBuffer:
1032 return ToHook<HWC2_PFN_SET_LAYER_BUFFER>(
1033 LayerHook<decltype(&HwcLayer::SetLayerBuffer),
1034 &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>);
1035 case HWC2::FunctionDescriptor::SetLayerColor:
1036 return ToHook<HWC2_PFN_SET_LAYER_COLOR>(
1037 LayerHook<decltype(&HwcLayer::SetLayerColor),
1038 &HwcLayer::SetLayerColor, hwc_color_t>);
1039 case HWC2::FunctionDescriptor::SetLayerCompositionType:
1040 return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
1041 LayerHook<decltype(&HwcLayer::SetLayerCompositionType),
1042 &HwcLayer::SetLayerCompositionType, int32_t>);
1043 case HWC2::FunctionDescriptor::SetLayerDataspace:
1044 return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>(
1045 LayerHook<decltype(&HwcLayer::SetLayerDataspace),
1046 &HwcLayer::SetLayerDataspace, int32_t>);
1047 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
1048 return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
1049 LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame),
1050 &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>);
1051 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
1052 return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
1053 LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha),
1054 &HwcLayer::SetLayerPlaneAlpha, float>);
1055 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
1056 return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(LayerHook<
1057 decltype(&HwcLayer::SetLayerSidebandStream),
1058 &HwcLayer::SetLayerSidebandStream, const native_handle_t *>);
1059 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
1060 return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
1061 LayerHook<decltype(&HwcLayer::SetLayerSourceCrop),
1062 &HwcLayer::SetLayerSourceCrop, hwc_frect_t>);
1063 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
1064 return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
1065 LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage),
1066 &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>);
1067 case HWC2::FunctionDescriptor::SetLayerTransform:
1068 return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>(
1069 LayerHook<decltype(&HwcLayer::SetLayerTransform),
1070 &HwcLayer::SetLayerTransform, int32_t>);
1071 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
1072 return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
1073 LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion),
1074 &HwcLayer::SetLayerVisibleRegion, hwc_region_t>);
1075 case HWC2::FunctionDescriptor::SetLayerZOrder:
1076 return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>(
1077 LayerHook<decltype(&HwcLayer::SetLayerZOrder),
1078 &HwcLayer::SetLayerZOrder, uint32_t>);
Sean Paulac874152016-03-10 16:00:26 -05001079 case HWC2::FunctionDescriptor::Invalid:
Sean Pauled2ec4b2016-03-10 15:35:40 -05001080 default:
1081 return NULL;
1082 }
1083}
Sean Paulac874152016-03-10 16:00:26 -05001084
1085// static
1086int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name,
1087 struct hw_device_t **dev) {
1088 supported(__func__);
1089 if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
1090 ALOGE("Invalid module name- %s", name);
1091 return -EINVAL;
1092 }
1093
1094 std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo());
1095 if (!ctx) {
1096 ALOGE("Failed to allocate DrmHwcTwo");
1097 return -ENOMEM;
1098 }
1099
1100 HWC2::Error err = ctx->Init();
1101 if (err != HWC2::Error::None) {
1102 ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err);
1103 return -EINVAL;
1104 }
1105
1106 ctx->common.module = const_cast<hw_module_t *>(module);
1107 *dev = &ctx->common;
1108 ctx.release();
1109 return 0;
Sean Pauled2ec4b2016-03-10 15:35:40 -05001110}
Sean Paulac874152016-03-10 16:00:26 -05001111}
1112
1113static struct hw_module_methods_t hwc2_module_methods = {
1114 .open = android::DrmHwcTwo::HookDevOpen,
1115};
1116
1117hw_module_t HAL_MODULE_INFO_SYM = {
1118 .tag = HARDWARE_MODULE_TAG,
1119 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
1120 .id = HWC_HARDWARE_MODULE_ID,
1121 .name = "DrmHwcTwo module",
1122 .author = "The Android Open Source Project",
1123 .methods = &hwc2_module_methods,
1124 .dso = NULL,
1125 .reserved = {0},
1126};