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