1 /*
2 * Copyright 2019 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 #include <android-base/stringprintf.h>
18 #include <common/trace.h>
19 #include <compositionengine/CompositionEngine.h>
20 #include <compositionengine/CompositionRefreshArgs.h>
21 #include <compositionengine/DisplayCreationArgs.h>
22 #include <compositionengine/DisplaySurface.h>
23 #include <compositionengine/LayerFE.h>
24 #include <compositionengine/impl/Display.h>
25 #include <compositionengine/impl/DisplayColorProfile.h>
26 #include <compositionengine/impl/DumpHelpers.h>
27 #include <compositionengine/impl/OutputLayer.h>
28 #include <compositionengine/impl/RenderSurface.h>
29
30 // TODO(b/129481165): remove the #pragma below and fix conversion issues
31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wconversion"
33
34 #include "DisplayHardware/HWComposer.h"
35
36 // TODO(b/129481165): remove the #pragma below and fix conversion issues
37 #pragma clang diagnostic pop // ignored "-Wconversion"
38
39 #include "PowerAdvisor/PowerAdvisor.h"
40
41 using aidl::android::hardware::graphics::composer3::Capability;
42 using aidl::android::hardware::graphics::composer3::DisplayCapability;
43
44 namespace android::compositionengine::impl {
45
createDisplay(const compositionengine::CompositionEngine & compositionEngine,const compositionengine::DisplayCreationArgs & args)46 std::shared_ptr<Display> createDisplay(
47 const compositionengine::CompositionEngine& compositionEngine,
48 const compositionengine::DisplayCreationArgs& args) {
49 return createDisplayTemplated<Display>(compositionEngine, args);
50 }
51
52 Display::~Display() = default;
53
setConfiguration(const compositionengine::DisplayCreationArgs & args)54 void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
55 mIdVariant = args.idVariant;
56 mPowerAdvisor = args.powerAdvisor;
57 mHasPictureProcessing = args.hasPictureProcessing;
58 mMaxLayerPictureProfiles = args.maxLayerPictureProfiles;
59 editState().isSecure = args.isSecure;
60 editState().isProtected = args.isProtected;
61 editState().displaySpace.setBounds(args.pixels);
62 setName(args.name);
63 }
64
isValid() const65 bool Display::isValid() const {
66 return Output::isValid() && mPowerAdvisor;
67 }
68
getId() const69 DisplayId Display::getId() const {
70 return asDisplayId(mIdVariant);
71 }
72
hasSecureLayers() const73 bool Display::hasSecureLayers() const {
74 const auto layers = getOutputLayersOrderedByZ();
75 return std::any_of(layers.begin(), layers.end(), [](const auto& layer) {
76 const auto* state = layer->getLayerFE().getCompositionState();
77 return state && state->isSecure;
78 });
79 }
80
isSecure() const81 bool Display::isSecure() const {
82 return getState().isSecure;
83 }
84
setSecure(bool secure)85 void Display::setSecure(bool secure) {
86 editState().isSecure = secure;
87 }
88
isVirtual() const89 bool Display::isVirtual() const {
90 return !std::holds_alternative<PhysicalDisplayId>(mIdVariant);
91 }
92
getDisplayId() const93 ftl::Optional<DisplayId> Display::getDisplayId() const {
94 return getId();
95 }
96
getDisplayIdVariant() const97 ftl::Optional<DisplayIdVariant> Display::getDisplayIdVariant() const {
98 return mIdVariant;
99 }
100
disconnect()101 void Display::disconnect() {
102 if (mIsDisconnected) {
103 return;
104 }
105
106 mIsDisconnected = true;
107
108 if (const auto id = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
109 getCompositionEngine().getHwComposer().disconnectDisplay(*id);
110 }
111 }
112
setColorTransform(const compositionengine::CompositionRefreshArgs & args)113 void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
114 Output::setColorTransform(args);
115 const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
116 if (mIsDisconnected || !halDisplayId || CC_LIKELY(!args.colorTransformMatrix)) {
117 return;
118 }
119
120 auto& hwc = getCompositionEngine().getHwComposer();
121 status_t result = hwc.setColorTransform(*halDisplayId, *args.colorTransformMatrix);
122 ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d",
123 to_string(*halDisplayId).c_str(), result);
124 }
125
setColorProfile(const ColorProfile & colorProfile)126 void Display::setColorProfile(const ColorProfile& colorProfile) {
127 if (colorProfile.mode == getState().colorMode &&
128 colorProfile.dataspace == getState().dataspace &&
129 colorProfile.renderIntent == getState().renderIntent) {
130 return;
131 }
132
133 if (isVirtual()) {
134 ALOGW("%s: Invalid operation on virtual display", __func__);
135 return;
136 }
137
138 Output::setColorProfile(colorProfile);
139
140 const auto physicalId = getDisplayIdVariant().and_then(asPhysicalDisplayId);
141 LOG_FATAL_IF(!physicalId);
142 getCompositionEngine().getHwComposer().setActiveColorMode(*physicalId, colorProfile.mode,
143 colorProfile.renderIntent);
144 }
145
dump(std::string & out) const146 void Display::dump(std::string& out) const {
147 const char* const type = isVirtual() ? "virtual" : "physical";
148 base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(getId()).c_str(), type,
149 getName().c_str());
150
151 out.append("\n Composition Display State:\n");
152 Output::dumpBase(out);
153 }
154
createDisplayColorProfile(const DisplayColorProfileCreationArgs & args)155 void Display::createDisplayColorProfile(const DisplayColorProfileCreationArgs& args) {
156 setDisplayColorProfile(compositionengine::impl::createDisplayColorProfile(args));
157 }
158
createRenderSurface(const RenderSurfaceCreationArgs & args)159 void Display::createRenderSurface(const RenderSurfaceCreationArgs& args) {
160 setRenderSurface(
161 compositionengine::impl::createRenderSurface(getCompositionEngine(), *this, args));
162 }
163
createClientCompositionCache(uint32_t cacheSize)164 void Display::createClientCompositionCache(uint32_t cacheSize) {
165 cacheClientCompositionRequests(cacheSize);
166 }
167
createOutputLayer(const sp<compositionengine::LayerFE> & layerFE) const168 std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
169 const sp<compositionengine::LayerFE>& layerFE) const {
170 auto outputLayer = impl::createOutputLayer(*this, layerFE);
171
172 if (const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
173 outputLayer && !mIsDisconnected && halDisplayId) {
174 auto& hwc = getCompositionEngine().getHwComposer();
175 auto hwcLayer = hwc.createLayer(*halDisplayId);
176 ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
177 getName().c_str());
178 outputLayer->setHwcLayer(std::move(hwcLayer));
179 }
180 return outputLayer;
181 }
182
setReleasedLayers(const compositionengine::CompositionRefreshArgs & refreshArgs)183 void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) {
184 Output::setReleasedLayers(refreshArgs);
185
186 if (mIsDisconnected || isGpuVirtualDisplay() || refreshArgs.layersWithQueuedFrames.empty()) {
187 return;
188 }
189
190 // For layers that are being removed from a HWC display, and that have
191 // queued frames, add them to a a list of released layers so we can properly
192 // set a fence.
193 compositionengine::Output::ReleasedLayers releasedLayers;
194
195 // Any non-null entries in the current list of layers are layers that are no
196 // longer going to be visible
197 for (auto* outputLayer : getOutputLayersOrderedByZ()) {
198 if (!outputLayer) {
199 continue;
200 }
201
202 compositionengine::LayerFE* layerFE = &outputLayer->getLayerFE();
203 const bool hasQueuedFrames =
204 std::any_of(refreshArgs.layersWithQueuedFrames.cbegin(),
205 refreshArgs.layersWithQueuedFrames.cend(),
206 [layerFE](sp<compositionengine::LayerFE> layerWithQueuedFrames) {
207 return layerFE == layerWithQueuedFrames.get();
208 });
209
210 if (hasQueuedFrames) {
211 releasedLayers.emplace_back(wp<LayerFE>::fromExisting(layerFE));
212 }
213 }
214
215 setReleasedLayers(std::move(releasedLayers));
216 }
217
applyDisplayBrightness(bool applyImmediately)218 void Display::applyDisplayBrightness(bool applyImmediately) {
219 if (!getState().displayBrightness) {
220 return;
221 }
222 if (auto displayId = getDisplayIdVariant().and_then(asPhysicalDisplayId)) {
223 auto& hwc = getCompositionEngine().getHwComposer();
224 status_t result = hwc.setDisplayBrightness(*displayId, *getState().displayBrightness,
225 getState().displayBrightnessNits,
226 Hwc2::Composer::DisplayBrightnessOptions{
227 .applyImmediately = applyImmediately})
228 .get();
229 ALOGE_IF(result != NO_ERROR, "setDisplayBrightness failed for %s: %d, (%s)",
230 getName().c_str(), result, strerror(-result));
231 }
232 // Clear out the display brightness now that it's been communicated to composer.
233 editState().displayBrightness.reset();
234 }
235
beginFrame()236 void Display::beginFrame() {
237 Output::beginFrame();
238
239 // If we don't have a HWC display, then we are done.
240 const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
241 if (!halDisplayId) {
242 return;
243 }
244
245 applyDisplayBrightness(false);
246 }
247
chooseCompositionStrategy(std::optional<android::HWComposer::DeviceRequestedChanges> * outChanges)248 bool Display::chooseCompositionStrategy(
249 std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
250 SFTRACE_FORMAT("%s for %s", __func__, getNamePlusId().c_str());
251 ALOGV(__FUNCTION__);
252
253 if (mIsDisconnected) {
254 return false;
255 }
256
257 // If we don't have a HWC display, then we are done.
258 const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
259 if (!halDisplayId) {
260 return false;
261 }
262
263 // Get any composition changes requested by the HWC device, and apply them.
264 auto& hwc = getCompositionEngine().getHwComposer();
265 const bool requiresClientComposition = anyLayersRequireClientComposition();
266
267 const TimePoint hwcValidateStartTime = TimePoint::now();
268
269 if (status_t result = hwc.getDeviceCompositionChanges(*halDisplayId, requiresClientComposition,
270 getState().earliestPresentTime,
271 getState().expectedPresentTime,
272 getState().frameInterval, outChanges);
273 result != NO_ERROR) {
274 ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
275 strerror(-result));
276 return false;
277 }
278
279 if (isPowerHintSessionEnabled()) {
280 mPowerAdvisor->setHwcValidateTiming(getId(), hwcValidateStartTime, TimePoint::now());
281 if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
282 mPowerAdvisor->setSkippedValidate(*halDisplayId, hwc.getValidateSkipped(*halDisplayId));
283 }
284 }
285
286 return true;
287 }
288
applyCompositionStrategy(const std::optional<DeviceRequestedChanges> & changes)289 void Display::applyCompositionStrategy(const std::optional<DeviceRequestedChanges>& changes) {
290 if (changes) {
291 applyChangedTypesToLayers(changes->changedTypes);
292 applyDisplayRequests(changes->displayRequests);
293 applyLayerRequestsToLayers(changes->layerRequests);
294 applyClientTargetRequests(changes->clientTargetProperty);
295 applyLayerLutsToLayers(changes->layerLuts);
296 }
297
298 // Determine what type of composition we are doing from the final state
299 auto& state = editState();
300 state.usesClientComposition = anyLayersRequireClientComposition();
301 state.usesDeviceComposition = !allLayersRequireClientComposition();
302 }
303
getSkipColorTransform() const304 bool Display::getSkipColorTransform() const {
305 auto& hwc = getCompositionEngine().getHwComposer();
306 if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
307 return hwc.hasDisplayCapability(*halDisplayId,
308 DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
309 }
310
311 return hwc.hasCapability(Capability::SKIP_CLIENT_COLOR_TRANSFORM);
312 }
313
allLayersRequireClientComposition() const314 bool Display::allLayersRequireClientComposition() const {
315 const auto layers = getOutputLayersOrderedByZ();
316 return std::all_of(layers.begin(), layers.end(),
317 [](const auto& layer) { return layer->requiresClientComposition(); });
318 }
319
applyChangedTypesToLayers(const ChangedTypes & changedTypes)320 void Display::applyChangedTypesToLayers(const ChangedTypes& changedTypes) {
321 if (changedTypes.empty()) {
322 return;
323 }
324
325 for (auto* layer : getOutputLayersOrderedByZ()) {
326 auto hwcLayer = layer->getHwcLayer();
327 if (!hwcLayer) {
328 continue;
329 }
330
331 if (auto it = changedTypes.find(hwcLayer); it != changedTypes.end()) {
332 layer->applyDeviceCompositionTypeChange(
333 static_cast<aidl::android::hardware::graphics::composer3::Composition>(
334 it->second));
335 }
336 }
337 }
338
applyDisplayRequests(const DisplayRequests & displayRequests)339 void Display::applyDisplayRequests(const DisplayRequests& displayRequests) {
340 auto& state = editState();
341 state.flipClientTarget = (static_cast<uint32_t>(displayRequests) &
342 static_cast<uint32_t>(hal::DisplayRequest::FLIP_CLIENT_TARGET)) != 0;
343 // Note: HWC2::DisplayRequest::WriteClientTargetToOutput is currently ignored.
344 }
345
applyLayerRequestsToLayers(const LayerRequests & layerRequests)346 void Display::applyLayerRequestsToLayers(const LayerRequests& layerRequests) {
347 for (auto* layer : getOutputLayersOrderedByZ()) {
348 layer->prepareForDeviceLayerRequests();
349
350 auto hwcLayer = layer->getHwcLayer();
351 if (!hwcLayer) {
352 continue;
353 }
354
355 if (auto it = layerRequests.find(hwcLayer); it != layerRequests.end()) {
356 layer->applyDeviceLayerRequest(
357 static_cast<Hwc2::IComposerClient::LayerRequest>(it->second));
358 }
359 }
360 }
361
applyClientTargetRequests(const ClientTargetProperty & clientTargetProperty)362 void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty) {
363 if (static_cast<ui::Dataspace>(clientTargetProperty.clientTargetProperty.dataspace) ==
364 ui::Dataspace::UNKNOWN) {
365 return;
366 }
367
368 editState().dataspace =
369 static_cast<ui::Dataspace>(clientTargetProperty.clientTargetProperty.dataspace);
370 editState().clientTargetBrightness = clientTargetProperty.brightness;
371 editState().clientTargetDimmingStage = clientTargetProperty.dimmingStage;
372 getRenderSurface()->setBufferDataspace(editState().dataspace);
373 getRenderSurface()->setBufferPixelFormat(
374 static_cast<ui::PixelFormat>(clientTargetProperty.clientTargetProperty.pixelFormat));
375 }
376
applyLayerLutsToLayers(const LayerLuts & layerLuts)377 void Display::applyLayerLutsToLayers(const LayerLuts& layerLuts) {
378 auto& mapper = getCompositionEngine().getHwComposer().getLutFileDescriptorMapper();
379 for (auto* layer : getOutputLayersOrderedByZ()) {
380 auto hwcLayer = layer->getHwcLayer();
381 if (!hwcLayer) {
382 continue;
383 }
384
385 if (auto lutsIt = layerLuts.find(hwcLayer); lutsIt != layerLuts.end()) {
386 if (auto mapperIt = mapper.find(hwcLayer); mapperIt != mapper.end()) {
387 layer->applyDeviceLayerLut(::android::base::unique_fd(mapperIt->second.release()),
388 lutsIt->second);
389 }
390 }
391 }
392
393 mapper.clear();
394 }
395
executeCommands()396 void Display::executeCommands() {
397 const auto halDisplayIdOpt = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
398 if (mIsDisconnected || !halDisplayIdOpt) {
399 return;
400 }
401
402 getCompositionEngine().getHwComposer().executeCommands(*halDisplayIdOpt);
403 }
404
presentFrame()405 compositionengine::Output::FrameFences Display::presentFrame() {
406 auto fences = impl::Output::presentFrame();
407
408 const auto halDisplayIdOpt = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
409 if (mIsDisconnected || !halDisplayIdOpt) {
410 return fences;
411 }
412
413 auto& hwc = getCompositionEngine().getHwComposer();
414
415 const TimePoint startTime = TimePoint::now();
416
417 if (isPowerHintSessionEnabled() && getState().earliestPresentTime) {
418 mPowerAdvisor->setHwcPresentDelayedTime(*halDisplayIdOpt, *getState().earliestPresentTime);
419 }
420
421 hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime);
422
423 if (isPowerHintSessionEnabled()) {
424 mPowerAdvisor->setHwcPresentTiming(*halDisplayIdOpt, startTime, TimePoint::now());
425 }
426
427 fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
428
429 // TODO(b/121291683): Change HWComposer call to return entire map
430 for (const auto* layer : getOutputLayersOrderedByZ()) {
431 auto hwcLayer = layer->getHwcLayer();
432 if (!hwcLayer) {
433 continue;
434 }
435
436 fences.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*halDisplayIdOpt, hwcLayer));
437 }
438
439 hwc.clearReleaseFences(*halDisplayIdOpt);
440
441 return fences;
442 }
443
setExpensiveRenderingExpected(bool enabled)444 void Display::setExpensiveRenderingExpected(bool enabled) {
445 Output::setExpensiveRenderingExpected(enabled);
446
447 if (mPowerAdvisor && !isGpuVirtualDisplay()) {
448 mPowerAdvisor->setExpensiveRenderingExpected(getId(), enabled);
449 }
450 }
451
isPowerHintSessionEnabled()452 bool Display::isPowerHintSessionEnabled() {
453 return mPowerAdvisor != nullptr && mPowerAdvisor->usePowerHintSession();
454 }
455
isPowerHintSessionGpuReportingEnabled()456 bool Display::isPowerHintSessionGpuReportingEnabled() {
457 return mPowerAdvisor != nullptr && mPowerAdvisor->supportsGpuReporting();
458 }
459
460 // For ADPF GPU v0 this is expected to set start time to when the GPU commands are submitted with
461 // fence returned, i.e. when RenderEngine flushes the commands and returns the draw fence.
setHintSessionGpuStart(TimePoint startTime)462 void Display::setHintSessionGpuStart(TimePoint startTime) {
463 mPowerAdvisor->setGpuStartTime(getId(), startTime);
464 }
465
setHintSessionGpuFence(std::unique_ptr<FenceTime> && gpuFence)466 void Display::setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) {
467 mPowerAdvisor->setGpuFenceTime(getId(), std::move(gpuFence));
468 }
469
setHintSessionRequiresRenderEngine(bool requiresRenderEngine)470 void Display::setHintSessionRequiresRenderEngine(bool requiresRenderEngine) {
471 mPowerAdvisor->setRequiresRenderEngine(getId(), requiresRenderEngine);
472 }
473
474 const aidl::android::hardware::graphics::composer3::OverlayProperties*
getOverlaySupport()475 Display::getOverlaySupport() {
476 return &getCompositionEngine().getHwComposer().getOverlaySupport();
477 }
478
hasPictureProcessing() const479 bool Display::hasPictureProcessing() const {
480 return mHasPictureProcessing;
481 }
482
getMaxLayerPictureProfiles() const483 int32_t Display::getMaxLayerPictureProfiles() const {
484 return mMaxLayerPictureProfiles;
485 }
486
finishFrame(GpuCompositionResult && result)487 void Display::finishFrame(GpuCompositionResult&& result) {
488 // We only need to actually compose the display if:
489 // 1) It is being handled by hardware composer, which may need this to
490 // keep its virtual display state machine in sync, or
491 // 2) There is work to be done (the dirty region isn't empty)
492 if (isGpuVirtualDisplay() && !mustRecompose()) {
493 ALOGV("Skipping display composition");
494 return;
495 }
496
497 impl::Output::finishFrame(std::move(result));
498 }
499
supportsOffloadPresent() const500 bool Display::supportsOffloadPresent() const {
501 if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
502 auto& hwc = getCompositionEngine().getHwComposer();
503 return hwc.hasDisplayCapability(*halDisplayId, DisplayCapability::MULTI_THREADED_PRESENT);
504 }
505
506 return false;
507 }
508
509 } // namespace android::compositionengine::impl
510