• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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