1 /*
2 * Copyright (C) 2010 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 LOG_NDEBUG 0
18
19 #undef LOG_TAG
20 #define LOG_TAG "HWComposer"
21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23 #include <inttypes.h>
24 #include <math.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/types.h>
30
31 #include <utils/Errors.h>
32 #include <utils/misc.h>
33 #include <utils/NativeHandle.h>
34 #include <utils/String8.h>
35 #include <utils/Thread.h>
36 #include <utils/Trace.h>
37 #include <utils/Vector.h>
38
39 #include <ui/GraphicBuffer.h>
40
41 #include <hardware/hardware.h>
42 #include <hardware/hwcomposer.h>
43
44 #include <android/configuration.h>
45
46 #include <cutils/properties.h>
47 #include <log/log.h>
48
49 #include "HWComposer.h"
50 #include "HWC2.h"
51 #include "ComposerHal.h"
52
53 #include "../Layer.h" // needed only for debugging
54 #include "../SurfaceFlinger.h"
55
56 namespace android {
57
58 #define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
59
60 // ---------------------------------------------------------------------------
61
HWComposer(bool useVrComposer)62 HWComposer::HWComposer(bool useVrComposer)
63 : mHwcDevice(),
64 mDisplayData(2),
65 mFreeDisplaySlots(),
66 mHwcDisplaySlots(),
67 mCBContext(),
68 mEventHandler(nullptr),
69 mVSyncCounts(),
70 mRemainingHwcVirtualDisplays(0)
71 {
72 for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
73 mLastHwVSync[i] = 0;
74 mVSyncCounts[i] = 0;
75 }
76
77 loadHwcModule(useVrComposer);
78 }
79
~HWComposer()80 HWComposer::~HWComposer() {}
81
setEventHandler(EventHandler * handler)82 void HWComposer::setEventHandler(EventHandler* handler)
83 {
84 if (handler == nullptr) {
85 ALOGE("setEventHandler: Rejected attempt to clear handler");
86 return;
87 }
88
89 bool wasNull = (mEventHandler == nullptr);
90 mEventHandler = handler;
91
92 if (wasNull) {
93 auto hotplugHook = std::bind(&HWComposer::hotplug, this,
94 std::placeholders::_1, std::placeholders::_2);
95 mHwcDevice->registerHotplugCallback(hotplugHook);
96 auto invalidateHook = std::bind(&HWComposer::invalidate, this,
97 std::placeholders::_1);
98 mHwcDevice->registerRefreshCallback(invalidateHook);
99 auto vsyncHook = std::bind(&HWComposer::vsync, this,
100 std::placeholders::_1, std::placeholders::_2);
101 mHwcDevice->registerVsyncCallback(vsyncHook);
102 }
103 }
104
105 // Load and prepare the hardware composer module. Sets mHwc.
loadHwcModule(bool useVrComposer)106 void HWComposer::loadHwcModule(bool useVrComposer)
107 {
108 ALOGV("loadHwcModule");
109 mHwcDevice = std::make_unique<HWC2::Device>(useVrComposer);
110 mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
111 }
112
hasCapability(HWC2::Capability capability) const113 bool HWComposer::hasCapability(HWC2::Capability capability) const
114 {
115 return mHwcDevice->getCapabilities().count(capability) > 0;
116 }
117
isValidDisplay(int32_t displayId) const118 bool HWComposer::isValidDisplay(int32_t displayId) const {
119 return static_cast<size_t>(displayId) < mDisplayData.size() &&
120 mDisplayData[displayId].hwcDisplay;
121 }
122
validateChange(HWC2::Composition from,HWC2::Composition to)123 void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
124 bool valid = true;
125 switch (from) {
126 case HWC2::Composition::Client:
127 valid = false;
128 break;
129 case HWC2::Composition::Device:
130 case HWC2::Composition::SolidColor:
131 valid = (to == HWC2::Composition::Client);
132 break;
133 case HWC2::Composition::Cursor:
134 case HWC2::Composition::Sideband:
135 valid = (to == HWC2::Composition::Client ||
136 to == HWC2::Composition::Device);
137 break;
138 default:
139 break;
140 }
141
142 if (!valid) {
143 ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
144 to_string(to).c_str());
145 }
146 }
147
hotplug(const std::shared_ptr<HWC2::Display> & display,HWC2::Connection connected)148 void HWComposer::hotplug(const std::shared_ptr<HWC2::Display>& display,
149 HWC2::Connection connected) {
150 ALOGV("hotplug: %" PRIu64 ", %s", display->getId(),
151 to_string(connected).c_str());
152 int32_t disp = 0;
153 if (!mDisplayData[0].hwcDisplay) {
154 ALOGE_IF(connected != HWC2::Connection::Connected, "Assumed primary"
155 " display would be connected");
156 mDisplayData[0].hwcDisplay = display;
157 mHwcDisplaySlots[display->getId()] = 0;
158 disp = DisplayDevice::DISPLAY_PRIMARY;
159 } else {
160 // Disconnect is handled through HWComposer::disconnectDisplay via
161 // SurfaceFlinger's onHotplugReceived callback handling
162 if (connected == HWC2::Connection::Connected) {
163 mDisplayData[1].hwcDisplay = display;
164 mHwcDisplaySlots[display->getId()] = 1;
165 }
166 disp = DisplayDevice::DISPLAY_EXTERNAL;
167 }
168 mEventHandler->onHotplugReceived(this, disp,
169 connected == HWC2::Connection::Connected);
170 }
171
invalidate(const std::shared_ptr<HWC2::Display> &)172 void HWComposer::invalidate(const std::shared_ptr<HWC2::Display>& /*display*/) {
173 mEventHandler->onInvalidateReceived(this);
174 }
175
vsync(const std::shared_ptr<HWC2::Display> & display,int64_t timestamp)176 void HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
177 int64_t timestamp) {
178 auto displayType = HWC2::DisplayType::Invalid;
179 auto error = display->getType(&displayType);
180 if (error != HWC2::Error::None) {
181 ALOGE("vsync: Failed to determine type of display %" PRIu64,
182 display->getId());
183 return;
184 }
185
186 if (displayType == HWC2::DisplayType::Virtual) {
187 ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
188 display->getId());
189 return;
190 }
191
192 if (mHwcDisplaySlots.count(display->getId()) == 0) {
193 ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
194 display->getId());
195 return;
196 }
197
198 int32_t disp = mHwcDisplaySlots[display->getId()];
199 {
200 Mutex::Autolock _l(mLock);
201
202 // There have been reports of HWCs that signal several vsync events
203 // with the same timestamp when turning the display off and on. This
204 // is a bug in the HWC implementation, but filter the extra events
205 // out here so they don't cause havoc downstream.
206 if (timestamp == mLastHwVSync[disp]) {
207 ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
208 timestamp);
209 return;
210 }
211
212 mLastHwVSync[disp] = timestamp;
213 }
214
215 char tag[16];
216 snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
217 ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
218
219 mEventHandler->onVSyncReceived(this, disp, timestamp);
220 }
221
allocateVirtualDisplay(uint32_t width,uint32_t height,android_pixel_format_t * format,int32_t * outId)222 status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
223 android_pixel_format_t* format, int32_t *outId) {
224 if (mRemainingHwcVirtualDisplays == 0) {
225 ALOGE("allocateVirtualDisplay: No remaining virtual displays");
226 return NO_MEMORY;
227 }
228
229 if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
230 (width > SurfaceFlinger::maxVirtualDisplaySize ||
231 height > SurfaceFlinger::maxVirtualDisplaySize)) {
232 ALOGE("createVirtualDisplay: Can't create a virtual display with"
233 " a dimension > %" PRIu64 " (tried %u x %u)",
234 SurfaceFlinger::maxVirtualDisplaySize, width, height);
235 return INVALID_OPERATION;
236 }
237
238 std::shared_ptr<HWC2::Display> display;
239 auto error = mHwcDevice->createVirtualDisplay(width, height, format,
240 &display);
241 if (error != HWC2::Error::None) {
242 ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display");
243 return NO_MEMORY;
244 }
245
246 size_t displaySlot = 0;
247 if (!mFreeDisplaySlots.empty()) {
248 displaySlot = *mFreeDisplaySlots.begin();
249 mFreeDisplaySlots.erase(displaySlot);
250 } else if (mDisplayData.size() < INT32_MAX) {
251 // Don't bother allocating a slot larger than we can return
252 displaySlot = mDisplayData.size();
253 mDisplayData.resize(displaySlot + 1);
254 } else {
255 ALOGE("allocateVirtualDisplay: Unable to allocate a display slot");
256 return NO_MEMORY;
257 }
258
259 mDisplayData[displaySlot].hwcDisplay = display;
260
261 --mRemainingHwcVirtualDisplays;
262 *outId = static_cast<int32_t>(displaySlot);
263
264 return NO_ERROR;
265 }
266
createLayer(int32_t displayId)267 std::shared_ptr<HWC2::Layer> HWComposer::createLayer(int32_t displayId) {
268 if (!isValidDisplay(displayId)) {
269 ALOGE("Failed to create layer on invalid display %d", displayId);
270 return nullptr;
271 }
272 auto display = mDisplayData[displayId].hwcDisplay;
273 std::shared_ptr<HWC2::Layer> layer;
274 auto error = display->createLayer(&layer);
275 if (error != HWC2::Error::None) {
276 ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
277 to_string(error).c_str(), static_cast<int32_t>(error));
278 return nullptr;
279 }
280 return layer;
281 }
282
getRefreshTimestamp(int32_t displayId) const283 nsecs_t HWComposer::getRefreshTimestamp(int32_t displayId) const {
284 // this returns the last refresh timestamp.
285 // if the last one is not available, we estimate it based on
286 // the refresh period and whatever closest timestamp we have.
287 Mutex::Autolock _l(mLock);
288 nsecs_t now = systemTime(CLOCK_MONOTONIC);
289 auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
290 return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
291 }
292
isConnected(int32_t displayId) const293 bool HWComposer::isConnected(int32_t displayId) const {
294 if (!isValidDisplay(displayId)) {
295 ALOGE("isConnected: Attempted to access invalid display %d", displayId);
296 return false;
297 }
298 return mDisplayData[displayId].hwcDisplay->isConnected();
299 }
300
301 std::vector<std::shared_ptr<const HWC2::Display::Config>>
getConfigs(int32_t displayId) const302 HWComposer::getConfigs(int32_t displayId) const {
303 if (!isValidDisplay(displayId)) {
304 ALOGE("getConfigs: Attempted to access invalid display %d", displayId);
305 return {};
306 }
307 auto& displayData = mDisplayData[displayId];
308 auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();
309 if (displayData.configMap.empty()) {
310 for (size_t i = 0; i < configs.size(); ++i) {
311 displayData.configMap[i] = configs[i];
312 }
313 }
314 return configs;
315 }
316
317 std::shared_ptr<const HWC2::Display::Config>
getActiveConfig(int32_t displayId) const318 HWComposer::getActiveConfig(int32_t displayId) const {
319 if (!isValidDisplay(displayId)) {
320 ALOGV("getActiveConfigs: Attempted to access invalid display %d",
321 displayId);
322 return nullptr;
323 }
324 std::shared_ptr<const HWC2::Display::Config> config;
325 auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config);
326 if (error == HWC2::Error::BadConfig) {
327 ALOGE("getActiveConfig: No config active, returning null");
328 return nullptr;
329 } else if (error != HWC2::Error::None) {
330 ALOGE("getActiveConfig failed for display %d: %s (%d)", displayId,
331 to_string(error).c_str(), static_cast<int32_t>(error));
332 return nullptr;
333 } else if (!config) {
334 ALOGE("getActiveConfig returned an unknown config for display %d",
335 displayId);
336 return nullptr;
337 }
338
339 return config;
340 }
341
getColorModes(int32_t displayId) const342 std::vector<android_color_mode_t> HWComposer::getColorModes(int32_t displayId) const {
343 std::vector<android_color_mode_t> modes;
344
345 if (!isValidDisplay(displayId)) {
346 ALOGE("getColorModes: Attempted to access invalid display %d",
347 displayId);
348 return modes;
349 }
350 const std::shared_ptr<HWC2::Display>& hwcDisplay =
351 mDisplayData[displayId].hwcDisplay;
352
353 auto error = hwcDisplay->getColorModes(&modes);
354 if (error != HWC2::Error::None) {
355 ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
356 to_string(error).c_str(), static_cast<int32_t>(error));
357 return std::vector<android_color_mode_t>();
358 }
359
360 return modes;
361 }
362
setActiveColorMode(int32_t displayId,android_color_mode_t mode)363 status_t HWComposer::setActiveColorMode(int32_t displayId, android_color_mode_t mode) {
364 if (!isValidDisplay(displayId)) {
365 ALOGE("setActiveColorMode: Display %d is not valid", displayId);
366 return BAD_INDEX;
367 }
368
369 auto& displayData = mDisplayData[displayId];
370 auto error = displayData.hwcDisplay->setColorMode(mode);
371 if (error != HWC2::Error::None) {
372 ALOGE("setActiveConfig: Failed to set color mode %d on display %d: "
373 "%s (%d)", mode, displayId, to_string(error).c_str(),
374 static_cast<int32_t>(error));
375 return UNKNOWN_ERROR;
376 }
377
378 return NO_ERROR;
379 }
380
381
setVsyncEnabled(int32_t displayId,HWC2::Vsync enabled)382 void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) {
383 if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) {
384 ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId);
385 return;
386 }
387
388 if (!isValidDisplay(displayId)) {
389 ALOGE("setVsyncEnabled: Attempted to access invalid display %d",
390 displayId);
391 return;
392 }
393
394 // NOTE: we use our own internal lock here because we have to call
395 // into the HWC with the lock held, and we want to make sure
396 // that even if HWC blocks (which it shouldn't), it won't
397 // affect other threads.
398 Mutex::Autolock _l(mVsyncLock);
399 auto& displayData = mDisplayData[displayId];
400 if (enabled != displayData.vsyncEnabled) {
401 ATRACE_CALL();
402 auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
403 if (error == HWC2::Error::None) {
404 displayData.vsyncEnabled = enabled;
405
406 char tag[16];
407 snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId);
408 ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0);
409 } else {
410 ALOGE("setVsyncEnabled: Failed to set vsync to %s on %d/%" PRIu64
411 ": %s (%d)", to_string(enabled).c_str(), displayId,
412 mDisplayData[displayId].hwcDisplay->getId(),
413 to_string(error).c_str(), static_cast<int32_t>(error));
414 }
415 }
416 }
417
setClientTarget(int32_t displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,android_dataspace_t dataspace)418 status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
419 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
420 android_dataspace_t dataspace) {
421 if (!isValidDisplay(displayId)) {
422 return BAD_INDEX;
423 }
424
425 ALOGV("setClientTarget for display %d", displayId);
426 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
427 auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
428 if (error != HWC2::Error::None) {
429 ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
430 to_string(error).c_str(), static_cast<int32_t>(error));
431 return BAD_VALUE;
432 }
433
434 return NO_ERROR;
435 }
436
prepare(DisplayDevice & displayDevice)437 status_t HWComposer::prepare(DisplayDevice& displayDevice) {
438 ATRACE_CALL();
439
440 Mutex::Autolock _l(mDisplayLock);
441 auto displayId = displayDevice.getHwcDisplayId();
442 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
443 ALOGV("Skipping HWComposer prepare for non-HWC display");
444 return NO_ERROR;
445 }
446 if (!isValidDisplay(displayId)) {
447 return BAD_INDEX;
448 }
449
450 auto& displayData = mDisplayData[displayId];
451 auto& hwcDisplay = displayData.hwcDisplay;
452 if (!hwcDisplay->isConnected()) {
453 return NO_ERROR;
454 }
455
456 uint32_t numTypes = 0;
457 uint32_t numRequests = 0;
458
459 HWC2::Error error = HWC2::Error::None;
460
461 // First try to skip validate altogether if the HWC supports it.
462 displayData.validateWasSkipped = false;
463 if (hasCapability(HWC2::Capability::SkipValidate) &&
464 !displayData.hasClientComposition) {
465 sp<android::Fence> outPresentFence;
466 uint32_t state = UINT32_MAX;
467 error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
468 if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
469 ALOGV("skipValidate: Failed to Present or Validate");
470 return UNKNOWN_ERROR;
471 }
472 if (state == 1) { //Present Succeeded.
473 std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
474 error = hwcDisplay->getReleaseFences(&releaseFences);
475 displayData.releaseFences = std::move(releaseFences);
476 displayData.lastPresentFence = outPresentFence;
477 displayData.validateWasSkipped = true;
478 displayData.presentError = error;
479 return NO_ERROR;
480 }
481 // Present failed but Validate ran.
482 } else {
483 error = hwcDisplay->validate(&numTypes, &numRequests);
484 }
485 ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
486 if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
487 ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
488 to_string(error).c_str(), static_cast<int32_t>(error));
489 return BAD_INDEX;
490 }
491
492 std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::Composition>
493 changedTypes;
494 changedTypes.reserve(numTypes);
495 error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
496 if (error != HWC2::Error::None) {
497 ALOGE("prepare: getChangedCompositionTypes failed on display %d: "
498 "%s (%d)", displayId, to_string(error).c_str(),
499 static_cast<int32_t>(error));
500 return BAD_INDEX;
501 }
502
503
504 displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
505 std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::LayerRequest>
506 layerRequests;
507 layerRequests.reserve(numRequests);
508 error = hwcDisplay->getRequests(&displayData.displayRequests,
509 &layerRequests);
510 if (error != HWC2::Error::None) {
511 ALOGE("prepare: getRequests failed on display %d: %s (%d)", displayId,
512 to_string(error).c_str(), static_cast<int32_t>(error));
513 return BAD_INDEX;
514 }
515
516 displayData.hasClientComposition = false;
517 displayData.hasDeviceComposition = false;
518 for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) {
519 auto hwcLayer = layer->getHwcLayer(displayId);
520
521 if (changedTypes.count(hwcLayer) != 0) {
522 // We pass false so we only update our state and don't call back
523 // into the HWC device
524 validateChange(layer->getCompositionType(displayId),
525 changedTypes[hwcLayer]);
526 layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
527 }
528
529 switch (layer->getCompositionType(displayId)) {
530 case HWC2::Composition::Client:
531 displayData.hasClientComposition = true;
532 break;
533 case HWC2::Composition::Device:
534 case HWC2::Composition::SolidColor:
535 case HWC2::Composition::Cursor:
536 case HWC2::Composition::Sideband:
537 displayData.hasDeviceComposition = true;
538 break;
539 default:
540 break;
541 }
542
543 if (layerRequests.count(hwcLayer) != 0 &&
544 layerRequests[hwcLayer] ==
545 HWC2::LayerRequest::ClearClientTarget) {
546 layer->setClearClientTarget(displayId, true);
547 } else {
548 if (layerRequests.count(hwcLayer) != 0) {
549 ALOGE("prepare: Unknown layer request: %s",
550 to_string(layerRequests[hwcLayer]).c_str());
551 }
552 layer->setClearClientTarget(displayId, false);
553 }
554 }
555
556 error = hwcDisplay->acceptChanges();
557 if (error != HWC2::Error::None) {
558 ALOGE("prepare: acceptChanges failed: %s", to_string(error).c_str());
559 return BAD_INDEX;
560 }
561
562 return NO_ERROR;
563 }
564
hasDeviceComposition(int32_t displayId) const565 bool HWComposer::hasDeviceComposition(int32_t displayId) const {
566 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
567 // Displays without a corresponding HWC display are never composed by
568 // the device
569 return false;
570 }
571 if (!isValidDisplay(displayId)) {
572 ALOGE("hasDeviceComposition: Invalid display %d", displayId);
573 return false;
574 }
575 return mDisplayData[displayId].hasDeviceComposition;
576 }
577
hasClientComposition(int32_t displayId) const578 bool HWComposer::hasClientComposition(int32_t displayId) const {
579 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
580 // Displays without a corresponding HWC display are always composed by
581 // the client
582 return true;
583 }
584 if (!isValidDisplay(displayId)) {
585 ALOGE("hasClientComposition: Invalid display %d", displayId);
586 return true;
587 }
588 return mDisplayData[displayId].hasClientComposition;
589 }
590
getPresentFence(int32_t displayId) const591 sp<Fence> HWComposer::getPresentFence(int32_t displayId) const {
592 if (!isValidDisplay(displayId)) {
593 ALOGE("getPresentFence failed for invalid display %d", displayId);
594 return Fence::NO_FENCE;
595 }
596 return mDisplayData[displayId].lastPresentFence;
597 }
598
getLayerReleaseFence(int32_t displayId,const std::shared_ptr<HWC2::Layer> & layer) const599 sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
600 const std::shared_ptr<HWC2::Layer>& layer) const {
601 if (!isValidDisplay(displayId)) {
602 ALOGE("getLayerReleaseFence: Invalid display");
603 return Fence::NO_FENCE;
604 }
605 auto displayFences = mDisplayData[displayId].releaseFences;
606 if (displayFences.count(layer) == 0) {
607 ALOGV("getLayerReleaseFence: Release fence not found");
608 return Fence::NO_FENCE;
609 }
610 return displayFences[layer];
611 }
612
presentAndGetReleaseFences(int32_t displayId)613 status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {
614 ATRACE_CALL();
615
616 if (!isValidDisplay(displayId)) {
617 return BAD_INDEX;
618 }
619
620 auto& displayData = mDisplayData[displayId];
621 auto& hwcDisplay = displayData.hwcDisplay;
622
623 if (displayData.validateWasSkipped) {
624 hwcDisplay->discardCommands();
625 auto error = displayData.presentError;
626 if (error != HWC2::Error::None) {
627 ALOGE("skipValidate: failed for display %d: %s (%d)",
628 displayId, to_string(error).c_str(), static_cast<int32_t>(error));
629 return UNKNOWN_ERROR;
630 }
631 return NO_ERROR;
632 }
633
634 auto error = hwcDisplay->present(&displayData.lastPresentFence);
635 if (error != HWC2::Error::None) {
636 ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
637 displayId, to_string(error).c_str(), static_cast<int32_t>(error));
638 return UNKNOWN_ERROR;
639 }
640
641 std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
642 error = hwcDisplay->getReleaseFences(&releaseFences);
643 if (error != HWC2::Error::None) {
644 ALOGE("presentAndGetReleaseFences: Failed to get release fences "
645 "for display %d: %s (%d)",
646 displayId, to_string(error).c_str(),
647 static_cast<int32_t>(error));
648 return UNKNOWN_ERROR;
649 }
650
651 displayData.releaseFences = std::move(releaseFences);
652
653 return NO_ERROR;
654 }
655
setPowerMode(int32_t displayId,int32_t intMode)656 status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) {
657 ALOGV("setPowerMode(%d, %d)", displayId, intMode);
658 if (!isValidDisplay(displayId)) {
659 ALOGE("setPowerMode: Bad display");
660 return BAD_INDEX;
661 }
662 if (displayId >= VIRTUAL_DISPLAY_ID_BASE) {
663 ALOGE("setPowerMode: Virtual display %d passed in, returning",
664 displayId);
665 return BAD_INDEX;
666 }
667
668 auto mode = static_cast<HWC2::PowerMode>(intMode);
669 if (mode == HWC2::PowerMode::Off) {
670 setVsyncEnabled(displayId, HWC2::Vsync::Disable);
671 }
672
673 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
674 switch (mode) {
675 case HWC2::PowerMode::Off:
676 case HWC2::PowerMode::On:
677 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
678 {
679 auto error = hwcDisplay->setPowerMode(mode);
680 if (error != HWC2::Error::None) {
681 ALOGE("setPowerMode: Unable to set power mode %s for "
682 "display %d: %s (%d)", to_string(mode).c_str(),
683 displayId, to_string(error).c_str(),
684 static_cast<int32_t>(error));
685 }
686 }
687 break;
688 case HWC2::PowerMode::Doze:
689 case HWC2::PowerMode::DozeSuspend:
690 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
691 {
692 bool supportsDoze = false;
693 auto error = hwcDisplay->supportsDoze(&supportsDoze);
694 if (error != HWC2::Error::None) {
695 ALOGE("setPowerMode: Unable to query doze support for "
696 "display %d: %s (%d)", displayId,
697 to_string(error).c_str(),
698 static_cast<int32_t>(error));
699 }
700 if (!supportsDoze) {
701 mode = HWC2::PowerMode::On;
702 }
703
704 error = hwcDisplay->setPowerMode(mode);
705 if (error != HWC2::Error::None) {
706 ALOGE("setPowerMode: Unable to set power mode %s for "
707 "display %d: %s (%d)", to_string(mode).c_str(),
708 displayId, to_string(error).c_str(),
709 static_cast<int32_t>(error));
710 }
711 }
712 break;
713 default:
714 ALOGV("setPowerMode: Not calling HWC");
715 break;
716 }
717
718 return NO_ERROR;
719 }
720
setActiveConfig(int32_t displayId,size_t configId)721 status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) {
722 if (!isValidDisplay(displayId)) {
723 ALOGE("setActiveConfig: Display %d is not valid", displayId);
724 return BAD_INDEX;
725 }
726
727 auto& displayData = mDisplayData[displayId];
728 if (displayData.configMap.count(configId) == 0) {
729 ALOGE("setActiveConfig: Invalid config %zd", configId);
730 return BAD_INDEX;
731 }
732
733 auto error = displayData.hwcDisplay->setActiveConfig(
734 displayData.configMap[configId]);
735 if (error != HWC2::Error::None) {
736 ALOGE("setActiveConfig: Failed to set config %zu on display %d: "
737 "%s (%d)", configId, displayId, to_string(error).c_str(),
738 static_cast<int32_t>(error));
739 return UNKNOWN_ERROR;
740 }
741
742 return NO_ERROR;
743 }
744
setColorTransform(int32_t displayId,const mat4 & transform)745 status_t HWComposer::setColorTransform(int32_t displayId,
746 const mat4& transform) {
747 if (!isValidDisplay(displayId)) {
748 ALOGE("setColorTransform: Display %d is not valid", displayId);
749 return BAD_INDEX;
750 }
751
752 auto& displayData = mDisplayData[displayId];
753 bool isIdentity = transform == mat4();
754 auto error = displayData.hwcDisplay->setColorTransform(transform,
755 isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
756 HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
757 if (error != HWC2::Error::None) {
758 ALOGE("setColorTransform: Failed to set transform on display %d: "
759 "%s (%d)", displayId, to_string(error).c_str(),
760 static_cast<int32_t>(error));
761 return UNKNOWN_ERROR;
762 }
763
764 return NO_ERROR;
765 }
766
disconnectDisplay(int displayId)767 void HWComposer::disconnectDisplay(int displayId) {
768 LOG_ALWAYS_FATAL_IF(displayId < 0);
769 auto& displayData = mDisplayData[displayId];
770
771 auto displayType = HWC2::DisplayType::Invalid;
772 auto error = displayData.hwcDisplay->getType(&displayType);
773 if (error != HWC2::Error::None) {
774 ALOGE("disconnectDisplay: Failed to determine type of display %d",
775 displayId);
776 return;
777 }
778
779 // If this was a virtual display, add its slot back for reuse by future
780 // virtual displays
781 if (displayType == HWC2::DisplayType::Virtual) {
782 mFreeDisplaySlots.insert(displayId);
783 ++mRemainingHwcVirtualDisplays;
784 }
785
786 auto hwcId = displayData.hwcDisplay->getId();
787 mHwcDisplaySlots.erase(hwcId);
788 displayData.reset();
789 }
790
setOutputBuffer(int32_t displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)791 status_t HWComposer::setOutputBuffer(int32_t displayId,
792 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
793 if (!isValidDisplay(displayId)) {
794 ALOGE("setOutputBuffer: Display %d is not valid", displayId);
795 return BAD_INDEX;
796 }
797
798 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
799 auto displayType = HWC2::DisplayType::Invalid;
800 auto error = hwcDisplay->getType(&displayType);
801 if (error != HWC2::Error::None) {
802 ALOGE("setOutputBuffer: Failed to determine type of display %d",
803 displayId);
804 return NAME_NOT_FOUND;
805 }
806
807 if (displayType != HWC2::DisplayType::Virtual) {
808 ALOGE("setOutputBuffer: Display %d is not virtual", displayId);
809 return INVALID_OPERATION;
810 }
811
812 error = hwcDisplay->setOutputBuffer(buffer, acquireFence);
813 if (error != HWC2::Error::None) {
814 ALOGE("setOutputBuffer: Failed to set buffer on display %d: %s (%d)",
815 displayId, to_string(error).c_str(),
816 static_cast<int32_t>(error));
817 return UNKNOWN_ERROR;
818 }
819
820 return NO_ERROR;
821 }
822
clearReleaseFences(int32_t displayId)823 void HWComposer::clearReleaseFences(int32_t displayId) {
824 if (!isValidDisplay(displayId)) {
825 ALOGE("clearReleaseFences: Display %d is not valid", displayId);
826 return;
827 }
828 mDisplayData[displayId].releaseFences.clear();
829 }
830
getHdrCapabilities(int32_t displayId)831 std::unique_ptr<HdrCapabilities> HWComposer::getHdrCapabilities(
832 int32_t displayId) {
833 if (!isValidDisplay(displayId)) {
834 ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
835 return nullptr;
836 }
837
838 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
839 std::unique_ptr<HdrCapabilities> capabilities;
840 auto error = hwcDisplay->getHdrCapabilities(&capabilities);
841 if (error != HWC2::Error::None) {
842 ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
843 " %s (%d)", displayId, to_string(error).c_str(),
844 static_cast<int32_t>(error));
845 return nullptr;
846 }
847
848 return capabilities;
849 }
850
851 // Converts a PixelFormat to a human-readable string. Max 11 chars.
852 // (Could use a table of prefab String8 objects.)
853 /*
854 static String8 getFormatStr(PixelFormat format) {
855 switch (format) {
856 case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888");
857 case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888");
858 case PIXEL_FORMAT_RGB_888: return String8("RGB_888");
859 case PIXEL_FORMAT_RGB_565: return String8("RGB_565");
860 case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888");
861 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
862 return String8("ImplDef");
863 default:
864 String8 result;
865 result.appendFormat("? %08x", format);
866 return result;
867 }
868 }
869 */
870
isUsingVrComposer() const871 bool HWComposer::isUsingVrComposer() const {
872 return getComposer()->isUsingVrComposer();
873 }
874
dump(String8 & result) const875 void HWComposer::dump(String8& result) const {
876 // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
877 // all the state going into the layers. This is probably better done in
878 // Layer itself, but it's going to take a bit of work to get there.
879 result.append(mHwcDevice->dump().c_str());
880 }
881
882 // ---------------------------------------------------------------------------
883
DisplayData()884 HWComposer::DisplayData::DisplayData()
885 : hasClientComposition(false),
886 hasDeviceComposition(false),
887 hwcDisplay(),
888 lastPresentFence(Fence::NO_FENCE),
889 outbufHandle(nullptr),
890 outbufAcquireFence(Fence::NO_FENCE),
891 vsyncEnabled(HWC2::Vsync::Disable) {
892 ALOGV("Created new DisplayData");
893 }
894
~DisplayData()895 HWComposer::DisplayData::~DisplayData() {
896 }
897
reset()898 void HWComposer::DisplayData::reset() {
899 ALOGV("DisplayData reset");
900 *this = DisplayData();
901 }
902
903 // ---------------------------------------------------------------------------
904 }; // namespace android
905