1 /*
2 * Copyright 2015 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 "HWC2"
21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
22
23 #include "HWC2.h"
24 #include "ComposerHal.h"
25
26 #include <ui/Fence.h>
27 #include <ui/FloatRect.h>
28 #include <ui/GraphicBuffer.h>
29
30 #include <android/configuration.h>
31
32 #include <inttypes.h>
33 #include <algorithm>
34 #include <iterator>
35 #include <set>
36
37 using android::Fence;
38 using android::FloatRect;
39 using android::GraphicBuffer;
40 using android::HdrCapabilities;
41 using android::HdrMetadata;
42 using android::Rect;
43 using android::Region;
44 using android::sp;
45 using android::hardware::Return;
46 using android::hardware::Void;
47
48 namespace HWC2 {
49
50 namespace Hwc2 = android::Hwc2;
51 using android::ui::ColorMode;
52 using android::ui::Dataspace;
53 using android::ui::PixelFormat;
54 using android::ui::RenderIntent;
55
56 namespace {
57
hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey> & keys,const Hwc2::PerFrameMetadataKey & key)58 inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys,
59 const Hwc2::PerFrameMetadataKey& key) {
60 return keys.find(key) != keys.end();
61 }
62
63 class ComposerCallbackBridge : public Hwc2::IComposerCallback {
64 public:
ComposerCallbackBridge(ComposerCallback * callback,int32_t sequenceId)65 ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
66 : mCallback(callback), mSequenceId(sequenceId) {}
67
onHotplug(Hwc2::Display display,IComposerCallback::Connection conn)68 Return<void> onHotplug(Hwc2::Display display,
69 IComposerCallback::Connection conn) override
70 {
71 HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
72 mCallback->onHotplugReceived(mSequenceId, display, connection);
73 return Void();
74 }
75
onRefresh(Hwc2::Display display)76 Return<void> onRefresh(Hwc2::Display display) override
77 {
78 mCallback->onRefreshReceived(mSequenceId, display);
79 return Void();
80 }
81
onVsync(Hwc2::Display display,int64_t timestamp)82 Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
83 {
84 mCallback->onVsyncReceived(mSequenceId, display, timestamp);
85 return Void();
86 }
87
88 private:
89 ComposerCallback* mCallback;
90 int32_t mSequenceId;
91 };
92
93 } // namespace anonymous
94
95
96 // Device methods
97
Device(std::unique_ptr<android::Hwc2::Composer> composer)98 Device::Device(std::unique_ptr<android::Hwc2::Composer> composer) : mComposer(std::move(composer)) {
99 loadCapabilities();
100 }
101
registerCallback(ComposerCallback * callback,int32_t sequenceId)102 void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {
103 if (mRegisteredCallback) {
104 ALOGW("Callback already registered. Ignored extra registration "
105 "attempt.");
106 return;
107 }
108 mRegisteredCallback = true;
109 sp<ComposerCallbackBridge> callbackBridge(
110 new ComposerCallbackBridge(callback, sequenceId));
111 mComposer->registerCallback(callbackBridge);
112 }
113
114 // Required by HWC2 device
115
dump() const116 std::string Device::dump() const
117 {
118 return mComposer->dumpDebugInfo();
119 }
120
getMaxVirtualDisplayCount() const121 uint32_t Device::getMaxVirtualDisplayCount() const
122 {
123 return mComposer->getMaxVirtualDisplayCount();
124 }
125
getDisplayIdentificationData(hwc2_display_t hwcDisplayId,uint8_t * outPort,std::vector<uint8_t> * outData) const126 Error Device::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
127 std::vector<uint8_t>* outData) const {
128 auto intError = mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData);
129 return static_cast<Error>(intError);
130 }
131
createVirtualDisplay(uint32_t width,uint32_t height,PixelFormat * format,Display ** outDisplay)132 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
133 PixelFormat* format, Display** outDisplay)
134 {
135 ALOGI("Creating virtual display");
136
137 hwc2_display_t displayId = 0;
138 auto intError = mComposer->createVirtualDisplay(width, height,
139 format, &displayId);
140 auto error = static_cast<Error>(intError);
141 if (error != Error::None) {
142 return error;
143 }
144
145 auto display = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId,
146 DisplayType::Virtual);
147 display->setConnected(true);
148 *outDisplay = display.get();
149 mDisplays.emplace(displayId, std::move(display));
150 ALOGI("Created virtual display");
151 return Error::None;
152 }
153
destroyDisplay(hwc2_display_t displayId)154 void Device::destroyDisplay(hwc2_display_t displayId)
155 {
156 ALOGI("Destroying display %" PRIu64, displayId);
157 mDisplays.erase(displayId);
158 }
159
onHotplug(hwc2_display_t displayId,Connection connection)160 void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
161 if (connection == Connection::Connected) {
162 // If we get a hotplug connected event for a display we already have,
163 // destroy the display and recreate it. This will force us to requery
164 // the display params and recreate all layers on that display.
165 auto oldDisplay = getDisplayById(displayId);
166 if (oldDisplay != nullptr && oldDisplay->isConnected()) {
167 ALOGI("Hotplug connecting an already connected display."
168 " Clearing old display state.");
169 }
170 mDisplays.erase(displayId);
171
172 DisplayType displayType;
173 auto intError = mComposer->getDisplayType(displayId,
174 reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(
175 &displayType));
176 auto error = static_cast<Error>(intError);
177 if (error != Error::None) {
178 ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). "
179 "Aborting hotplug attempt.",
180 displayId, to_string(error).c_str(), intError);
181 return;
182 }
183
184 auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities,
185 displayId, displayType);
186 newDisplay->setConnected(true);
187 mDisplays.emplace(displayId, std::move(newDisplay));
188 } else if (connection == Connection::Disconnected) {
189 // The display will later be destroyed by a call to
190 // destroyDisplay(). For now we just mark it disconnected.
191 auto display = getDisplayById(displayId);
192 if (display) {
193 display->setConnected(false);
194 } else {
195 ALOGW("Attempted to disconnect unknown display %" PRIu64,
196 displayId);
197 }
198 }
199 }
200
201 // Other Device methods
202
getDisplayById(hwc2_display_t id)203 Display* Device::getDisplayById(hwc2_display_t id) {
204 auto iter = mDisplays.find(id);
205 return iter == mDisplays.end() ? nullptr : iter->second.get();
206 }
207
208 // Device initialization methods
209
loadCapabilities()210 void Device::loadCapabilities()
211 {
212 static_assert(sizeof(Capability) == sizeof(int32_t),
213 "Capability size has changed");
214 auto capabilities = mComposer->getCapabilities();
215 for (auto capability : capabilities) {
216 mCapabilities.emplace(static_cast<Capability>(capability));
217 }
218 }
219
flushCommands()220 Error Device::flushCommands()
221 {
222 return static_cast<Error>(mComposer->executeCommands());
223 }
224
225 // Display methods
226 Display::~Display() = default;
227
Config(Display & display,hwc2_config_t id)228 Display::Config::Config(Display& display, hwc2_config_t id)
229 : mDisplay(display),
230 mId(id),
231 mWidth(-1),
232 mHeight(-1),
233 mVsyncPeriod(-1),
234 mDpiX(-1),
235 mDpiY(-1) {}
236
Builder(Display & display,hwc2_config_t id)237 Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
238 : mConfig(new Config(display, id)) {}
239
getDefaultDensity()240 float Display::Config::Builder::getDefaultDensity() {
241 // Default density is based on TVs: 1080p displays get XHIGH density, lower-
242 // resolution displays get TV density. Maybe eventually we'll need to update
243 // it for 4k displays, though hopefully those will just report accurate DPI
244 // information to begin with. This is also used for virtual displays and
245 // older HWC implementations, so be careful about orientation.
246
247 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
248 if (longDimension >= 1080) {
249 return ACONFIGURATION_DENSITY_XHIGH;
250 } else {
251 return ACONFIGURATION_DENSITY_TV;
252 }
253 }
254
255 namespace impl {
Display(android::Hwc2::Composer & composer,const std::unordered_set<Capability> & capabilities,hwc2_display_t id,DisplayType type)256 Display::Display(android::Hwc2::Composer& composer,
257 const std::unordered_set<Capability>& capabilities, hwc2_display_t id,
258 DisplayType type)
259 : mComposer(composer),
260 mCapabilities(capabilities),
261 mId(id),
262 mIsConnected(false),
263 mType(type) {
264 ALOGV("Created display %" PRIu64, id);
265 }
266
~Display()267 Display::~Display() {
268 mLayers.clear();
269
270 if (mType == DisplayType::Virtual) {
271 ALOGV("Destroying virtual display");
272 auto intError = mComposer.destroyVirtualDisplay(mId);
273 auto error = static_cast<Error>(intError);
274 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64
275 ") failed: %s (%d)", mId, to_string(error).c_str(), intError);
276 } else if (mType == DisplayType::Physical) {
277 auto error = setVsyncEnabled(HWC2::Vsync::Disable);
278 if (error != Error::None) {
279 ALOGE("~Display: Failed to disable vsync for display %" PRIu64
280 ": %s (%d)", mId, to_string(error).c_str(),
281 static_cast<int32_t>(error));
282 }
283 }
284 }
285
286 // Required by HWC2 display
acceptChanges()287 Error Display::acceptChanges()
288 {
289 auto intError = mComposer.acceptDisplayChanges(mId);
290 return static_cast<Error>(intError);
291 }
292
createLayer(HWC2::Layer ** outLayer)293 Error Display::createLayer(HWC2::Layer** outLayer) {
294 if (!outLayer) {
295 return Error::BadParameter;
296 }
297 hwc2_layer_t layerId = 0;
298 auto intError = mComposer.createLayer(mId, &layerId);
299 auto error = static_cast<Error>(intError);
300 if (error != Error::None) {
301 return error;
302 }
303
304 auto layer = std::make_unique<impl::Layer>(mComposer, mCapabilities, mId, layerId);
305 *outLayer = layer.get();
306 mLayers.emplace(layerId, std::move(layer));
307 return Error::None;
308 }
309
destroyLayer(HWC2::Layer * layer)310 Error Display::destroyLayer(HWC2::Layer* layer) {
311 if (!layer) {
312 return Error::BadParameter;
313 }
314 mLayers.erase(layer->getId());
315 return Error::None;
316 }
317
getActiveConfig(std::shared_ptr<const Display::Config> * outConfig) const318 Error Display::getActiveConfig(
319 std::shared_ptr<const Display::Config>* outConfig) const
320 {
321 ALOGV("[%" PRIu64 "] getActiveConfig", mId);
322 hwc2_config_t configId = 0;
323 auto intError = mComposer.getActiveConfig(mId, &configId);
324 auto error = static_cast<Error>(intError);
325
326 if (error != Error::None) {
327 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
328 *outConfig = nullptr;
329 return error;
330 }
331
332 if (mConfigs.count(configId) != 0) {
333 *outConfig = mConfigs.at(configId);
334 } else {
335 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
336 configId);
337 // Return no error, but the caller needs to check for a null pointer to
338 // detect this case
339 *outConfig = nullptr;
340 }
341
342 return Error::None;
343 }
344
getActiveConfigIndex(int * outIndex) const345 Error Display::getActiveConfigIndex(int* outIndex) const {
346 ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId);
347 hwc2_config_t configId = 0;
348 auto intError = mComposer.getActiveConfig(mId, &configId);
349 auto error = static_cast<Error>(intError);
350
351 if (error != Error::None) {
352 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
353 *outIndex = -1;
354 return error;
355 }
356
357 auto pos = mConfigs.find(configId);
358 if (pos != mConfigs.end()) {
359 *outIndex = std::distance(mConfigs.begin(), pos);
360 } else {
361 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId);
362 // Return no error, but the caller needs to check for a negative index
363 // to detect this case
364 *outIndex = -1;
365 }
366
367 return Error::None;
368 }
369
getChangedCompositionTypes(std::unordered_map<HWC2::Layer *,Composition> * outTypes)370 Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
371 std::vector<Hwc2::Layer> layerIds;
372 std::vector<Hwc2::IComposerClient::Composition> types;
373 auto intError = mComposer.getChangedCompositionTypes(
374 mId, &layerIds, &types);
375 uint32_t numElements = layerIds.size();
376 auto error = static_cast<Error>(intError);
377 error = static_cast<Error>(intError);
378 if (error != Error::None) {
379 return error;
380 }
381
382 outTypes->clear();
383 outTypes->reserve(numElements);
384 for (uint32_t element = 0; element < numElements; ++element) {
385 auto layer = getLayerById(layerIds[element]);
386 if (layer) {
387 auto type = static_cast<Composition>(types[element]);
388 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
389 layer->getId(), to_string(type).c_str());
390 outTypes->emplace(layer, type);
391 } else {
392 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
393 " on display %" PRIu64, layerIds[element], mId);
394 }
395 }
396
397 return Error::None;
398 }
399
getColorModes(std::vector<ColorMode> * outModes) const400 Error Display::getColorModes(std::vector<ColorMode>* outModes) const
401 {
402 auto intError = mComposer.getColorModes(mId, outModes);
403 return static_cast<Error>(intError);
404 }
405
getSupportedPerFrameMetadata() const406 int32_t Display::getSupportedPerFrameMetadata() const
407 {
408 int32_t supportedPerFrameMetadata = 0;
409
410 std::vector<Hwc2::PerFrameMetadataKey> tmpKeys = mComposer.getPerFrameMetadataKeys(mId);
411 std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end());
412
413 // Check whether a specific metadata type is supported. A metadata type is considered
414 // supported if and only if all required fields are supported.
415
416 // SMPTE2086
417 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) &&
418 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) &&
419 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) &&
420 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) &&
421 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) &&
422 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) &&
423 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) &&
424 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) &&
425 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) &&
426 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) {
427 supportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086;
428 }
429 // CTA861_3
430 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) &&
431 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) {
432 supportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3;
433 }
434
435 // HDR10PLUS
436 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI)) {
437 supportedPerFrameMetadata |= HdrMetadata::Type::HDR10PLUS;
438 }
439
440 return supportedPerFrameMetadata;
441 }
442
getRenderIntents(ColorMode colorMode,std::vector<RenderIntent> * outRenderIntents) const443 Error Display::getRenderIntents(ColorMode colorMode,
444 std::vector<RenderIntent>* outRenderIntents) const
445 {
446 auto intError = mComposer.getRenderIntents(mId, colorMode, outRenderIntents);
447 return static_cast<Error>(intError);
448 }
449
getDataspaceSaturationMatrix(Dataspace dataspace,android::mat4 * outMatrix)450 Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* outMatrix)
451 {
452 auto intError = mComposer.getDataspaceSaturationMatrix(dataspace, outMatrix);
453 return static_cast<Error>(intError);
454 }
455
getConfigs() const456 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
457 {
458 std::vector<std::shared_ptr<const Config>> configs;
459 for (const auto& element : mConfigs) {
460 configs.emplace_back(element.second);
461 }
462 return configs;
463 }
464
getName(std::string * outName) const465 Error Display::getName(std::string* outName) const
466 {
467 auto intError = mComposer.getDisplayName(mId, outName);
468 return static_cast<Error>(intError);
469 }
470
getRequests(HWC2::DisplayRequest * outDisplayRequests,std::unordered_map<HWC2::Layer *,LayerRequest> * outLayerRequests)471 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
472 std::unordered_map<HWC2::Layer*, LayerRequest>* outLayerRequests) {
473 uint32_t intDisplayRequests = 0;
474 std::vector<Hwc2::Layer> layerIds;
475 std::vector<uint32_t> layerRequests;
476 auto intError = mComposer.getDisplayRequests(
477 mId, &intDisplayRequests, &layerIds, &layerRequests);
478 uint32_t numElements = layerIds.size();
479 auto error = static_cast<Error>(intError);
480 if (error != Error::None) {
481 return error;
482 }
483
484 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
485 outLayerRequests->clear();
486 outLayerRequests->reserve(numElements);
487 for (uint32_t element = 0; element < numElements; ++element) {
488 auto layer = getLayerById(layerIds[element]);
489 if (layer) {
490 auto layerRequest =
491 static_cast<LayerRequest>(layerRequests[element]);
492 outLayerRequests->emplace(layer, layerRequest);
493 } else {
494 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
495 PRIu64, layerIds[element], mId);
496 }
497 }
498
499 return Error::None;
500 }
501
getType(DisplayType * outType) const502 Error Display::getType(DisplayType* outType) const
503 {
504 *outType = mType;
505 return Error::None;
506 }
507
supportsDoze(bool * outSupport) const508 Error Display::supportsDoze(bool* outSupport) const {
509 *outSupport = mDisplayCapabilities.count(DisplayCapability::Doze) > 0;
510 return Error::None;
511 }
512
getHdrCapabilities(HdrCapabilities * outCapabilities) const513 Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const
514 {
515 float maxLuminance = -1.0f;
516 float maxAverageLuminance = -1.0f;
517 float minLuminance = -1.0f;
518 std::vector<Hwc2::Hdr> types;
519 auto intError = mComposer.getHdrCapabilities(mId, &types,
520 &maxLuminance, &maxAverageLuminance, &minLuminance);
521 auto error = static_cast<HWC2::Error>(intError);
522
523 if (error != Error::None) {
524 return error;
525 }
526
527 *outCapabilities = HdrCapabilities(std::move(types),
528 maxLuminance, maxAverageLuminance, minLuminance);
529 return Error::None;
530 }
531
getDisplayedContentSamplingAttributes(PixelFormat * outFormat,Dataspace * outDataspace,uint8_t * outComponentMask) const532 Error Display::getDisplayedContentSamplingAttributes(PixelFormat* outFormat,
533 Dataspace* outDataspace,
534 uint8_t* outComponentMask) const {
535 auto intError = mComposer.getDisplayedContentSamplingAttributes(mId, outFormat, outDataspace,
536 outComponentMask);
537 return static_cast<Error>(intError);
538 }
539
setDisplayContentSamplingEnabled(bool enabled,uint8_t componentMask,uint64_t maxFrames) const540 Error Display::setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask,
541 uint64_t maxFrames) const {
542 auto intError =
543 mComposer.setDisplayContentSamplingEnabled(mId, enabled, componentMask, maxFrames);
544 return static_cast<Error>(intError);
545 }
546
getDisplayedContentSample(uint64_t maxFrames,uint64_t timestamp,android::DisplayedFrameStats * outStats) const547 Error Display::getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
548 android::DisplayedFrameStats* outStats) const {
549 auto intError = mComposer.getDisplayedContentSample(mId, maxFrames, timestamp, outStats);
550 return static_cast<Error>(intError);
551 }
552
getReleaseFences(std::unordered_map<HWC2::Layer *,sp<Fence>> * outFences) const553 Error Display::getReleaseFences(std::unordered_map<HWC2::Layer*, sp<Fence>>* outFences) const {
554 std::vector<Hwc2::Layer> layerIds;
555 std::vector<int> fenceFds;
556 auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
557 auto error = static_cast<Error>(intError);
558 uint32_t numElements = layerIds.size();
559 if (error != Error::None) {
560 return error;
561 }
562
563 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
564 releaseFences.reserve(numElements);
565 for (uint32_t element = 0; element < numElements; ++element) {
566 auto layer = getLayerById(layerIds[element]);
567 if (layer) {
568 sp<Fence> fence(new Fence(fenceFds[element]));
569 releaseFences.emplace(layer, fence);
570 } else {
571 ALOGE("getReleaseFences: invalid layer %" PRIu64
572 " found on display %" PRIu64, layerIds[element], mId);
573 for (; element < numElements; ++element) {
574 close(fenceFds[element]);
575 }
576 return Error::BadLayer;
577 }
578 }
579
580 *outFences = std::move(releaseFences);
581 return Error::None;
582 }
583
present(sp<Fence> * outPresentFence)584 Error Display::present(sp<Fence>* outPresentFence)
585 {
586 int32_t presentFenceFd = -1;
587 auto intError = mComposer.presentDisplay(mId, &presentFenceFd);
588 auto error = static_cast<Error>(intError);
589 if (error != Error::None) {
590 return error;
591 }
592
593 *outPresentFence = new Fence(presentFenceFd);
594 return Error::None;
595 }
596
setActiveConfig(const std::shared_ptr<const Config> & config)597 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
598 {
599 if (config->getDisplayId() != mId) {
600 ALOGE("setActiveConfig received config %u for the wrong display %"
601 PRIu64 " (expected %" PRIu64 ")", config->getId(),
602 config->getDisplayId(), mId);
603 return Error::BadConfig;
604 }
605 auto intError = mComposer.setActiveConfig(mId, config->getId());
606 return static_cast<Error>(intError);
607 }
608
setClientTarget(uint32_t slot,const sp<GraphicBuffer> & target,const sp<Fence> & acquireFence,Dataspace dataspace)609 Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
610 const sp<Fence>& acquireFence, Dataspace dataspace)
611 {
612 // TODO: Properly encode client target surface damage
613 int32_t fenceFd = acquireFence->dup();
614 auto intError = mComposer.setClientTarget(mId, slot, target,
615 fenceFd, dataspace, std::vector<Hwc2::IComposerClient::Rect>());
616 return static_cast<Error>(intError);
617 }
618
setColorMode(ColorMode mode,RenderIntent renderIntent)619 Error Display::setColorMode(ColorMode mode, RenderIntent renderIntent)
620 {
621 auto intError = mComposer.setColorMode(mId, mode, renderIntent);
622 return static_cast<Error>(intError);
623 }
624
setColorTransform(const android::mat4 & matrix,android_color_transform_t hint)625 Error Display::setColorTransform(const android::mat4& matrix,
626 android_color_transform_t hint)
627 {
628 auto intError = mComposer.setColorTransform(mId,
629 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
630 return static_cast<Error>(intError);
631 }
632
setOutputBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)633 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
634 const sp<Fence>& releaseFence)
635 {
636 int32_t fenceFd = releaseFence->dup();
637 auto handle = buffer->getNativeBuffer()->handle;
638 auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd);
639 close(fenceFd);
640 return static_cast<Error>(intError);
641 }
642
setPowerMode(PowerMode mode)643 Error Display::setPowerMode(PowerMode mode)
644 {
645 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
646 auto intError = mComposer.setPowerMode(mId, intMode);
647
648 if (mode == PowerMode::On) {
649 std::call_once(mDisplayCapabilityQueryFlag, [this]() {
650 std::vector<Hwc2::DisplayCapability> tmpCapabilities;
651 auto error =
652 static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
653 if (error == Error::None) {
654 for (auto capability : tmpCapabilities) {
655 mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability));
656 }
657 } else if (error == Error::Unsupported) {
658 if (mCapabilities.count(Capability::SkipClientColorTransform)) {
659 mDisplayCapabilities.emplace(DisplayCapability::SkipClientColorTransform);
660 }
661 bool dozeSupport = false;
662 error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
663 if (error == Error::None && dozeSupport) {
664 mDisplayCapabilities.emplace(DisplayCapability::Doze);
665 }
666 }
667 });
668 }
669
670 return static_cast<Error>(intError);
671 }
672
setVsyncEnabled(Vsync enabled)673 Error Display::setVsyncEnabled(Vsync enabled)
674 {
675 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
676 auto intError = mComposer.setVsyncEnabled(mId, intEnabled);
677 return static_cast<Error>(intError);
678 }
679
validate(uint32_t * outNumTypes,uint32_t * outNumRequests)680 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
681 {
682 uint32_t numTypes = 0;
683 uint32_t numRequests = 0;
684 auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests);
685 auto error = static_cast<Error>(intError);
686 if (error != Error::None && error != Error::HasChanges) {
687 return error;
688 }
689
690 *outNumTypes = numTypes;
691 *outNumRequests = numRequests;
692 return error;
693 }
694
presentOrValidate(uint32_t * outNumTypes,uint32_t * outNumRequests,sp<android::Fence> * outPresentFence,uint32_t * state)695 Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
696 sp<android::Fence>* outPresentFence, uint32_t* state) {
697
698 uint32_t numTypes = 0;
699 uint32_t numRequests = 0;
700 int32_t presentFenceFd = -1;
701 auto intError = mComposer.presentOrValidateDisplay(
702 mId, &numTypes, &numRequests, &presentFenceFd, state);
703 auto error = static_cast<Error>(intError);
704 if (error != Error::None && error != Error::HasChanges) {
705 return error;
706 }
707
708 if (*state == 1) {
709 *outPresentFence = new Fence(presentFenceFd);
710 }
711
712 if (*state == 0) {
713 *outNumTypes = numTypes;
714 *outNumRequests = numRequests;
715 }
716 return error;
717 }
718
setDisplayBrightness(float brightness) const719 Error Display::setDisplayBrightness(float brightness) const {
720 auto intError = mComposer.setDisplayBrightness(mId, brightness);
721 return static_cast<Error>(intError);
722 }
723
724 // For use by Device
725
setConnected(bool connected)726 void Display::setConnected(bool connected) {
727 if (!mIsConnected && connected) {
728 mComposer.setClientTargetSlotCount(mId);
729 if (mType == DisplayType::Physical) {
730 loadConfigs();
731 }
732 }
733 mIsConnected = connected;
734 }
735
getAttribute(hwc2_config_t configId,Attribute attribute)736 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
737 {
738 int32_t value = 0;
739 auto intError = mComposer.getDisplayAttribute(mId, configId,
740 static_cast<Hwc2::IComposerClient::Attribute>(attribute),
741 &value);
742 auto error = static_cast<Error>(intError);
743 if (error != Error::None) {
744 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
745 configId, to_string(attribute).c_str(),
746 to_string(error).c_str(), intError);
747 return -1;
748 }
749 return value;
750 }
751
loadConfig(hwc2_config_t configId)752 void Display::loadConfig(hwc2_config_t configId)
753 {
754 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
755
756 auto config = Config::Builder(*this, configId)
757 .setWidth(getAttribute(configId, Attribute::Width))
758 .setHeight(getAttribute(configId, Attribute::Height))
759 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
760 .setDpiX(getAttribute(configId, Attribute::DpiX))
761 .setDpiY(getAttribute(configId, Attribute::DpiY))
762 .build();
763 mConfigs.emplace(configId, std::move(config));
764 }
765
loadConfigs()766 void Display::loadConfigs()
767 {
768 ALOGV("[%" PRIu64 "] loadConfigs", mId);
769
770 std::vector<Hwc2::Config> configIds;
771 auto intError = mComposer.getDisplayConfigs(mId, &configIds);
772 auto error = static_cast<Error>(intError);
773 if (error != Error::None) {
774 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
775 to_string(error).c_str(), intError);
776 return;
777 }
778
779 for (auto configId : configIds) {
780 loadConfig(configId);
781 }
782 }
783
784 // Other Display methods
785
getLayerById(hwc2_layer_t id) const786 HWC2::Layer* Display::getLayerById(hwc2_layer_t id) const {
787 if (mLayers.count(id) == 0) {
788 return nullptr;
789 }
790
791 return mLayers.at(id).get();
792 }
793 } // namespace impl
794
795 // Layer methods
796
797 Layer::~Layer() = default;
798
799 namespace impl {
800
Layer(android::Hwc2::Composer & composer,const std::unordered_set<Capability> & capabilities,hwc2_display_t displayId,hwc2_layer_t layerId)801 Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
802 hwc2_display_t displayId, hwc2_layer_t layerId)
803 : mComposer(composer),
804 mCapabilities(capabilities),
805 mDisplayId(displayId),
806 mId(layerId),
807 mColorMatrix(android::mat4())
808 {
809 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId);
810 }
811
~Layer()812 Layer::~Layer()
813 {
814 auto intError = mComposer.destroyLayer(mDisplayId, mId);
815 auto error = static_cast<Error>(intError);
816 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
817 " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(),
818 intError);
819 }
820
setCursorPosition(int32_t x,int32_t y)821 Error Layer::setCursorPosition(int32_t x, int32_t y)
822 {
823 auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y);
824 return static_cast<Error>(intError);
825 }
826
setBuffer(uint32_t slot,const sp<GraphicBuffer> & buffer,const sp<Fence> & acquireFence)827 Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
828 const sp<Fence>& acquireFence)
829 {
830 if (buffer == nullptr && mBufferSlot == slot) {
831 return Error::None;
832 }
833 mBufferSlot = slot;
834
835 int32_t fenceFd = acquireFence->dup();
836 auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer,
837 fenceFd);
838 return static_cast<Error>(intError);
839 }
840
setSurfaceDamage(const Region & damage)841 Error Layer::setSurfaceDamage(const Region& damage)
842 {
843 if (damage.isRect() && mDamageRegion.isRect() &&
844 (damage.getBounds() == mDamageRegion.getBounds())) {
845 return Error::None;
846 }
847 mDamageRegion = damage;
848
849 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
850 // rects for HWC
851 Hwc2::Error intError = Hwc2::Error::NONE;
852 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
853 intError = mComposer.setLayerSurfaceDamage(mDisplayId,
854 mId, std::vector<Hwc2::IComposerClient::Rect>());
855 } else {
856 size_t rectCount = 0;
857 auto rectArray = damage.getArray(&rectCount);
858
859 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
860 for (size_t rect = 0; rect < rectCount; ++rect) {
861 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
862 rectArray[rect].right, rectArray[rect].bottom});
863 }
864
865 intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects);
866 }
867
868 return static_cast<Error>(intError);
869 }
870
setBlendMode(BlendMode mode)871 Error Layer::setBlendMode(BlendMode mode)
872 {
873 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
874 auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode);
875 return static_cast<Error>(intError);
876 }
877
setColor(hwc_color_t color)878 Error Layer::setColor(hwc_color_t color)
879 {
880 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
881 auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor);
882 return static_cast<Error>(intError);
883 }
884
setCompositionType(Composition type)885 Error Layer::setCompositionType(Composition type)
886 {
887 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
888 auto intError = mComposer.setLayerCompositionType(
889 mDisplayId, mId, intType);
890 return static_cast<Error>(intError);
891 }
892
setDataspace(Dataspace dataspace)893 Error Layer::setDataspace(Dataspace dataspace)
894 {
895 if (dataspace == mDataSpace) {
896 return Error::None;
897 }
898 mDataSpace = dataspace;
899 auto intError = mComposer.setLayerDataspace(mDisplayId, mId, mDataSpace);
900 return static_cast<Error>(intError);
901 }
902
setPerFrameMetadata(const int32_t supportedPerFrameMetadata,const android::HdrMetadata & metadata)903 Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
904 const android::HdrMetadata& metadata)
905 {
906 if (metadata == mHdrMetadata) {
907 return Error::None;
908 }
909
910 mHdrMetadata = metadata;
911 int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata;
912 std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas;
913 if (validTypes & HdrMetadata::SMPTE2086) {
914 perFrameMetadatas.insert(perFrameMetadatas.end(),
915 {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
916 mHdrMetadata.smpte2086.displayPrimaryRed.x},
917 {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
918 mHdrMetadata.smpte2086.displayPrimaryRed.y},
919 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
920 mHdrMetadata.smpte2086.displayPrimaryGreen.x},
921 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
922 mHdrMetadata.smpte2086.displayPrimaryGreen.y},
923 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
924 mHdrMetadata.smpte2086.displayPrimaryBlue.x},
925 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
926 mHdrMetadata.smpte2086.displayPrimaryBlue.y},
927 {Hwc2::PerFrameMetadataKey::WHITE_POINT_X,
928 mHdrMetadata.smpte2086.whitePoint.x},
929 {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y,
930 mHdrMetadata.smpte2086.whitePoint.y},
931 {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE,
932 mHdrMetadata.smpte2086.maxLuminance},
933 {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE,
934 mHdrMetadata.smpte2086.minLuminance}});
935 }
936
937 if (validTypes & HdrMetadata::CTA861_3) {
938 perFrameMetadatas.insert(perFrameMetadatas.end(),
939 {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
940 mHdrMetadata.cta8613.maxContentLightLevel},
941 {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
942 mHdrMetadata.cta8613.maxFrameAverageLightLevel}});
943 }
944
945 Error error = static_cast<Error>(
946 mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas));
947
948 if (validTypes & HdrMetadata::HDR10PLUS) {
949 std::vector<Hwc2::PerFrameMetadataBlob> perFrameMetadataBlobs;
950 perFrameMetadataBlobs.push_back(
951 {Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI, mHdrMetadata.hdr10plus});
952 Error setMetadataBlobsError = static_cast<Error>(
953 mComposer.setLayerPerFrameMetadataBlobs(mDisplayId, mId, perFrameMetadataBlobs));
954 if (error == Error::None) {
955 return setMetadataBlobsError;
956 }
957 }
958 return error;
959 }
960
setDisplayFrame(const Rect & frame)961 Error Layer::setDisplayFrame(const Rect& frame)
962 {
963 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
964 frame.right, frame.bottom};
965 auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect);
966 return static_cast<Error>(intError);
967 }
968
setPlaneAlpha(float alpha)969 Error Layer::setPlaneAlpha(float alpha)
970 {
971 auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha);
972 return static_cast<Error>(intError);
973 }
974
setSidebandStream(const native_handle_t * stream)975 Error Layer::setSidebandStream(const native_handle_t* stream)
976 {
977 if (mCapabilities.count(Capability::SidebandStream) == 0) {
978 ALOGE("Attempted to call setSidebandStream without checking that the "
979 "device supports sideband streams");
980 return Error::Unsupported;
981 }
982 auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream);
983 return static_cast<Error>(intError);
984 }
985
setSourceCrop(const FloatRect & crop)986 Error Layer::setSourceCrop(const FloatRect& crop)
987 {
988 Hwc2::IComposerClient::FRect hwcRect{
989 crop.left, crop.top, crop.right, crop.bottom};
990 auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect);
991 return static_cast<Error>(intError);
992 }
993
setTransform(Transform transform)994 Error Layer::setTransform(Transform transform)
995 {
996 auto intTransform = static_cast<Hwc2::Transform>(transform);
997 auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform);
998 return static_cast<Error>(intError);
999 }
1000
setVisibleRegion(const Region & region)1001 Error Layer::setVisibleRegion(const Region& region)
1002 {
1003 if (region.isRect() && mVisibleRegion.isRect() &&
1004 (region.getBounds() == mVisibleRegion.getBounds())) {
1005 return Error::None;
1006 }
1007 mVisibleRegion = region;
1008
1009 size_t rectCount = 0;
1010 auto rectArray = region.getArray(&rectCount);
1011
1012 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
1013 for (size_t rect = 0; rect < rectCount; ++rect) {
1014 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1015 rectArray[rect].right, rectArray[rect].bottom});
1016 }
1017
1018 auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects);
1019 return static_cast<Error>(intError);
1020 }
1021
setZOrder(uint32_t z)1022 Error Layer::setZOrder(uint32_t z)
1023 {
1024 auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z);
1025 return static_cast<Error>(intError);
1026 }
1027
setInfo(uint32_t type,uint32_t appId)1028 Error Layer::setInfo(uint32_t type, uint32_t appId)
1029 {
1030 auto intError = mComposer.setLayerInfo(mDisplayId, mId, type, appId);
1031 return static_cast<Error>(intError);
1032 }
1033
1034 // Composer HAL 2.3
setColorTransform(const android::mat4 & matrix)1035 Error Layer::setColorTransform(const android::mat4& matrix) {
1036 if (matrix == mColorMatrix) {
1037 return Error::None;
1038 }
1039 auto intError = mComposer.setLayerColorTransform(mDisplayId, mId, matrix.asArray());
1040 Error error = static_cast<Error>(intError);
1041 if (error != Error::None) {
1042 return error;
1043 }
1044 mColorMatrix = matrix;
1045 return error;
1046 }
1047
1048 } // namespace impl
1049 } // namespace HWC2
1050