1 /*
2 * Copyright (C) 2021 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 ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18
19 #include "ComposerClient.h"
20
21 #include <android-base/logging.h>
22 #include <android/binder_ibinder_platform.h>
23
24 #include "Util.h"
25
26 namespace aidl::android::hardware::graphics::composer3::impl {
27
init()28 bool ComposerClient::init() {
29 DEBUG_FUNC();
30 mResources = IResourceManager::create();
31 if (!mResources) {
32 LOG(ERROR) << "failed to create composer resources";
33 return false;
34 }
35
36 mCommandEngine = std::make_unique<ComposerCommandEngine>(mHal, mResources.get());
37 if (mCommandEngine == nullptr) {
38 return false;
39 }
40 if (!mCommandEngine->init()) {
41 mCommandEngine = nullptr;
42 return false;
43 }
44
45 return true;
46 }
47
~ComposerClient()48 ComposerClient::~ComposerClient() {
49 DEBUG_FUNC();
50 // not initialized
51 if (!mCommandEngine) {
52 return;
53 }
54
55 LOG(DEBUG) << "destroying composer client";
56
57 mHal->unregisterEventCallback();
58 destroyResources();
59
60 if (mOnClientDestroyed) {
61 mOnClientDestroyed();
62 }
63
64 LOG(DEBUG) << "removed composer client";
65 }
66
67 // no need to check nullptr for output parameter, the aidl stub code won't pass nullptr
createLayer(int64_t display,int32_t bufferSlotCount,int64_t * layer)68 ndk::ScopedAStatus ComposerClient::createLayer(int64_t display, int32_t bufferSlotCount,
69 int64_t* layer) {
70 DEBUG_FUNC();
71 auto err = mHal->createLayer(display, layer);
72 if (!err) {
73 err = mResources->addLayer(display, *layer, bufferSlotCount);
74 if (err) {
75 layer = 0;
76 }
77 }
78 return TO_BINDER_STATUS(err);
79 }
80
createVirtualDisplay(int32_t width,int32_t height,AidlPixelFormat formatHint,int32_t outputBufferSlotCount,VirtualDisplay * display)81 ndk::ScopedAStatus ComposerClient::createVirtualDisplay(int32_t width, int32_t height,
82 AidlPixelFormat formatHint,
83 int32_t outputBufferSlotCount,
84 VirtualDisplay* display) {
85 DEBUG_FUNC();
86 auto err = mHal->createVirtualDisplay(width, height, formatHint, display);
87 if (!err) {
88 err = mResources->addVirtualDisplay(display->display, outputBufferSlotCount);
89 }
90 return TO_BINDER_STATUS(err);
91 }
92
destroyLayer(int64_t display,int64_t layer)93 ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display, int64_t layer) {
94 DEBUG_FUNC();
95 auto err = mHal->destroyLayer(display, layer);
96 if (!err) {
97 err = mResources->removeLayer(display, layer);
98 }
99 return TO_BINDER_STATUS(err);
100 }
101
destroyVirtualDisplay(int64_t display)102 ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display) {
103 DEBUG_FUNC();
104 auto err = mHal->destroyVirtualDisplay(display);
105 if (!err) {
106 err = mResources->removeDisplay(display);
107 }
108 return TO_BINDER_STATUS(err);
109 }
110
executeCommands(const std::vector<DisplayCommand> & commands,std::vector<CommandResultPayload> * results)111 ndk::ScopedAStatus ComposerClient::executeCommands(const std::vector<DisplayCommand>& commands,
112 std::vector<CommandResultPayload>* results) {
113 DEBUG_FUNC();
114 auto err = mCommandEngine->execute(commands, results);
115 return TO_BINDER_STATUS(err);
116 }
117
getActiveConfig(int64_t display,int32_t * config)118 ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display, int32_t* config) {
119 DEBUG_FUNC();
120 auto err = mHal->getActiveConfig(display, config);
121 return TO_BINDER_STATUS(err);
122 }
123
getColorModes(int64_t display,std::vector<ColorMode> * colorModes)124 ndk::ScopedAStatus ComposerClient::getColorModes(int64_t display,
125 std::vector<ColorMode>* colorModes) {
126 DEBUG_FUNC();
127 auto err = mHal->getColorModes(display, colorModes);
128 return TO_BINDER_STATUS(err);
129 }
130
getDataspaceSaturationMatrix(common::Dataspace dataspace,std::vector<float> * matrix)131 ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(common::Dataspace dataspace,
132 std::vector<float>* matrix) {
133 DEBUG_FUNC();
134 if (dataspace != common::Dataspace::SRGB_LINEAR) {
135 return TO_BINDER_STATUS(EX_BAD_PARAMETER);
136 }
137
138 auto err = mHal->getDataspaceSaturationMatrix(dataspace, matrix);
139 if (err) {
140 constexpr std::array<float, 16> unit {
141 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
142 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
143 };
144 matrix->clear();
145 matrix->insert(matrix->begin(), unit.begin(), unit.end());
146 }
147 return TO_BINDER_STATUS(err);
148 }
149
getDisplayAttribute(int64_t display,int32_t config,DisplayAttribute attribute,int32_t * value)150 ndk::ScopedAStatus ComposerClient::getDisplayAttribute(int64_t display, int32_t config,
151 DisplayAttribute attribute, int32_t* value) {
152 DEBUG_FUNC();
153 auto err = mHal->getDisplayAttribute(display, config, attribute, value);
154 return TO_BINDER_STATUS(err);
155 }
156
getDisplayCapabilities(int64_t display,std::vector<DisplayCapability> * caps)157 ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(int64_t display,
158 std::vector<DisplayCapability>* caps) {
159 DEBUG_FUNC();
160 auto err = mHal->getDisplayCapabilities(display, caps);
161 if (err) {
162 return TO_BINDER_STATUS(err);
163 }
164
165 bool support = false;
166 err = mHal->getDisplayIdleTimerSupport(display, support);
167 if (err != ::android::OK) {
168 LOG(ERROR) << "failed to getDisplayIdleTimerSupport: " << err;
169 }
170
171 if (support) {
172 caps->push_back(DisplayCapability::DISPLAY_IDLE_TIMER);
173 }
174
175 return TO_BINDER_STATUS(err);
176 }
177
getDisplayConfigs(int64_t display,std::vector<int32_t> * configs)178 ndk::ScopedAStatus ComposerClient::getDisplayConfigs(int64_t display,
179 std::vector<int32_t>* configs) {
180 DEBUG_FUNC();
181 auto err = mHal->getDisplayConfigs(display, configs);
182 return TO_BINDER_STATUS(err);
183 }
184
getDisplayConnectionType(int64_t display,DisplayConnectionType * type)185 ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(int64_t display,
186 DisplayConnectionType* type) {
187 DEBUG_FUNC();
188 auto err = mHal->getDisplayConnectionType(display, type);
189 return TO_BINDER_STATUS(err);
190 }
191
getDisplayIdentificationData(int64_t display,DisplayIdentification * id)192 ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(int64_t display,
193 DisplayIdentification* id) {
194 DEBUG_FUNC();
195 auto err = mHal->getDisplayIdentificationData(display, id);
196 return TO_BINDER_STATUS(err);
197 }
198
getDisplayName(int64_t display,std::string * name)199 ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display, std::string* name) {
200 DEBUG_FUNC();
201 auto err = mHal->getDisplayName(display, name);
202 return TO_BINDER_STATUS(err);
203 }
204
getDisplayVsyncPeriod(int64_t display,int32_t * vsyncPeriod)205 ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(int64_t display, int32_t* vsyncPeriod) {
206 DEBUG_FUNC();
207 auto err = mHal->getDisplayVsyncPeriod(display, vsyncPeriod);
208 return TO_BINDER_STATUS(err);
209 }
210
getDisplayedContentSample(int64_t display,int64_t maxFrames,int64_t timestamp,DisplayContentSample * samples)211 ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(int64_t display, int64_t maxFrames,
212 int64_t timestamp,
213 DisplayContentSample* samples) {
214 DEBUG_FUNC();
215 auto err = mHal->getDisplayedContentSample(display, maxFrames, timestamp, samples);
216 return TO_BINDER_STATUS(err);
217 }
218
getDisplayedContentSamplingAttributes(int64_t display,DisplayContentSamplingAttributes * attrs)219 ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
220 int64_t display, DisplayContentSamplingAttributes* attrs) {
221 DEBUG_FUNC();
222 auto err = mHal->getDisplayedContentSamplingAttributes(display, attrs);
223 return TO_BINDER_STATUS(err);
224 }
225
getDisplayPhysicalOrientation(int64_t display,common::Transform * orientation)226 ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(int64_t display,
227 common::Transform* orientation) {
228 DEBUG_FUNC();
229 auto err = mHal->getDisplayPhysicalOrientation(display, orientation);
230 return TO_BINDER_STATUS(err);
231 }
232
getHdrCapabilities(int64_t display,HdrCapabilities * caps)233 ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display, HdrCapabilities* caps) {
234 DEBUG_FUNC();
235 auto err = mHal->getHdrCapabilities(display, caps);
236 return TO_BINDER_STATUS(err);
237 }
238
getMaxVirtualDisplayCount(int32_t * count)239 ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
240 DEBUG_FUNC();
241 auto err = mHal->getMaxVirtualDisplayCount(count);
242 return TO_BINDER_STATUS(err);
243 }
244
getPerFrameMetadataKeys(int64_t display,std::vector<PerFrameMetadataKey> * keys)245 ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(int64_t display,
246 std::vector<PerFrameMetadataKey>* keys) {
247 DEBUG_FUNC();
248 auto err = mHal->getPerFrameMetadataKeys(display, keys);
249 return TO_BINDER_STATUS(err);
250 }
251
getReadbackBufferAttributes(int64_t display,ReadbackBufferAttributes * attrs)252 ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(int64_t display,
253 ReadbackBufferAttributes* attrs) {
254 DEBUG_FUNC();
255 auto err = mHal->getReadbackBufferAttributes(display, attrs);
256 return TO_BINDER_STATUS(err);
257 }
258
getReadbackBufferFence(int64_t display,ndk::ScopedFileDescriptor * acquireFence)259 ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(int64_t display,
260 ndk::ScopedFileDescriptor* acquireFence) {
261 DEBUG_FUNC();
262 auto err = mHal->getReadbackBufferFence(display, acquireFence);
263 return TO_BINDER_STATUS(err);
264 }
265
getRenderIntents(int64_t display,ColorMode mode,std::vector<RenderIntent> * intents)266 ndk::ScopedAStatus ComposerClient::getRenderIntents(int64_t display, ColorMode mode,
267 std::vector<RenderIntent>* intents) {
268 DEBUG_FUNC();
269 auto err = mHal->getRenderIntents(display, mode, intents);
270 return TO_BINDER_STATUS(err);
271 }
272
getSupportedContentTypes(int64_t display,std::vector<ContentType> * types)273 ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(int64_t display,
274 std::vector<ContentType>* types) {
275 DEBUG_FUNC();
276 auto err = mHal->getSupportedContentTypes(display, types);
277 return TO_BINDER_STATUS(err);
278 }
279
getDisplayDecorationSupport(int64_t display,std::optional<common::DisplayDecorationSupport> * supportStruct)280 ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
281 int64_t display, std::optional<common::DisplayDecorationSupport>* supportStruct) {
282 DEBUG_FUNC();
283 bool support = false;
284 auto err = mHal->getRCDLayerSupport(display, support);
285 if (err != ::android::OK) {
286 LOG(ERROR) << "failed to getRCDLayerSupport: " << err;
287 }
288 if (support) {
289 // TODO (b/218499393): determine from mHal instead of hard coding.
290 auto& s = supportStruct->emplace();
291 s.format = common::PixelFormat::R_8;
292 s.alphaInterpretation = common::AlphaInterpretation::COVERAGE;
293 } else {
294 supportStruct->reset();
295 }
296 return TO_BINDER_STATUS(err);
297 }
298
registerCallback(const std::shared_ptr<IComposerCallback> & callback)299 ndk::ScopedAStatus ComposerClient::registerCallback(
300 const std::shared_ptr<IComposerCallback>& callback) {
301 DEBUG_FUNC();
302 // no locking as we require this function to be called only once
303 mHalEventCallback = std::make_unique<HalEventCallback>(mHal, mResources.get(), callback);
304 mHal->registerEventCallback(mHalEventCallback.get());
305 return ndk::ScopedAStatus::ok();
306 }
307
setActiveConfig(int64_t display,int32_t config)308 ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display, int32_t config) {
309 DEBUG_FUNC();
310 auto err = mHal->setActiveConfig(display, config);
311 return TO_BINDER_STATUS(err);
312 }
313
setActiveConfigWithConstraints(int64_t display,int32_t config,const VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * timeline)314 ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
315 int64_t display, int32_t config, const VsyncPeriodChangeConstraints& constraints,
316 VsyncPeriodChangeTimeline* timeline) {
317 DEBUG_FUNC();
318 auto err = mHal->setActiveConfigWithConstraints(display, config, constraints, timeline);
319 return TO_BINDER_STATUS(err);
320 }
321
setBootDisplayConfig(int64_t display,int32_t config)322 ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
323 DEBUG_FUNC();
324 auto err = mHal->setBootDisplayConfig(display, config);
325 return TO_BINDER_STATUS(err);
326 }
327
clearBootDisplayConfig(int64_t display)328 ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t display) {
329 DEBUG_FUNC();
330 auto err = mHal->clearBootDisplayConfig(display);
331 return TO_BINDER_STATUS(err);
332 }
333
getPreferredBootDisplayConfig(int64_t display,int32_t * config)334 ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(int64_t display, int32_t* config) {
335 DEBUG_FUNC();
336 auto err = mHal->getPreferredBootDisplayConfig(display, config);
337 return TO_BINDER_STATUS(err);
338 }
339
setAutoLowLatencyMode(int64_t display,bool on)340 ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display, bool on) {
341 DEBUG_FUNC();
342 auto err = mHal->setAutoLowLatencyMode(display, on);
343 return TO_BINDER_STATUS(err);
344 }
345
setClientTargetSlotCount(int64_t display,int32_t count)346 ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display, int32_t count) {
347 DEBUG_FUNC();
348 auto err = mResources->setDisplayClientTargetCacheSize(display, count);
349 return TO_BINDER_STATUS(err);
350 }
351
setColorMode(int64_t display,ColorMode mode,RenderIntent intent)352 ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display, ColorMode mode,
353 RenderIntent intent) {
354 DEBUG_FUNC();
355 auto err = mHal->setColorMode(display, mode, intent);
356 return TO_BINDER_STATUS(err);
357 }
358
setContentType(int64_t display,ContentType type)359 ndk::ScopedAStatus ComposerClient::setContentType(int64_t display, ContentType type) {
360 DEBUG_FUNC();
361 auto err = mHal->setContentType(display, type);
362 return TO_BINDER_STATUS(err);
363 }
364
setDisplayedContentSamplingEnabled(int64_t display,bool enable,FormatColorComponent componentMask,int64_t maxFrames)365 ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
366 int64_t display, bool enable, FormatColorComponent componentMask, int64_t maxFrames) {
367 DEBUG_FUNC();
368 auto err = mHal->setDisplayedContentSamplingEnabled(display, enable, componentMask, maxFrames);
369 return TO_BINDER_STATUS(err);
370 }
371
setPowerMode(int64_t display,PowerMode mode)372 ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display, PowerMode mode) {
373 DEBUG_FUNC();
374 auto err = mHal->setPowerMode(display, mode);
375 return TO_BINDER_STATUS(err);
376 }
377
setReadbackBuffer(int64_t display,const AidlNativeHandle & aidlBuffer,const ndk::ScopedFileDescriptor & releaseFence)378 ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
379 int64_t display, const AidlNativeHandle& aidlBuffer,
380 const ndk::ScopedFileDescriptor& releaseFence) {
381 DEBUG_FUNC();
382 buffer_handle_t readbackBuffer;
383 // Note ownership of the buffer is not passed to resource manager.
384 buffer_handle_t buffer = ::android::makeFromAidl(aidlBuffer);
385 auto bufReleaser = mResources->createReleaser(true /* isBuffer */);
386 auto err = mResources->getDisplayReadbackBuffer(display, buffer,
387 readbackBuffer, bufReleaser.get());
388 if (!err) {
389 err = mHal->setReadbackBuffer(display, readbackBuffer, releaseFence);
390 }
391 return TO_BINDER_STATUS(err);
392 }
393
setVsyncEnabled(int64_t display,bool enabled)394 ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display, bool enabled) {
395 DEBUG_FUNC();
396 auto err = mHal->setVsyncEnabled(display, enabled);
397 return TO_BINDER_STATUS(err);
398 }
399
setIdleTimerEnabled(int64_t display,int32_t timeout)400 ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeout) {
401 DEBUG_FUNC();
402 auto err = mHal->setIdleTimerEnabled(display, timeout);
403 return TO_BINDER_STATUS(err);
404 }
405
onHotplug(int64_t display,bool connected)406 void ComposerClient::HalEventCallback::onHotplug(int64_t display, bool connected) {
407 DEBUG_FUNC();
408 if (connected) {
409 if (mResources->hasDisplay(display)) {
410 // This is a subsequent hotplug "connected" for a display. This signals a
411 // display change and thus the framework may want to reallocate buffers. We
412 // need to free all cached handles, since they are holding a strong reference
413 // to the underlying buffers.
414 cleanDisplayResources(display);
415 mResources->removeDisplay(display);
416 }
417 mResources->addPhysicalDisplay(display);
418 } else {
419 mResources->removeDisplay(display);
420 }
421
422 auto ret = mCallback->onHotplug(display, connected);
423 if (!ret.isOk()) {
424 LOG(ERROR) << "failed to send onHotplug:" << ret.getDescription();
425 }
426 }
427
onRefresh(int64_t display)428 void ComposerClient::HalEventCallback::onRefresh(int64_t display) {
429 DEBUG_FUNC();
430 mResources->setDisplayMustValidateState(display, true);
431 auto ret = mCallback->onRefresh(display);
432 if (!ret.isOk()) {
433 LOG(ERROR) << "failed to send onRefresh:" << ret.getDescription();
434 }
435 }
436
onVsync(int64_t display,int64_t timestamp,int32_t vsyncPeriodNanos)437 void ComposerClient::HalEventCallback::onVsync(int64_t display, int64_t timestamp,
438 int32_t vsyncPeriodNanos) {
439 DEBUG_FUNC();
440 auto ret = mCallback->onVsync(display, timestamp, vsyncPeriodNanos);
441 if (!ret.isOk()) {
442 LOG(ERROR) << "failed to send onVsync:" << ret.getDescription();
443 }
444 }
445
onVsyncPeriodTimingChanged(int64_t display,const VsyncPeriodChangeTimeline & timeline)446 void ComposerClient::HalEventCallback::onVsyncPeriodTimingChanged(
447 int64_t display, const VsyncPeriodChangeTimeline& timeline) {
448 DEBUG_FUNC();
449 auto ret = mCallback->onVsyncPeriodTimingChanged(display, timeline);
450 if (!ret.isOk()) {
451 LOG(ERROR) << "failed to send onVsyncPeriodTimingChanged:" << ret.getDescription();
452 }
453 }
454
onVsyncIdle(int64_t display)455 void ComposerClient::HalEventCallback::onVsyncIdle(int64_t display) {
456 DEBUG_FUNC();
457 auto ret = mCallback->onVsyncIdle(display);
458 if (!ret.isOk()) {
459 LOG(ERROR) << "failed to send onVsyncIdle:" << ret.getDescription();
460 }
461 }
462
onSeamlessPossible(int64_t display)463 void ComposerClient::HalEventCallback::onSeamlessPossible(int64_t display) {
464 DEBUG_FUNC();
465 auto ret = mCallback->onSeamlessPossible(display);
466 if (!ret.isOk()) {
467 LOG(ERROR) << "failed to send onSealmessPossible:" << ret.getDescription();
468 }
469 }
470
cleanDisplayResources(int64_t display)471 void ComposerClient::HalEventCallback::cleanDisplayResources(int64_t display) {
472 DEBUG_FUNC();
473 size_t cacheSize;
474 auto err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize);
475 if (!err) {
476 for (int slot = 0; slot < cacheSize; slot++) {
477 // Replace the buffer slots with NULLs. Keep the old handle until it is
478 // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
479 buffer_handle_t outHandle;
480 auto bufReleaser = mResources->createReleaser(true /* isBuffer */);
481 err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true,
482 /*rawHandle*/ nullptr, outHandle,
483 bufReleaser.get());
484 if (err) {
485 continue;
486 }
487 const std::vector<common::Rect> damage;
488 ndk::ScopedFileDescriptor fence; // empty fence
489 common::Dataspace dataspace = common::Dataspace::UNKNOWN;
490 err = mHal->setClientTarget(display, outHandle, fence, dataspace, damage);
491 if (err) {
492 LOG(ERROR) << "Can't clean slot " << slot
493 << " of the client target buffer cache for display" << display;
494 }
495 }
496 } else {
497 LOG(ERROR) << "Can't clean client target cache for display " << display;
498 }
499
500 err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize);
501 if (!err) {
502 for (int slot = 0; slot < cacheSize; slot++) {
503 // Replace the buffer slots with NULLs. Keep the old handle until it is
504 // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
505 buffer_handle_t outputBuffer;
506 auto bufReleaser = mResources->createReleaser(true /* isBuffer */);
507 err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
508 /*rawHandle*/ nullptr, outputBuffer,
509 bufReleaser.get());
510 if (err) {
511 continue;
512 }
513 ndk::ScopedFileDescriptor emptyFd;
514 err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ emptyFd);
515 if (err) {
516 LOG(ERROR) << "Can't clean slot " << slot
517 << " of the output buffer cache for display " << display;
518 }
519 }
520 } else {
521 LOG(ERROR) << "Can't clean output buffer cache for display " << display;
522 }
523 }
524
destroyResources()525 void ComposerClient::destroyResources() {
526 DEBUG_FUNC();
527 // We want to call hwc2_close here (and move hwc2_open to the
528 // constructor), with the assumption that hwc2_close would
529 //
530 // - clean up all resources owned by the client
531 // - make sure all displays are blank (since there is no layer)
532 //
533 // But since SF used to crash at this point, different hwcomposer2
534 // implementations behave differently on hwc2_close. Our only portable
535 // choice really is to abort(). But that is not an option anymore
536 // because we might also have VTS or VR as clients that can come and go.
537 //
538 // Below we manually clean all resources (layers and virtual
539 // displays), and perform a presentDisplay afterwards.
540 mResources->clear([this](int64_t display, bool isVirtual, const std::vector<int64_t> layers) {
541 LOG(WARNING) << "destroying client resources for display " << display;
542 for (auto layer : layers) {
543 mHal->destroyLayer(display, layer);
544 }
545
546 if (isVirtual) {
547 mHal->destroyVirtualDisplay(display);
548 } else {
549 LOG(WARNING) << "performing a final presentDisplay";
550 std::vector<int64_t> changedLayers;
551 std::vector<Composition> compositionTypes;
552 uint32_t displayRequestMask = 0;
553 std::vector<int64_t> requestedLayers;
554 std::vector<int32_t> requestMasks;
555 ClientTargetProperty clientTargetProperty;
556 DimmingStage dimmingStage;
557 mHal->validateDisplay(display, &changedLayers, &compositionTypes, &displayRequestMask,
558 &requestedLayers, &requestMasks, &clientTargetProperty,
559 &dimmingStage);
560 mHal->acceptDisplayChanges(display);
561
562 ndk::ScopedFileDescriptor presentFence;
563 std::vector<int64_t> releasedLayers;
564 std::vector<ndk::ScopedFileDescriptor> releaseFences;
565 mHal->presentDisplay(display, presentFence, &releasedLayers, &releaseFences);
566 }
567 });
568 mResources.reset();
569 }
570
createBinder()571 ::ndk::SpAIBinder ComposerClient::createBinder() {
572 auto binder = BnComposerClient::createBinder();
573 AIBinder_setInheritRt(binder.get(), true);
574 return binder;
575 }
576
577 } // namespace aidl::android::hardware::graphics::composer3::impl
578