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