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