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