• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <compositionengine/Output.h>
24 #include <compositionengine/OutputLayer.h>
25 #include <compositionengine/impl/OutputLayerCompositionState.h>
26 #include <log/log.h>
27 #include <ui/DebugUtils.h>
28 #include <ui/GraphicBuffer.h>
29 #include <utils/Errors.h>
30 #include <utils/Trace.h>
31 
32 #include "HWComposer.h"
33 #include "HWC2.h"
34 #include "ComposerHal.h"
35 
36 #include "../Layer.h"           // needed only for debugging
37 #include "../SurfaceFlinger.h"
38 
39 #define LOG_HWC_DISPLAY_ERROR(hwcDisplayId, msg) \
40     ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
41 
42 #define LOG_DISPLAY_ERROR(displayId, msg) \
43     ALOGE("%s failed for display %s: %s", __FUNCTION__, to_string(displayId).c_str(), msg)
44 
45 #define LOG_HWC_ERROR(what, error, displayId)                          \
46     ALOGE("%s: %s failed for display %s: %s (%d)", __FUNCTION__, what, \
47           to_string(displayId).c_str(), to_string(error).c_str(), static_cast<int32_t>(error))
48 
49 #define RETURN_IF_INVALID_DISPLAY(displayId, ...)            \
50     do {                                                     \
51         if (mDisplayData.count(displayId) == 0) {            \
52             LOG_DISPLAY_ERROR(displayId, "Invalid display"); \
53             return __VA_ARGS__;                              \
54         }                                                    \
55     } while (false)
56 
57 #define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
58     do {                                                     \
59         if (error != HWC2::Error::None) {                    \
60             LOG_HWC_ERROR(what, error, displayId);           \
61             return __VA_ARGS__;                              \
62         }                                                    \
63     } while (false)
64 
65 #define RETURN_IF_HWC_ERROR(error, displayId, ...) \
66     RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
67 
68 namespace android {
69 
70 HWComposer::~HWComposer() = default;
71 
72 namespace impl {
73 
HWComposer(std::unique_ptr<Hwc2::Composer> composer)74 HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
75       : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
76 
~HWComposer()77 HWComposer::~HWComposer() {
78     mDisplayData.clear();
79 }
80 
registerCallback(HWC2::ComposerCallback * callback,int32_t sequenceId)81 void HWComposer::registerCallback(HWC2::ComposerCallback* callback,
82                                   int32_t sequenceId) {
83     mHwcDevice->registerCallback(callback, sequenceId);
84 }
85 
getDisplayIdentificationData(hwc2_display_t hwcDisplayId,uint8_t * outPort,DisplayIdentificationData * outData) const86 bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
87                                               DisplayIdentificationData* outData) const {
88     const auto error = mHwcDevice->getDisplayIdentificationData(hwcDisplayId, outPort, outData);
89     if (error != HWC2::Error::None) {
90         if (error != HWC2::Error::Unsupported) {
91             LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
92         }
93         return false;
94     }
95     return true;
96 }
97 
hasCapability(HWC2::Capability capability) const98 bool HWComposer::hasCapability(HWC2::Capability capability) const
99 {
100     return mHwcDevice->getCapabilities().count(capability) > 0;
101 }
102 
hasDisplayCapability(const std::optional<DisplayId> & displayId,HWC2::DisplayCapability capability) const103 bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
104                                       HWC2::DisplayCapability capability) const {
105     if (!displayId) {
106         // Checkout global capabilities for displays without a corresponding HWC display.
107         if (capability == HWC2::DisplayCapability::SkipClientColorTransform) {
108             return hasCapability(HWC2::Capability::SkipClientColorTransform);
109         }
110         return false;
111     }
112     RETURN_IF_INVALID_DISPLAY(*displayId, false);
113     return mDisplayData.at(*displayId).hwcDisplay->getCapabilities().count(capability) > 0;
114 }
115 
validateChange(HWC2::Composition from,HWC2::Composition to)116 void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
117     bool valid = true;
118     switch (from) {
119         case HWC2::Composition::Client:
120             valid = false;
121             break;
122         case HWC2::Composition::Device:
123         case HWC2::Composition::SolidColor:
124             valid = (to == HWC2::Composition::Client);
125             break;
126         case HWC2::Composition::Cursor:
127         case HWC2::Composition::Sideband:
128             valid = (to == HWC2::Composition::Client ||
129                     to == HWC2::Composition::Device);
130             break;
131         default:
132             break;
133     }
134 
135     if (!valid) {
136         ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(),
137                 to_string(to).c_str());
138     }
139 }
140 
onHotplug(hwc2_display_t hwcDisplayId,HWC2::Connection connection)141 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hwcDisplayId,
142                                                                HWC2::Connection connection) {
143     std::optional<DisplayIdentificationInfo> info;
144 
145     if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
146         info = DisplayIdentificationInfo{*displayId, std::string()};
147     } else {
148         if (connection == HWC2::Connection::Disconnected) {
149             ALOGE("Ignoring disconnection of invalid HWC display %" PRIu64, hwcDisplayId);
150             return {};
151         }
152 
153         info = onHotplugConnect(hwcDisplayId);
154         if (!info) return {};
155     }
156 
157     ALOGV("%s: %s %s display %s with HWC ID %" PRIu64, __FUNCTION__, to_string(connection).c_str(),
158           hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external",
159           to_string(info->id).c_str(), hwcDisplayId);
160 
161     mHwcDevice->onHotplug(hwcDisplayId, connection);
162 
163     // Disconnect is handled through HWComposer::disconnectDisplay via
164     // SurfaceFlinger's onHotplugReceived callback handling
165     if (connection == HWC2::Connection::Connected) {
166         mDisplayData[info->id].hwcDisplay = mHwcDevice->getDisplayById(hwcDisplayId);
167         mPhysicalDisplayIdMap[hwcDisplayId] = info->id;
168     }
169 
170     return info;
171 }
172 
onVsync(hwc2_display_t hwcDisplayId,int64_t timestamp)173 bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) {
174     const auto displayId = toPhysicalDisplayId(hwcDisplayId);
175     if (!displayId) {
176         LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
177         return false;
178     }
179 
180     RETURN_IF_INVALID_DISPLAY(*displayId, false);
181 
182     auto& displayData = mDisplayData[*displayId];
183     if (displayData.isVirtual) {
184         LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
185         return false;
186     }
187 
188     {
189         std::lock_guard lock(displayData.lastHwVsyncLock);
190 
191         // There have been reports of HWCs that signal several vsync events
192         // with the same timestamp when turning the display off and on. This
193         // is a bug in the HWC implementation, but filter the extra events
194         // out here so they don't cause havoc downstream.
195         if (timestamp == displayData.lastHwVsync) {
196             ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
197                   to_string(*displayId).c_str(), timestamp);
198             return false;
199         }
200 
201         displayData.lastHwVsync = timestamp;
202     }
203 
204     const auto tag = "HW_VSYNC_" + to_string(*displayId);
205     ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
206     displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
207 
208     return true;
209 }
210 
allocateVirtualDisplay(uint32_t width,uint32_t height,ui::PixelFormat * format)211 std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
212                                                             ui::PixelFormat* format) {
213     if (mRemainingHwcVirtualDisplays == 0) {
214         ALOGE("%s: No remaining virtual displays", __FUNCTION__);
215         return {};
216     }
217 
218     if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
219         (width > SurfaceFlinger::maxVirtualDisplaySize ||
220          height > SurfaceFlinger::maxVirtualDisplaySize)) {
221         ALOGE("%s: Display size %ux%u exceeds maximum dimension of %" PRIu64, __FUNCTION__, width,
222               height, SurfaceFlinger::maxVirtualDisplaySize);
223         return {};
224     }
225     HWC2::Display* display;
226     auto error = mHwcDevice->createVirtualDisplay(width, height, format,
227             &display);
228     if (error != HWC2::Error::None) {
229         ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
230         return {};
231     }
232 
233     DisplayId displayId;
234     if (mFreeVirtualDisplayIds.empty()) {
235         displayId = getVirtualDisplayId(mNextVirtualDisplayId++);
236     } else {
237         displayId = *mFreeVirtualDisplayIds.begin();
238         mFreeVirtualDisplayIds.erase(displayId);
239     }
240 
241     auto& displayData = mDisplayData[displayId];
242     displayData.hwcDisplay = display;
243     displayData.isVirtual = true;
244 
245     --mRemainingHwcVirtualDisplays;
246     return displayId;
247 }
248 
createLayer(DisplayId displayId)249 HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
250     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
251 
252     auto display = mDisplayData[displayId].hwcDisplay;
253     HWC2::Layer* layer;
254     auto error = display->createLayer(&layer);
255     RETURN_IF_HWC_ERROR(error, displayId, nullptr);
256     return layer;
257 }
258 
destroyLayer(DisplayId displayId,HWC2::Layer * layer)259 void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {
260     RETURN_IF_INVALID_DISPLAY(displayId);
261 
262     auto display = mDisplayData[displayId].hwcDisplay;
263     auto error = display->destroyLayer(layer);
264     RETURN_IF_HWC_ERROR(error, displayId);
265 }
266 
getRefreshTimestamp(DisplayId displayId) const267 nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
268     RETURN_IF_INVALID_DISPLAY(displayId, 0);
269     const auto& displayData = mDisplayData.at(displayId);
270     // this returns the last refresh timestamp.
271     // if the last one is not available, we estimate it based on
272     // the refresh period and whatever closest timestamp we have.
273     std::lock_guard lock(displayData.lastHwVsyncLock);
274     nsecs_t now = systemTime(CLOCK_MONOTONIC);
275     auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
276     return now - ((now - displayData.lastHwVsync) % vsyncPeriod);
277 }
278 
isConnected(DisplayId displayId) const279 bool HWComposer::isConnected(DisplayId displayId) const {
280     RETURN_IF_INVALID_DISPLAY(displayId, false);
281     return mDisplayData.at(displayId).hwcDisplay->isConnected();
282 }
283 
getConfigs(DisplayId displayId) const284 std::vector<std::shared_ptr<const HWC2::Display::Config>> HWComposer::getConfigs(
285         DisplayId displayId) const {
286     RETURN_IF_INVALID_DISPLAY(displayId, {});
287 
288     const auto& displayData = mDisplayData.at(displayId);
289     auto configs = displayData.hwcDisplay->getConfigs();
290     if (displayData.configMap.empty()) {
291         for (size_t i = 0; i < configs.size(); ++i) {
292             displayData.configMap[i] = configs[i];
293         }
294     }
295     return configs;
296 }
297 
getActiveConfig(DisplayId displayId) const298 std::shared_ptr<const HWC2::Display::Config> HWComposer::getActiveConfig(
299         DisplayId displayId) const {
300     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
301 
302     std::shared_ptr<const HWC2::Display::Config> config;
303     auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfig(&config);
304     if (error == HWC2::Error::BadConfig) {
305         LOG_DISPLAY_ERROR(displayId, "No active config");
306         return nullptr;
307     }
308 
309     RETURN_IF_HWC_ERROR(error, displayId, nullptr);
310 
311     if (!config) {
312         LOG_DISPLAY_ERROR(displayId, "Unknown config");
313         return nullptr;
314     }
315 
316     return config;
317 }
318 
getActiveConfigIndex(DisplayId displayId) const319 int HWComposer::getActiveConfigIndex(DisplayId displayId) const {
320     RETURN_IF_INVALID_DISPLAY(displayId, -1);
321 
322     int index;
323     auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfigIndex(&index);
324     if (error == HWC2::Error::BadConfig) {
325         LOG_DISPLAY_ERROR(displayId, "No active config");
326         return -1;
327     }
328 
329     RETURN_IF_HWC_ERROR(error, displayId, -1);
330 
331     if (index < 0) {
332         LOG_DISPLAY_ERROR(displayId, "Unknown config");
333         return -1;
334     }
335 
336     return index;
337 }
338 
getColorModes(DisplayId displayId) const339 std::vector<ui::ColorMode> HWComposer::getColorModes(DisplayId displayId) const {
340     RETURN_IF_INVALID_DISPLAY(displayId, {});
341 
342     std::vector<ui::ColorMode> modes;
343     auto error = mDisplayData.at(displayId).hwcDisplay->getColorModes(&modes);
344     RETURN_IF_HWC_ERROR(error, displayId, {});
345     return modes;
346 }
347 
setActiveColorMode(DisplayId displayId,ui::ColorMode mode,ui::RenderIntent renderIntent)348 status_t HWComposer::setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
349                                         ui::RenderIntent renderIntent) {
350     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
351 
352     auto& displayData = mDisplayData[displayId];
353     auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent);
354     RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " +
355                              decodeRenderIntent(renderIntent) + ")")
356                                     .c_str(),
357                             error, displayId, UNKNOWN_ERROR);
358 
359     return NO_ERROR;
360 }
361 
setVsyncEnabled(DisplayId displayId,HWC2::Vsync enabled)362 void HWComposer::setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) {
363     RETURN_IF_INVALID_DISPLAY(displayId);
364     auto& displayData = mDisplayData[displayId];
365 
366     if (displayData.isVirtual) {
367         LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
368         return;
369     }
370 
371     // NOTE: we use our own internal lock here because we have to call
372     // into the HWC with the lock held, and we want to make sure
373     // that even if HWC blocks (which it shouldn't), it won't
374     // affect other threads.
375     std::lock_guard lock(displayData.vsyncEnabledLock);
376     if (enabled == displayData.vsyncEnabled) {
377         return;
378     }
379 
380     ATRACE_CALL();
381     auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
382     RETURN_IF_HWC_ERROR(error, displayId);
383 
384     displayData.vsyncEnabled = enabled;
385 
386     const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
387     ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
388 }
389 
setClientTarget(DisplayId displayId,uint32_t slot,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & target,ui::Dataspace dataspace)390 status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
391                                      const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
392                                      ui::Dataspace dataspace) {
393     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
394 
395     ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
396     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
397     auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
398     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
399     return NO_ERROR;
400 }
401 
prepare(DisplayId displayId,const compositionengine::Output & output)402 status_t HWComposer::prepare(DisplayId displayId, const compositionengine::Output& output) {
403     ATRACE_CALL();
404 
405     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
406 
407     auto& displayData = mDisplayData[displayId];
408     auto& hwcDisplay = displayData.hwcDisplay;
409     if (!hwcDisplay->isConnected()) {
410         return NO_ERROR;
411     }
412 
413     uint32_t numTypes = 0;
414     uint32_t numRequests = 0;
415 
416     HWC2::Error error = HWC2::Error::None;
417 
418     // First try to skip validate altogether when there is no client
419     // composition.  When there is client composition, since we haven't
420     // rendered to the client target yet, we should not attempt to skip
421     // validate.
422     //
423     // displayData.hasClientComposition hasn't been updated for this frame.
424     // The check below is incorrect.  We actually rely on HWC here to fall
425     // back to validate when there is any client layer.
426     displayData.validateWasSkipped = false;
427     if (!displayData.hasClientComposition) {
428         sp<Fence> outPresentFence;
429         uint32_t state = UINT32_MAX;
430         error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
431         if (error != HWC2::Error::HasChanges) {
432             RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
433         }
434         if (state == 1) { //Present Succeeded.
435             std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
436             error = hwcDisplay->getReleaseFences(&releaseFences);
437             displayData.releaseFences = std::move(releaseFences);
438             displayData.lastPresentFence = outPresentFence;
439             displayData.validateWasSkipped = true;
440             displayData.presentError = error;
441             return NO_ERROR;
442         }
443         // Present failed but Validate ran.
444     } else {
445         error = hwcDisplay->validate(&numTypes, &numRequests);
446     }
447     ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
448     if (error != HWC2::Error::HasChanges) {
449         RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
450     }
451 
452     std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
453     changedTypes.reserve(numTypes);
454     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
455     RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
456 
457     displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
458     std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
459     layerRequests.reserve(numRequests);
460     error = hwcDisplay->getRequests(&displayData.displayRequests,
461             &layerRequests);
462     RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
463 
464     displayData.hasClientComposition = false;
465     displayData.hasDeviceComposition = false;
466     for (auto& outputLayer : output.getOutputLayersOrderedByZ()) {
467         auto& state = outputLayer->editState();
468         LOG_FATAL_IF(!state.hwc.);
469         auto hwcLayer = (*state.hwc).hwcLayer;
470 
471         if (auto it = changedTypes.find(hwcLayer.get()); it != changedTypes.end()) {
472             auto newCompositionType = it->second;
473             validateChange(static_cast<HWC2::Composition>((*state.hwc).hwcCompositionType),
474                            newCompositionType);
475             (*state.hwc).hwcCompositionType =
476                     static_cast<Hwc2::IComposerClient::Composition>(newCompositionType);
477         }
478 
479         switch ((*state.hwc).hwcCompositionType) {
480             case Hwc2::IComposerClient::Composition::CLIENT:
481                 displayData.hasClientComposition = true;
482                 break;
483             case Hwc2::IComposerClient::Composition::DEVICE:
484             case Hwc2::IComposerClient::Composition::SOLID_COLOR:
485             case Hwc2::IComposerClient::Composition::CURSOR:
486             case Hwc2::IComposerClient::Composition::SIDEBAND:
487                 displayData.hasDeviceComposition = true;
488                 break;
489             default:
490                 break;
491         }
492 
493         state.clearClientTarget = false;
494         if (auto it = layerRequests.find(hwcLayer.get()); it != layerRequests.end()) {
495             auto request = it->second;
496             if (request == HWC2::LayerRequest::ClearClientTarget) {
497                 state.clearClientTarget = true;
498             } else {
499                 LOG_DISPLAY_ERROR(displayId,
500                                   ("Unknown layer request " + to_string(request)).c_str());
501             }
502         }
503     }
504 
505     error = hwcDisplay->acceptChanges();
506     RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
507 
508     return NO_ERROR;
509 }
510 
hasDeviceComposition(const std::optional<DisplayId> & displayId) const511 bool HWComposer::hasDeviceComposition(const std::optional<DisplayId>& displayId) const {
512     if (!displayId) {
513         // Displays without a corresponding HWC display are never composed by
514         // the device
515         return false;
516     }
517 
518     RETURN_IF_INVALID_DISPLAY(*displayId, false);
519     return mDisplayData.at(*displayId).hasDeviceComposition;
520 }
521 
hasFlipClientTargetRequest(const std::optional<DisplayId> & displayId) const522 bool HWComposer::hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const {
523     if (!displayId) {
524         // Displays without a corresponding HWC display are never composed by
525         // the device
526         return false;
527     }
528 
529     RETURN_IF_INVALID_DISPLAY(*displayId, false);
530     return ((static_cast<uint32_t>(mDisplayData.at(*displayId).displayRequests) &
531              static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0);
532 }
533 
hasClientComposition(const std::optional<DisplayId> & displayId) const534 bool HWComposer::hasClientComposition(const std::optional<DisplayId>& displayId) const {
535     if (!displayId) {
536         // Displays without a corresponding HWC display are always composed by
537         // the client
538         return true;
539     }
540 
541     RETURN_IF_INVALID_DISPLAY(*displayId, true);
542     return mDisplayData.at(*displayId).hasClientComposition;
543 }
544 
getPresentFence(DisplayId displayId) const545 sp<Fence> HWComposer::getPresentFence(DisplayId displayId) const {
546     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
547     return mDisplayData.at(displayId).lastPresentFence;
548 }
549 
getLayerReleaseFence(DisplayId displayId,HWC2::Layer * layer) const550 sp<Fence> HWComposer::getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const {
551     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
552     auto displayFences = mDisplayData.at(displayId).releaseFences;
553     if (displayFences.count(layer) == 0) {
554         ALOGV("getLayerReleaseFence: Release fence not found");
555         return Fence::NO_FENCE;
556     }
557     return displayFences[layer];
558 }
559 
presentAndGetReleaseFences(DisplayId displayId)560 status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
561     ATRACE_CALL();
562 
563     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
564 
565     auto& displayData = mDisplayData[displayId];
566     auto& hwcDisplay = displayData.hwcDisplay;
567 
568     if (displayData.validateWasSkipped) {
569         // explicitly flush all pending commands
570         auto error = mHwcDevice->flushCommands();
571         RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR);
572         RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
573         return NO_ERROR;
574     }
575 
576     auto error = hwcDisplay->present(&displayData.lastPresentFence);
577     RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
578 
579     std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
580     error = hwcDisplay->getReleaseFences(&releaseFences);
581     RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
582 
583     displayData.releaseFences = std::move(releaseFences);
584 
585     return NO_ERROR;
586 }
587 
setPowerMode(DisplayId displayId,int32_t intMode)588 status_t HWComposer::setPowerMode(DisplayId displayId, int32_t intMode) {
589     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
590 
591     const auto& displayData = mDisplayData[displayId];
592     if (displayData.isVirtual) {
593         LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
594         return INVALID_OPERATION;
595     }
596 
597     auto mode = static_cast<HWC2::PowerMode>(intMode);
598     if (mode == HWC2::PowerMode::Off) {
599         setVsyncEnabled(displayId, HWC2::Vsync::Disable);
600     }
601 
602     auto& hwcDisplay = displayData.hwcDisplay;
603     switch (mode) {
604         case HWC2::PowerMode::Off:
605         case HWC2::PowerMode::On:
606             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
607             {
608                 auto error = hwcDisplay->setPowerMode(mode);
609                 if (error != HWC2::Error::None) {
610                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
611                                   error, displayId);
612                 }
613             }
614             break;
615         case HWC2::PowerMode::Doze:
616         case HWC2::PowerMode::DozeSuspend:
617             ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
618             {
619                 bool supportsDoze = false;
620                 auto error = hwcDisplay->supportsDoze(&supportsDoze);
621                 if (error != HWC2::Error::None) {
622                     LOG_HWC_ERROR("supportsDoze", error, displayId);
623                 }
624 
625                 if (!supportsDoze) {
626                     mode = HWC2::PowerMode::On;
627                 }
628 
629                 error = hwcDisplay->setPowerMode(mode);
630                 if (error != HWC2::Error::None) {
631                     LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
632                                   error, displayId);
633                 }
634             }
635             break;
636         default:
637             ALOGV("setPowerMode: Not calling HWC");
638             break;
639     }
640 
641     return NO_ERROR;
642 }
643 
setActiveConfig(DisplayId displayId,size_t configId)644 status_t HWComposer::setActiveConfig(DisplayId displayId, size_t configId) {
645     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
646 
647     auto& displayData = mDisplayData[displayId];
648     if (displayData.configMap.count(configId) == 0) {
649         LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str());
650         return BAD_INDEX;
651     }
652 
653     auto error = displayData.hwcDisplay->setActiveConfig(displayData.configMap[configId]);
654     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
655     return NO_ERROR;
656 }
657 
setColorTransform(DisplayId displayId,const mat4 & transform)658 status_t HWComposer::setColorTransform(DisplayId displayId, const mat4& transform) {
659     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
660 
661     auto& displayData = mDisplayData[displayId];
662     bool isIdentity = transform == mat4();
663     auto error = displayData.hwcDisplay->setColorTransform(transform,
664             isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
665             HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
666     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
667     return NO_ERROR;
668 }
669 
disconnectDisplay(DisplayId displayId)670 void HWComposer::disconnectDisplay(DisplayId displayId) {
671     RETURN_IF_INVALID_DISPLAY(displayId);
672     auto& displayData = mDisplayData[displayId];
673 
674     // If this was a virtual display, add its slot back for reuse by future
675     // virtual displays
676     if (displayData.isVirtual) {
677         mFreeVirtualDisplayIds.insert(displayId);
678         ++mRemainingHwcVirtualDisplays;
679     }
680 
681     const auto hwcDisplayId = displayData.hwcDisplay->getId();
682     mPhysicalDisplayIdMap.erase(hwcDisplayId);
683     mDisplayData.erase(displayId);
684 
685     // TODO(b/74619554): Select internal/external display from remaining displays.
686     if (hwcDisplayId == mInternalHwcDisplayId) {
687         mInternalHwcDisplayId.reset();
688     } else if (hwcDisplayId == mExternalHwcDisplayId) {
689         mExternalHwcDisplayId.reset();
690     }
691 
692     mHwcDevice->destroyDisplay(hwcDisplayId);
693 }
694 
setOutputBuffer(DisplayId displayId,const sp<Fence> & acquireFence,const sp<GraphicBuffer> & buffer)695 status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
696                                      const sp<GraphicBuffer>& buffer) {
697     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
698     const auto& displayData = mDisplayData[displayId];
699 
700     if (!displayData.isVirtual) {
701         LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
702         return INVALID_OPERATION;
703     }
704 
705     auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
706     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
707     return NO_ERROR;
708 }
709 
clearReleaseFences(DisplayId displayId)710 void HWComposer::clearReleaseFences(DisplayId displayId) {
711     RETURN_IF_INVALID_DISPLAY(displayId);
712     mDisplayData[displayId].releaseFences.clear();
713 }
714 
getHdrCapabilities(DisplayId displayId,HdrCapabilities * outCapabilities)715 status_t HWComposer::getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) {
716     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
717 
718     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
719     auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
720     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
721     return NO_ERROR;
722 }
723 
getSupportedPerFrameMetadata(DisplayId displayId) const724 int32_t HWComposer::getSupportedPerFrameMetadata(DisplayId displayId) const {
725     RETURN_IF_INVALID_DISPLAY(displayId, 0);
726     return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
727 }
728 
getRenderIntents(DisplayId displayId,ui::ColorMode colorMode) const729 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(DisplayId displayId,
730                                                            ui::ColorMode colorMode) const {
731     RETURN_IF_INVALID_DISPLAY(displayId, {});
732 
733     std::vector<ui::RenderIntent> renderIntents;
734     auto error = mDisplayData.at(displayId).hwcDisplay->getRenderIntents(colorMode, &renderIntents);
735     RETURN_IF_HWC_ERROR(error, displayId, {});
736     return renderIntents;
737 }
738 
getDataspaceSaturationMatrix(DisplayId displayId,ui::Dataspace dataspace)739 mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) {
740     RETURN_IF_INVALID_DISPLAY(displayId, {});
741 
742     mat4 matrix;
743     auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace,
744             &matrix);
745     RETURN_IF_HWC_ERROR(error, displayId, {});
746     return matrix;
747 }
748 
getDisplayedContentSamplingAttributes(DisplayId displayId,ui::PixelFormat * outFormat,ui::Dataspace * outDataspace,uint8_t * outComponentMask)749 status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId,
750                                                            ui::PixelFormat* outFormat,
751                                                            ui::Dataspace* outDataspace,
752                                                            uint8_t* outComponentMask) {
753     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
754     const auto error =
755             mDisplayData[displayId]
756                     .hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
757                                                                        outComponentMask);
758     if (error == HWC2::Error::Unsupported) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
759     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
760     return NO_ERROR;
761 }
762 
setDisplayContentSamplingEnabled(DisplayId displayId,bool enabled,uint8_t componentMask,uint64_t maxFrames)763 status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
764                                                       uint8_t componentMask, uint64_t maxFrames) {
765     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
766     const auto error =
767             mDisplayData[displayId].hwcDisplay->setDisplayContentSamplingEnabled(enabled,
768                                                                                  componentMask,
769                                                                                  maxFrames);
770 
771     if (error == HWC2::Error::Unsupported) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
772     if (error == HWC2::Error::BadParameter) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
773     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
774     return NO_ERROR;
775 }
776 
getDisplayedContentSample(DisplayId displayId,uint64_t maxFrames,uint64_t timestamp,DisplayedFrameStats * outStats)777 status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
778                                                uint64_t timestamp, DisplayedFrameStats* outStats) {
779     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
780     const auto error =
781             mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
782                                                                           outStats);
783     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
784     return NO_ERROR;
785 }
786 
setDisplayBrightness(DisplayId displayId,float brightness)787 status_t HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
788     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
789     const auto error = mDisplayData[displayId].hwcDisplay->setDisplayBrightness(brightness);
790     if (error == HWC2::Error::Unsupported) {
791         RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
792     }
793     if (error == HWC2::Error::BadParameter) {
794         RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
795     }
796     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
797     return NO_ERROR;
798 }
799 
isUsingVrComposer() const800 bool HWComposer::isUsingVrComposer() const {
801     return getComposer()->isUsingVrComposer();
802 }
803 
dump(std::string & result) const804 void HWComposer::dump(std::string& result) const {
805     // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
806     // all the state going into the layers. This is probably better done in
807     // Layer itself, but it's going to take a bit of work to get there.
808     result.append(mHwcDevice->dump());
809 }
810 
toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const811 std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const {
812     if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
813         it != mPhysicalDisplayIdMap.end()) {
814         return it->second;
815     }
816     return {};
817 }
818 
fromPhysicalDisplayId(DisplayId displayId) const819 std::optional<hwc2_display_t> HWComposer::fromPhysicalDisplayId(DisplayId displayId) const {
820     if (const auto it = mDisplayData.find(displayId);
821         it != mDisplayData.end() && !it->second.isVirtual) {
822         return it->second.hwcDisplay->getId();
823     }
824     return {};
825 }
826 
onHotplugConnect(hwc2_display_t hwcDisplayId)827 std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(hwc2_display_t hwcDisplayId) {
828     if (isUsingVrComposer() && mInternalHwcDisplayId) {
829         ALOGE("Ignoring connection of external display %" PRIu64 " in VR mode", hwcDisplayId);
830         return {};
831     }
832 
833     uint8_t port;
834     DisplayIdentificationData data;
835     const bool hasMultiDisplaySupport = getDisplayIdentificationData(hwcDisplayId, &port, &data);
836 
837     if (mPhysicalDisplayIdMap.empty()) {
838         mHasMultiDisplaySupport = hasMultiDisplaySupport;
839         ALOGI("Switching to %s multi-display mode",
840               hasMultiDisplaySupport ? "generalized" : "legacy");
841     } else if (mHasMultiDisplaySupport && !hasMultiDisplaySupport) {
842         ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
843               hwcDisplayId);
844         return {};
845     }
846 
847     std::optional<DisplayIdentificationInfo> info;
848 
849     if (mHasMultiDisplaySupport) {
850         info = parseDisplayIdentificationData(port, data);
851         ALOGE_IF(!info, "Failed to parse identification data for display %" PRIu64, hwcDisplayId);
852     } else if (mInternalHwcDisplayId && mExternalHwcDisplayId) {
853         ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
854         return {};
855     } else {
856         ALOGW_IF(hasMultiDisplaySupport, "Ignoring identification data for display %" PRIu64,
857                  hwcDisplayId);
858         port = mInternalHwcDisplayId ? HWC_DISPLAY_EXTERNAL : HWC_DISPLAY_PRIMARY;
859     }
860 
861     if (!mInternalHwcDisplayId) {
862         mInternalHwcDisplayId = hwcDisplayId;
863     } else if (!mExternalHwcDisplayId) {
864         mExternalHwcDisplayId = hwcDisplayId;
865     }
866 
867     if (info) return info;
868 
869     return DisplayIdentificationInfo{getFallbackDisplayId(port),
870                                      hwcDisplayId == mInternalHwcDisplayId ? "Internal display"
871                                                                            : "External display"};
872 }
873 
874 } // namespace impl
875 } // namespace android
876