HWComposer.cpp 33 KB

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