1 /*
2 * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
3 * Not a Contribution.
4 *
5 * Copyright (C) 2017 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #include <vector>
21 #include <string>
22
23 #include "QtiComposerClient.h"
24
25 namespace vendor {
26 namespace qti {
27 namespace hardware {
28 namespace display {
29 namespace composer {
30 namespace V3_0 {
31 namespace implementation {
32
33 ComposerHandleImporter mHandleImporter;
34
BufferCacheEntry()35 BufferCacheEntry::BufferCacheEntry() : mHandle(nullptr) {}
36
BufferCacheEntry(BufferCacheEntry && other)37 BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other) {
38 mHandle = other.mHandle;
39 other.mHandle = nullptr;
40 }
41
operator =(buffer_handle_t handle)42 BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle) {
43 clear();
44 mHandle = handle;
45 return *this;
46 }
47
~BufferCacheEntry()48 BufferCacheEntry::~BufferCacheEntry() {
49 clear();
50 }
51
clear()52 void BufferCacheEntry::clear() {
53 if (mHandle) {
54 mHandleImporter.freeBuffer(mHandle);
55 }
56 }
57
QtiComposerClient()58 QtiComposerClient::QtiComposerClient() : mWriter(kWriterInitialSize), mReader(*this) {
59 hwc_session_ = HWCSession::GetInstance();
60 mHandleImporter.initialize();
61 }
62
~QtiComposerClient()63 QtiComposerClient::~QtiComposerClient() {
64 // We want to call hwc2_close here (and move hwc2_open to the
65 // constructor), with the assumption that hwc2_close would
66 //
67 // - clean up all resources owned by the client
68 // - make sure all displays are blank (since there is no layer)
69 //
70 // But since SF used to crash at this point, different hwcomposer2
71 // implementations behave differently on hwc2_close. Our only portable
72 // choice really is to abort(). But that is not an option anymore
73 // because we might also have VTS or VR as clients that can come and go.
74 //
75 // Below we manually clean all resources (layers and virtual
76 // displays), and perform a presentDisplay afterwards.
77 ALOGW("destroying composer client");
78
79 enableCallback(false);
80
81 // no need to grab the mutex as any in-flight hwbinder call would have
82 // kept the client alive
83 for (const auto& dpy : mDisplayData) {
84 ALOGW("destroying client resources for display %" PRIu64, dpy.first);
85
86 for (const auto& ly : dpy.second.Layers) {
87 hwc_session_->DestroyLayer(dpy.first, ly.first);
88 }
89
90 if (dpy.second.IsVirtual) {
91 destroyVirtualDisplay(dpy.first);
92 } else {
93 ALOGW("performing a final presentDisplay");
94
95 std::vector<Layer> changedLayers;
96 std::vector<IComposerClient::Composition> compositionTypes;
97 uint32_t displayRequestMask = 0;
98 std::vector<Layer> requestedLayers;
99 std::vector<uint32_t> requestMasks;
100 IComposerClient::ClientTargetProperty clientTargetProperty;
101 mReader.validateDisplay(dpy.first, changedLayers, compositionTypes, displayRequestMask,
102 requestedLayers, requestMasks, clientTargetProperty);
103
104 hwc_session_->AcceptDisplayChanges(dpy.first);
105
106 shared_ptr<Fence> presentFence = nullptr;
107 std::vector<Layer> releasedLayers;
108 std::vector<shared_ptr<Fence>> releaseFences;
109 mReader.presentDisplay(dpy.first, &presentFence, releasedLayers, releaseFences);
110 }
111 }
112
113 mDisplayData.clear();
114
115 mHandleImporter.cleanup();
116
117 ALOGW("removed composer client");
118 }
119
onHotplug(hwc2_callback_data_t callbackData,hwc2_display_t display,int32_t connected)120 void QtiComposerClient::onHotplug(hwc2_callback_data_t callbackData, hwc2_display_t display,
121 int32_t connected) {
122 auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
123 auto connect = static_cast<composer_V2_4::IComposerCallback::Connection>(connected);
124 if (connect == composer_V2_4::IComposerCallback::Connection::CONNECTED) {
125 std::lock_guard<std::mutex> lock_d(client->mDisplayDataMutex);
126 client->mDisplayData.emplace(display, DisplayData(false));
127 }
128
129 auto ret = client->callback_->onHotplug(display, connect);
130 ALOGW_IF(!ret.isOk(), "failed to send onHotplug: %s. SF likely unavailable.",
131 ret.description().c_str());
132
133 if (connect == composer_V2_4::IComposerCallback::Connection::DISCONNECTED) {
134 // Trigger refresh to make sure disconnect event received/updated properly by SurfaceFlinger.
135 client->hwc_session_->Refresh(HWC_DISPLAY_PRIMARY);
136 // Wait for sufficient time to ensure sufficient resources are available to process connection.
137 uint32_t vsync_period;
138 client->hwc_session_->GetVsyncPeriod(HWC_DISPLAY_PRIMARY, &vsync_period);
139 usleep(vsync_period * 2 / 1000);
140
141 // Wait for the input command message queue to process before destroying the local display data.
142 std::lock_guard<std::mutex> lock(client->mCommandMutex);
143 std::lock_guard<std::mutex> lock_d(client->mDisplayDataMutex);
144 client->mDisplayData.erase(display);
145 }
146 }
147
onRefresh(hwc2_callback_data_t callbackData,hwc2_display_t display)148 void QtiComposerClient::onRefresh(hwc2_callback_data_t callbackData, hwc2_display_t display) {
149 auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
150 auto ret = client->callback_->onRefresh(display);
151 ALOGW_IF(!ret.isOk(), "failed to send onRefresh: %s. SF likely unavailable.",
152 ret.description().c_str());
153 }
154
onVsync(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp)155 void QtiComposerClient::onVsync(hwc2_callback_data_t callbackData, hwc2_display_t display,
156 int64_t timestamp) {
157 auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
158 auto ret = client->callback_->onVsync(display, timestamp);
159 ALOGW_IF(!ret.isOk(), "failed to send onVsync: %s. SF likely unavailable.",
160 ret.description().c_str());
161 }
162
onVsync_2_4(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp,VsyncPeriodNanos vsyncPeriodNanos)163 void QtiComposerClient::onVsync_2_4(hwc2_callback_data_t callbackData, hwc2_display_t display,
164 int64_t timestamp, VsyncPeriodNanos vsyncPeriodNanos) {
165 auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
166 auto ret = client->callback24_->onVsync_2_4(display, timestamp, vsyncPeriodNanos);
167 ALOGW_IF(!ret.isOk(), "failed to send onVsync_2_4: %s. SF likely unavailable.",
168 ret.description().c_str());
169 }
170
onVsyncPeriodTimingChanged(hwc2_callback_data_t callbackData,hwc2_display_t display,hwc_vsync_period_change_timeline_t * updatedTimeline)171 void QtiComposerClient::onVsyncPeriodTimingChanged(hwc2_callback_data_t callbackData,
172 hwc2_display_t display, hwc_vsync_period_change_timeline_t *updatedTimeline) {
173 VsyncPeriodChangeTimeline timeline =
174 {updatedTimeline->newVsyncAppliedTimeNanos,
175 static_cast<bool>(updatedTimeline->refreshRequired),
176 updatedTimeline->refreshTimeNanos};
177
178 auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
179 auto ret = client->callback24_->onVsyncPeriodTimingChanged(display, timeline);
180 ALOGW_IF(!ret.isOk(), "failed to send onVsyncPeriodTimingChanged: %s. SF likely unavailable.",
181 ret.description().c_str());
182 }
183
onSeamlessPossible(hwc2_callback_data_t callbackData,hwc2_display_t display)184 void QtiComposerClient::onSeamlessPossible(hwc2_callback_data_t callbackData,
185 hwc2_display_t display) {
186 auto client = reinterpret_cast<QtiComposerClient*>(callbackData);
187 auto ret = client->callback24_->onSeamlessPossible(display);
188 ALOGW_IF(!ret.isOk(), "failed to send onSeamlessPossible: %s. SF likely unavailable.",
189 ret.description().c_str());
190 }
191
192 // convert fenceFd to or from hidl_handle
193 // Handle would still own original fence. Hence create a Fence object on duped fd.
getFence(const hidl_handle & fenceHandle,shared_ptr<Fence> * outFence,const string & name)194 Error QtiComposerClient::getFence(const hidl_handle& fenceHandle, shared_ptr<Fence>* outFence,
195 const string& name) {
196 auto handle = fenceHandle.getNativeHandle();
197 if (handle && handle->numFds > 1) {
198 ALOGE("invalid fence handle with %d fds", handle->numFds);
199 return Error::BAD_PARAMETER;
200 }
201
202 int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
203 *outFence = Fence::Create(dup(fenceFd), name);
204
205 return Error::NONE;
206 }
207
208 // Handle would own fence hereafter. Hence provide a dupped fd.
getFenceHandle(const shared_ptr<Fence> & fence,char * handleStorage)209 hidl_handle QtiComposerClient::getFenceHandle(const shared_ptr<Fence>& fence,
210 char* handleStorage) {
211 native_handle_t* handle = nullptr;
212 if (fence) {
213 handle = native_handle_init(handleStorage, 1, 0);
214 if (handle) {
215 handle->data[0] = Fence::Dup(fence);
216 }
217 }
218
219 return hidl_handle(handle);
220 }
221
getDisplayReadbackBuffer(Display display,const native_handle_t * rawHandle,const native_handle_t ** outHandle)222 Error QtiComposerClient::getDisplayReadbackBuffer(Display display,
223 const native_handle_t* rawHandle,
224 const native_handle_t** outHandle) {
225 // TODO(user): revisit for caching and freeBuffer in success case.
226 if (!mHandleImporter.importBuffer(rawHandle)) {
227 ALOGE("%s: importBuffer failed: ", __FUNCTION__);
228 return Error::NO_RESOURCES;
229 }
230
231 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
232 auto iter = mDisplayData.find(display);
233 if (iter == mDisplayData.end()) {
234 mHandleImporter.freeBuffer(rawHandle);
235 return Error::BAD_DISPLAY;
236 }
237
238 *outHandle = rawHandle;
239 return Error::NONE;
240 }
241
getCapabilities()242 void QtiComposerClient::getCapabilities() {
243 uint32_t count = 0;
244 hwc_session_->GetCapabilities(&count, nullptr);
245
246 std::vector<int32_t> composer_caps(count);
247 hwc_session_->GetCapabilities(&count, composer_caps.data());
248 composer_caps.resize(count);
249
250 mCapabilities.reserve(count);
251 for (auto cap : composer_caps) {
252 mCapabilities.insert(static_cast<hwc2_capability_t>(cap));
253 }
254 }
255
enableCallback(bool enable)256 void QtiComposerClient::enableCallback(bool enable) {
257 if (enable) {
258 hwc_session_->RegisterCallback(HWC2_CALLBACK_HOTPLUG, this,
259 reinterpret_cast<hwc2_function_pointer_t>(onHotplug));
260 hwc_session_->RegisterCallback(HWC2_CALLBACK_REFRESH, this,
261 reinterpret_cast<hwc2_function_pointer_t>(onRefresh));
262 if (!mUseCallback24_) {
263 hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC, this,
264 reinterpret_cast<hwc2_function_pointer_t>(onVsync));
265 } else {
266 hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_2_4, this,
267 reinterpret_cast<hwc2_function_pointer_t>(onVsync_2_4));
268 hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
269 reinterpret_cast<hwc2_function_pointer_t>(onVsyncPeriodTimingChanged));
270 hwc_session_->RegisterCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
271 reinterpret_cast<hwc2_function_pointer_t>(onSeamlessPossible));
272 }
273 } else {
274 hwc_session_->RegisterCallback(HWC2_CALLBACK_HOTPLUG, this, nullptr);
275 hwc_session_->RegisterCallback(HWC2_CALLBACK_REFRESH, this, nullptr);
276 if (!mUseCallback24_) {
277 hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC, this, nullptr);
278 } else {
279 hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
280 hwc_session_->RegisterCallback(HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this, nullptr);
281 hwc_session_->RegisterCallback(HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, nullptr);
282 }
283 }
284 }
285
286 // Methods from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
registerCallback(const sp<composer_V2_1::IComposerCallback> & callback)287 Return<void> QtiComposerClient::registerCallback(
288 const sp<composer_V2_1::IComposerCallback>& callback) {
289 callback_ = callback;
290 enableCallback(callback != nullptr);
291 return Void();
292 }
293
getMaxVirtualDisplayCount()294 Return<uint32_t> QtiComposerClient::getMaxVirtualDisplayCount() {
295 return hwc_session_->GetMaxVirtualDisplayCount();
296 }
297
createVirtualDisplay(uint32_t width,uint32_t height,common_V1_0::PixelFormat formatHint,uint32_t outputBufferSlotCount,createVirtualDisplay_cb _hidl_cb)298 Return<void> QtiComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
299 common_V1_0::PixelFormat formatHint,
300 uint32_t outputBufferSlotCount,
301 createVirtualDisplay_cb _hidl_cb) {
302 // TODO(user): Implement combinedly w.r.t createVirtualDisplay_2_2
303 int32_t format = static_cast<int32_t>(formatHint);
304 uint64_t display;
305 auto error = hwc_session_->CreateVirtualDisplay(width, height, &format, &display);
306
307 if (static_cast<Error>(error) == Error::NONE) {
308 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
309
310 auto dpy = mDisplayData.emplace(static_cast<Display>(display), DisplayData(true)).first;
311 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
312 }
313
314 _hidl_cb(static_cast<Error>(error), display, static_cast<common_V1_0::PixelFormat>(format));
315 return Void();
316 }
317
destroyVirtualDisplay(uint64_t display)318 Return<composer_V2_1::Error> QtiComposerClient::destroyVirtualDisplay(uint64_t display) {
319 auto error = hwc_session_->DestroyVirtualDisplay(display);
320 if (static_cast<Error>(error) == Error::NONE) {
321 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
322
323 mDisplayData.erase(display);
324 }
325
326 return static_cast<Error>(error);
327 }
328
createLayer(uint64_t display,uint32_t bufferSlotCount,createLayer_cb _hidl_cb)329 Return<void> QtiComposerClient::createLayer(uint64_t display, uint32_t bufferSlotCount,
330 createLayer_cb _hidl_cb) {
331 composer_V2_1::Layer layer = 0;
332 auto error = hwc_session_->CreateLayer(display, &layer);
333 Error err = static_cast<Error>(error);
334 if (err == Error::NONE) {
335 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
336 auto dpy = mDisplayData.find(display);
337 // The display entry may have already been removed by onHotplug.
338 if (dpy != mDisplayData.end()) {
339 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
340 ly->second.Buffers.resize(bufferSlotCount);
341 } else {
342 err = Error::BAD_DISPLAY;
343 // Note: We do not destroy the layer on this error as the hotplug
344 // disconnect invalidates the display id. The implementation should
345 // ensure all layers for the display are destroyed.
346 }
347 }
348
349 _hidl_cb(err, layer);
350 return Void();
351 }
352
destroyLayer(uint64_t display,uint64_t layer)353 Return<Error> QtiComposerClient::destroyLayer(uint64_t display, uint64_t layer) {
354 auto error = hwc_session_->DestroyLayer(display, layer);
355 Error err = static_cast<Error>(error);
356 if (err == Error::NONE) {
357 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
358
359 auto dpy = mDisplayData.find(display);
360 // The display entry may have already been removed by onHotplug.
361 if (dpy != mDisplayData.end()) {
362 dpy->second.Layers.erase(layer);
363 }
364 }
365
366 return static_cast<Error>(error);
367 }
368
getActiveConfig(uint64_t display,getActiveConfig_cb _hidl_cb)369 Return<void> QtiComposerClient::getActiveConfig(uint64_t display, getActiveConfig_cb _hidl_cb) {
370 uint32_t config = 0;
371 auto error = hwc_session_->GetActiveConfig(display, &config);
372
373 _hidl_cb(static_cast<Error>(error), config);
374
375 return Void();
376 }
377
getClientTargetSupport(uint64_t display,uint32_t width,uint32_t height,common_V1_0::PixelFormat format,common_V1_0::Dataspace dataspace)378 Return<Error> QtiComposerClient::getClientTargetSupport(uint64_t display, uint32_t width,
379 uint32_t height,
380 common_V1_0::PixelFormat format,
381 common_V1_0::Dataspace dataspace) {
382 auto error = hwc_session_->GetClientTargetSupport(display, width, height,
383 static_cast<int32_t>(format),
384 static_cast<int32_t>(dataspace));
385
386 return static_cast<Error>(error);
387 }
388
getColorModes(uint64_t display,getColorModes_cb _hidl_cb)389 Return<void> QtiComposerClient::getColorModes(uint64_t display, getColorModes_cb _hidl_cb) {
390 // TODO(user): Implement combinedly w.r.t getColorModes_2_3
391 hidl_vec<common_V1_0::ColorMode> modes;
392 uint32_t count = 0;
393
394 auto error = hwc_session_->GetColorModes(display, &count, nullptr);
395 if (error != HWC2_ERROR_NONE) {
396 _hidl_cb(static_cast<Error>(error), modes);
397 return Void();
398 }
399
400 modes.resize(count);
401 error = hwc_session_->GetColorModes(display, &count,
402 reinterpret_cast<std::underlying_type<common_V1_0::ColorMode>::type*>(modes.data()));
403
404 _hidl_cb(static_cast<Error>(error), modes);
405 return Void();
406 }
407
getDisplayAttribute(uint64_t display,uint32_t config,composer_V2_1::IComposerClient::Attribute attribute,getDisplayAttribute_cb _hidl_cb)408 Return<void> QtiComposerClient::getDisplayAttribute(uint64_t display, uint32_t config,
409 composer_V2_1::IComposerClient::Attribute attribute,
410 getDisplayAttribute_cb _hidl_cb) {
411 int32_t value = 0;
412 auto error = hwc_session_->GetDisplayAttribute(
413 display, config, static_cast<composer_V2_4::IComposerClient::Attribute>(attribute), &value);
414
415 _hidl_cb(static_cast<Error>(error), value);
416 return Void();
417 }
418
getDisplayConfigs(uint64_t display,getDisplayConfigs_cb _hidl_cb)419 Return<void> QtiComposerClient::getDisplayConfigs(uint64_t display,
420 getDisplayConfigs_cb _hidl_cb) {
421 hidl_vec<uint32_t> configs;
422 uint32_t count = 0;
423
424 auto error = hwc_session_->GetDisplayConfigs(display, &count, nullptr);
425 if (error != HWC2_ERROR_NONE) {
426 _hidl_cb(static_cast<Error>(error), configs);
427 return Void();
428 }
429
430 configs.resize(count);
431 error = hwc_session_->GetDisplayConfigs(display, &count, configs.data());
432
433 _hidl_cb(static_cast<Error>(error), configs);
434 return Void();
435 }
436
getDisplayName(uint64_t display,getDisplayName_cb _hidl_cb)437 Return<void> QtiComposerClient::getDisplayName(uint64_t display, getDisplayName_cb _hidl_cb) {
438 uint32_t count = 0;
439 hidl_string name_reply;
440 std::vector<char> name;
441
442 auto error = hwc_session_->GetDisplayName(display, &count, nullptr);
443 if (error != HWC2_ERROR_NONE) {
444 _hidl_cb(static_cast<Error>(error), name_reply);
445 return Void();
446 }
447
448 name.resize(count + 1);
449 error = hwc_session_->GetDisplayName(display, &count, name.data());
450 if (error != HWC2_ERROR_NONE) {
451 _hidl_cb(static_cast<Error>(error), name_reply);
452 return Void();
453 }
454
455 name.resize(count + 1);
456 name[count] = '\0';
457 name_reply.setToExternal(name.data(), count);
458
459 _hidl_cb(static_cast<Error>(error), name_reply);
460 return Void();
461 }
462
getDisplayType(uint64_t display,getDisplayType_cb _hidl_cb)463 Return<void> QtiComposerClient::getDisplayType(uint64_t display, getDisplayType_cb _hidl_cb) {
464 int32_t hwc_type;
465 auto error = hwc_session_->GetDisplayType(display, &hwc_type);
466
467 _hidl_cb(static_cast<Error>(error), static_cast<IComposerClient::DisplayType>(hwc_type));
468 return Void();
469 }
470
getDozeSupport(uint64_t display,getDozeSupport_cb _hidl_cb)471 Return<void> QtiComposerClient::getDozeSupport(uint64_t display, getDozeSupport_cb _hidl_cb) {
472 int32_t hwc_support = 0;
473 auto error = hwc_session_->GetDozeSupport(display, &hwc_support);
474
475 _hidl_cb(static_cast<Error>(error), hwc_support);
476 return Void();
477 }
478
getHdrCapabilities(uint64_t display,getHdrCapabilities_cb _hidl_cb)479 Return<void> QtiComposerClient::getHdrCapabilities(uint64_t display,
480 getHdrCapabilities_cb _hidl_cb) {
481 // TODO(user): Implement combinedly w.r.t getHdrCapabilities_2_3
482 uint32_t count = 0;
483 hidl_vec<common_V1_0::Hdr> types;
484 float max_lumi = 0.0f;
485 float max_avg_lumi = 0.0f;
486 float min_lumi = 0.0f;
487
488 auto error = hwc_session_->GetHdrCapabilities(display, &count, nullptr, &max_lumi,
489 &max_avg_lumi, &min_lumi);
490 if (error != HWC2_ERROR_NONE) {
491 _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
492 return Void();
493 }
494
495 types.resize(count);
496 error = hwc_session_->GetHdrCapabilities(display, &count,
497 reinterpret_cast<std::underlying_type<common_V1_2::Hdr>::type*>(types.data()),
498 &max_lumi, &max_avg_lumi, &min_lumi);
499
500 _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
501 return Void();
502 }
503
setClientTargetSlotCount(uint64_t display,uint32_t clientTargetSlotCount)504 Return<Error> QtiComposerClient::setClientTargetSlotCount(uint64_t display,
505 uint32_t clientTargetSlotCount) {
506 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
507
508 auto dpy = mDisplayData.find(display);
509 if (dpy == mDisplayData.end()) {
510 return Error::BAD_DISPLAY;
511 }
512 dpy->second.ClientTargets.resize(clientTargetSlotCount);
513
514 return Error::NONE;
515 }
516
setActiveConfig(uint64_t display,uint32_t config)517 Return<Error> QtiComposerClient::setActiveConfig(uint64_t display, uint32_t config) {
518 auto error = hwc_session_->SetActiveConfig(display, config);
519
520 return static_cast<Error>(error);
521 }
522
setColorMode(uint64_t display,common_V1_0::ColorMode mode)523 Return<Error> QtiComposerClient::setColorMode(uint64_t display, common_V1_0::ColorMode mode) {
524 auto error = hwc_session_->SetColorMode(display, static_cast<int32_t>(mode));
525
526 return static_cast<Error>(error);
527 }
528
setPowerMode(uint64_t display,composer_V2_1::IComposerClient::PowerMode mode)529 Return<Error> QtiComposerClient::setPowerMode(uint64_t display,
530 composer_V2_1::IComposerClient::PowerMode mode) {
531 // TODO(user): Implement combinedly w.r.t setPowerMode_2_2
532 auto error = hwc_session_->SetPowerMode(display, static_cast<int32_t>(mode));
533
534 return static_cast<Error>(error);
535 }
536
setVsyncEnabled(uint64_t display,composer_V2_1::IComposerClient::Vsync enabled)537 Return<Error> QtiComposerClient::setVsyncEnabled(uint64_t display,
538 composer_V2_1::IComposerClient::Vsync enabled) {
539 auto error = hwc_session_->SetVsyncEnabled(display, static_cast<int32_t>(enabled));
540
541 return static_cast<Error>(error);
542 }
543
setInputCommandQueue(const MQDescriptorSync<uint32_t> & descriptor)544 Return<Error> QtiComposerClient::setInputCommandQueue(
545 const MQDescriptorSync<uint32_t>& descriptor) {
546 std::lock_guard<std::mutex> lock(mCommandMutex);
547 return mReader.setMQDescriptor(descriptor) ? Error::NONE : Error::NO_RESOURCES;
548 }
549
getOutputCommandQueue(getOutputCommandQueue_cb _hidl_cb)550 Return<void> QtiComposerClient::getOutputCommandQueue(getOutputCommandQueue_cb _hidl_cb) {
551 // no locking as we require this function to be called inside
552 // executeCommands_cb
553
554 auto outDescriptor = mWriter.getMQDescriptor();
555 if (outDescriptor) {
556 _hidl_cb(Error::NONE, *outDescriptor);
557 } else {
558 _hidl_cb(Error::NO_RESOURCES, MQDescriptorSync<uint32_t>());
559 }
560
561 return Void();
562 }
563
executeCommands(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_cb _hidl_cb)564 Return<void> QtiComposerClient::executeCommands(uint32_t inLength,
565 const hidl_vec<hidl_handle>& inHandles,
566 executeCommands_cb _hidl_cb) {
567 std::lock_guard<std::mutex> lock(mCommandMutex);
568
569 bool outChanged = false;
570 uint32_t outLength = 0;
571 hidl_vec<hidl_handle> outHandles;
572
573 if (!mReader.readQueue(inLength, inHandles)) {
574 _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
575 return Void();
576 }
577
578 Error err = mReader.parse();
579 if (err == Error::NONE &&
580 !mWriter.writeQueue(outChanged, outLength, outHandles)) {
581 err = Error::NO_RESOURCES;
582 }
583
584 _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
585
586 mReader.reset();
587 mWriter.reset();
588
589 return Void();
590 }
591
592
593 // Methods from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
getPerFrameMetadataKeys(uint64_t display,getPerFrameMetadataKeys_cb _hidl_cb)594 Return<void> QtiComposerClient::getPerFrameMetadataKeys(uint64_t display,
595 getPerFrameMetadataKeys_cb _hidl_cb) {
596 // TODO(user): Implement combinedly w.r.t getPerFrameMetadataKeys_2_3
597 std::vector<PerFrameMetadataKey_V2> keys;
598 uint32_t count = 0;
599
600 auto error = hwc_session_->GetPerFrameMetadataKeys(display, &count, nullptr);
601 if (error != HWC2_ERROR_NONE) {
602 _hidl_cb(static_cast<Error>(error), keys);
603 return Void();
604 }
605
606 keys.resize(count);
607 error = hwc_session_->GetPerFrameMetadataKeys(display, &count,
608 reinterpret_cast<std::underlying_type<PerFrameMetadataKey_V2>::type*>(keys.data()));
609
610 _hidl_cb(static_cast<Error>(error), keys);
611 return Void();
612 }
613
getReadbackBufferAttributes(uint64_t display,getReadbackBufferAttributes_cb _hidl_cb)614 Return<void> QtiComposerClient::getReadbackBufferAttributes(uint64_t display,
615 getReadbackBufferAttributes_cb _hidl_cb) {
616 // TODO(user): Implement combinedly w.r.t getReadbackBufferAttributes_2_3
617 int32_t format = 0;
618 int32_t dataspace = 0;
619
620 auto error = hwc_session_->GetReadbackBufferAttributes(display, &format, &dataspace);
621
622 if (error != HWC2_ERROR_NONE) {
623 format = 0;
624 dataspace = 0;
625 }
626
627 _hidl_cb(static_cast<Error>(error), static_cast<common_V1_1::PixelFormat>(format),
628 static_cast<common_V1_1::Dataspace>(dataspace));
629 return Void();
630 }
631
getReadbackBufferFence(uint64_t display,getReadbackBufferFence_cb _hidl_cb)632 Return<void> QtiComposerClient::getReadbackBufferFence(uint64_t display,
633 getReadbackBufferFence_cb _hidl_cb) {
634 shared_ptr<Fence> fence = nullptr;
635 auto error = hwc_session_->GetReadbackBufferFence(display, &fence);
636 if (static_cast<Error>(error) != Error::NONE) {
637 _hidl_cb(static_cast<Error>(error), nullptr);
638 return Void();
639 }
640
641 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
642
643 _hidl_cb(static_cast<Error>(error), getFenceHandle(fence, fenceStorage));
644 return Void();
645 }
646
setReadbackBuffer(uint64_t display,const hidl_handle & buffer,const hidl_handle & releaseFence)647 Return<Error> QtiComposerClient::setReadbackBuffer(uint64_t display, const hidl_handle& buffer,
648 const hidl_handle& releaseFence) {
649 shared_ptr<Fence> fence = nullptr;
650 Error error = getFence(releaseFence, &fence, "read_back");
651 if (error != Error::NONE) {
652 return error;
653 }
654
655 const native_handle_t* readbackBuffer;
656 error = getDisplayReadbackBuffer(display, buffer.getNativeHandle(), &readbackBuffer);
657 if (error != Error::NONE) {
658 return error;
659 }
660
661 auto err = hwc_session_->SetReadbackBuffer(display, readbackBuffer, fence);
662 return static_cast<Error>(err);
663 }
664
createVirtualDisplay_2_2(uint32_t width,uint32_t height,common_V1_1::PixelFormat formatHint,uint32_t outputBufferSlotCount,createVirtualDisplay_2_2_cb _hidl_cb)665 Return<void> QtiComposerClient::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
666 common_V1_1::PixelFormat formatHint,
667 uint32_t outputBufferSlotCount,
668 createVirtualDisplay_2_2_cb _hidl_cb) {
669 int32_t format = static_cast<int32_t>(formatHint);
670 uint64_t display;
671 auto error = hwc_session_->CreateVirtualDisplay(width, height, &format, &display);
672
673 if (static_cast<Error>(error) == Error::NONE) {
674 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
675
676 auto dpy = mDisplayData.emplace(static_cast<Display>(display), DisplayData(true)).first;
677 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
678 }
679
680 _hidl_cb(static_cast<Error>(error), display, static_cast<common_V1_1::PixelFormat>(format));
681 return Void();
682 }
683
getClientTargetSupport_2_2(uint64_t display,uint32_t width,uint32_t height,common_V1_1::PixelFormat format,common_V1_1::Dataspace dataspace)684 Return<Error> QtiComposerClient::getClientTargetSupport_2_2(uint64_t display, uint32_t width,
685 uint32_t height,
686 common_V1_1::PixelFormat format,
687 common_V1_1::Dataspace dataspace) {
688 auto error = hwc_session_->GetClientTargetSupport(display, width, height,
689 static_cast<int32_t>(format),
690 static_cast<int32_t>(dataspace));
691
692 return static_cast<Error>(error);
693 }
694
setPowerMode_2_2(uint64_t display,composer_V2_2::IComposerClient::PowerMode mode)695 Return<Error> QtiComposerClient::setPowerMode_2_2(uint64_t display,
696 composer_V2_2::IComposerClient::PowerMode mode) {
697 if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
698 return Error::UNSUPPORTED;
699 }
700 auto error = hwc_session_->SetPowerMode(display, static_cast<int32_t>(mode));
701
702 return static_cast<Error>(error);
703 }
704
getColorModes_2_2(uint64_t display,getColorModes_2_2_cb _hidl_cb)705 Return<void> QtiComposerClient::getColorModes_2_2(uint64_t display,
706 getColorModes_2_2_cb _hidl_cb) {
707 // TODO(user): Implement combinedly w.r.t getColorModes_2_3
708 hidl_vec<common_V1_1::ColorMode> modes;
709 uint32_t count = 0;
710
711 auto error = hwc_session_->GetColorModes(display, &count, nullptr);
712 if (error != HWC2_ERROR_NONE) {
713 _hidl_cb(static_cast<Error>(error), modes);
714 return Void();
715 }
716
717 modes.resize(count);
718 error = hwc_session_->GetColorModes(display, &count,
719 reinterpret_cast<std::underlying_type<common_V1_1::ColorMode>::type*>(modes.data()));
720
721 _hidl_cb(static_cast<Error>(error), modes);
722 return Void();
723 }
724
getRenderIntents(uint64_t display,common_V1_1::ColorMode mode,getRenderIntents_cb _hidl_cb)725 Return<void> QtiComposerClient::getRenderIntents(uint64_t display, common_V1_1::ColorMode mode,
726 getRenderIntents_cb _hidl_cb) {
727 // TODO(user): Implement combinedly w.r.t getRenderIntents_2_3
728 uint32_t count = 0;
729 std::vector<RenderIntent> intents;
730
731 auto error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count, nullptr);
732 if (error != HWC2_ERROR_NONE) {
733 _hidl_cb(static_cast<Error>(error), intents);
734 return Void();
735 }
736
737 intents.resize(count);
738 error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count,
739 reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
740
741 _hidl_cb(static_cast<Error>(error), intents);
742 return Void();
743 }
744
setColorMode_2_2(uint64_t display,common_V1_1::ColorMode mode,common_V1_1::RenderIntent intent)745 Return<Error> QtiComposerClient::setColorMode_2_2(uint64_t display, common_V1_1::ColorMode mode,
746 common_V1_1::RenderIntent intent) {
747 auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),
748 static_cast<int32_t>(intent));
749
750 return static_cast<Error>(error);
751 }
752
getDataspaceSaturationMatrix(common_V1_1::Dataspace dataspace,getDataspaceSaturationMatrix_cb _hidl_cb)753 Return<void> QtiComposerClient::getDataspaceSaturationMatrix(common_V1_1::Dataspace dataspace,
754 getDataspaceSaturationMatrix_cb _hidl_cb) {
755 if (dataspace != common_V1_1::Dataspace::SRGB_LINEAR) {
756 _hidl_cb(Error::BAD_PARAMETER, std::array<float, 16>{0.0f}.data());
757 return Void();
758 }
759
760 std::array<float, 16> matrix;
761 int32_t error = HWC2_ERROR_UNSUPPORTED;
762 error = hwc_session_->GetDataspaceSaturationMatrix(static_cast<int32_t>(dataspace),
763 matrix.data());
764 if (error != HWC2_ERROR_NONE) {
765 matrix = {
766 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
767 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
768 };
769 }
770 _hidl_cb(Error::NONE, matrix.data());
771 return Void();
772 }
773
executeCommands_2_2(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_2_2_cb _hidl_cb)774 Return<void> QtiComposerClient::executeCommands_2_2(uint32_t inLength,
775 const hidl_vec<hidl_handle>& inHandles,
776 executeCommands_2_2_cb _hidl_cb) {
777 std::lock_guard<std::mutex> lock(mCommandMutex);
778
779 bool outChanged = false;
780 uint32_t outLength = 0;
781 hidl_vec<hidl_handle> outHandles;
782
783 if (!mReader.readQueue(inLength, inHandles)) {
784 _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
785 return Void();
786 }
787
788 Error err = mReader.parse();
789 if (err == Error::NONE &&
790 !mWriter.writeQueue(outChanged, outLength, outHandles)) {
791 err = Error::NO_RESOURCES;
792 }
793
794 _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
795
796 mReader.reset();
797 mWriter.reset();
798
799 return Void();
800 }
801
802
803 // Methods from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
getDisplayIdentificationData(uint64_t display,getDisplayIdentificationData_cb _hidl_cb)804 Return<void> QtiComposerClient::getDisplayIdentificationData(uint64_t display,
805 getDisplayIdentificationData_cb _hidl_cb) {
806 uint8_t port = 0;
807 uint32_t size = 0;
808 std::vector<uint8_t> data(size);
809
810 auto error = hwc_session_->GetDisplayIdentificationData(display, &port, &size, nullptr);
811 if (error != HWC2_ERROR_NONE) {
812 _hidl_cb(static_cast<Error>(error), port, data);
813 return Void();
814 }
815
816 data.resize(size);
817 error = hwc_session_->GetDisplayIdentificationData(display, &port, &size, data.data());
818
819 _hidl_cb(static_cast<Error>(error), port, data);
820 return Void();
821 }
822
getReadbackBufferAttributes_2_3(uint64_t display,getReadbackBufferAttributes_2_3_cb _hidl_cb)823 Return<void> QtiComposerClient::getReadbackBufferAttributes_2_3(uint64_t display,
824 getReadbackBufferAttributes_2_3_cb _hidl_cb) {
825 int32_t format = 0;
826 int32_t dataspace = 0;
827
828 auto error = hwc_session_->GetReadbackBufferAttributes(display, &format, &dataspace);
829
830 if (error != HWC2_ERROR_NONE) {
831 format = 0;
832 dataspace = 0;
833 }
834
835 _hidl_cb(static_cast<Error>(error), static_cast<common_V1_2::PixelFormat>(format),
836 static_cast<common_V1_2::Dataspace>(dataspace));
837 return Void();
838 }
839
getClientTargetSupport_2_3(uint64_t display,uint32_t width,uint32_t height,common_V1_2::PixelFormat format,common_V1_2::Dataspace dataspace)840 Return<Error> QtiComposerClient::getClientTargetSupport_2_3(uint64_t display, uint32_t width,
841 uint32_t height,
842 common_V1_2::PixelFormat format,
843 common_V1_2::Dataspace dataspace) {
844 auto error = hwc_session_->GetClientTargetSupport(display, width, height,
845 static_cast<int32_t>(format),
846 static_cast<int32_t>(dataspace));
847
848 return static_cast<Error>(error);
849 }
850
getDisplayedContentSamplingAttributes(uint64_t display,getDisplayedContentSamplingAttributes_cb _hidl_cb)851 Return<void> QtiComposerClient::getDisplayedContentSamplingAttributes(uint64_t display,
852 getDisplayedContentSamplingAttributes_cb _hidl_cb) {
853 // getDisplayedContentSamplingAttributes is not supported
854 int constexpr invalid = -1;
855 auto error = Error::UNSUPPORTED;
856 common_V1_2::PixelFormat format = static_cast<common_V1_2::PixelFormat>(invalid);
857 common_V1_2::Dataspace dataspace = static_cast<common_V1_2::Dataspace>(invalid);
858 hidl_bitfield<IComposerClient::FormatColorComponent> componentMask =
859 static_cast<hidl_bitfield<IComposerClient::FormatColorComponent>>(invalid);
860
861 _hidl_cb(error, format, dataspace, componentMask);
862 return Void();
863 }
864
setDisplayedContentSamplingEnabled(uint64_t display,composer_V2_3::IComposerClient::DisplayedContentSampling enable,hidl_bitfield<FormatColorComponent> componentMask,uint64_t maxFrames)865 Return<Error> QtiComposerClient::setDisplayedContentSamplingEnabled(uint64_t display,
866 composer_V2_3::IComposerClient::DisplayedContentSampling enable,
867 hidl_bitfield<FormatColorComponent> componentMask,
868 uint64_t maxFrames) {
869 // setDisplayedContentSamplingEnabled is not supported
870 return Error::UNSUPPORTED;
871 }
872
getDisplayedContentSample(uint64_t display,uint64_t maxFrames,uint64_t timestamp,getDisplayedContentSample_cb _hidl_cb)873 Return<void> QtiComposerClient::getDisplayedContentSample(uint64_t display, uint64_t maxFrames,
874 uint64_t timestamp,
875 getDisplayedContentSample_cb _hidl_cb) {
876 // getDisplayedContentSample is not supported
877 auto error = Error::UNSUPPORTED;
878 uint64_t frameCount = 0;
879 hidl_vec<uint64_t> sampleComponent0 = 0;
880 hidl_vec<uint64_t> sampleComponent1 = 0;
881 hidl_vec<uint64_t> sampleComponent2 = 0;
882 hidl_vec<uint64_t> sampleComponent3 = 0;
883
884 _hidl_cb(error, frameCount, sampleComponent0, sampleComponent1, sampleComponent2,
885 sampleComponent3);
886 return Void();
887 }
888
executeCommands_2_3(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_2_3_cb _hidl_cb)889 Return<void> QtiComposerClient::executeCommands_2_3(uint32_t inLength,
890 const hidl_vec<hidl_handle>& inHandles,
891 executeCommands_2_3_cb _hidl_cb) {
892 // TODO(user): Implement combinedly w.r.t executeCommands_2_2
893 std::lock_guard<std::mutex> lock(mCommandMutex);
894
895 bool outChanged = false;
896 uint32_t outLength = 0;
897 hidl_vec<hidl_handle> outHandles;
898
899 if (!mReader.readQueue(inLength, inHandles)) {
900 _hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
901 return Void();
902 }
903
904 Error err = mReader.parse();
905 if (err == Error::NONE &&
906 !mWriter.writeQueue(outChanged, outLength, outHandles)) {
907 err = Error::NO_RESOURCES;
908 }
909
910 _hidl_cb(Error::NONE, outChanged, outLength, outHandles);
911
912 mReader.reset();
913 mWriter.reset();
914
915 return Void();
916 }
917
getRenderIntents_2_3(uint64_t display,common_V1_2::ColorMode mode,getRenderIntents_2_3_cb _hidl_cb)918 Return<void> QtiComposerClient::getRenderIntents_2_3(uint64_t display, common_V1_2::ColorMode mode,
919 getRenderIntents_2_3_cb _hidl_cb) {
920 uint32_t count = 0;
921 std::vector<RenderIntent> intents;
922
923 auto error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count, nullptr);
924 if (error != HWC2_ERROR_NONE) {
925 _hidl_cb(static_cast<Error>(error), intents);
926 return Void();
927 }
928
929 intents.resize(count);
930 error = hwc_session_->GetRenderIntents(display, int32_t(mode), &count,
931 reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
932
933 _hidl_cb(static_cast<Error>(error), intents);
934 return Void();
935 }
936
getColorModes_2_3(uint64_t display,getColorModes_2_3_cb _hidl_cb)937 Return<void> QtiComposerClient::getColorModes_2_3(uint64_t display,
938 getColorModes_2_3_cb _hidl_cb) {
939 hidl_vec<common_V1_2::ColorMode> modes;
940 uint32_t count = 0;
941
942 auto error = hwc_session_->GetColorModes(display, &count, nullptr);
943 if (error != HWC2_ERROR_NONE) {
944 _hidl_cb(static_cast<Error>(error), modes);
945 return Void();
946 }
947
948 modes.resize(count);
949 error = hwc_session_->GetColorModes(display, &count,
950 reinterpret_cast<std::underlying_type<common_V1_2::ColorMode>::type*>(modes.data()));
951
952 _hidl_cb(static_cast<Error>(error), modes);
953 return Void();
954 }
955
setColorMode_2_3(uint64_t display,common_V1_2::ColorMode mode,common_V1_1::RenderIntent intent)956 Return<Error> QtiComposerClient::setColorMode_2_3(uint64_t display, common_V1_2::ColorMode mode,
957 common_V1_1::RenderIntent intent) {
958 auto error = hwc_session_->SetColorModeWithRenderIntent(display, static_cast<int32_t>(mode),
959 static_cast<int32_t>(intent));
960
961 return static_cast<Error>(error);
962 }
963
getDisplayCapabilities(uint64_t display,getDisplayCapabilities_cb _hidl_cb)964 Return<void> QtiComposerClient::getDisplayCapabilities(uint64_t display,
965 getDisplayCapabilities_cb _hidl_cb) {
966 hidl_vec<composer_V2_3::IComposerClient::DisplayCapability> capabilities;
967 uint32_t count = 0;
968 auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
969 if (error != HWC2_ERROR_NONE) {
970 _hidl_cb(static_cast<Error>(error), capabilities);
971 return Void();
972 }
973
974 capabilities.resize(count);
975 error = hwc_session_->GetDisplayCapabilities(
976 display, &count,
977 reinterpret_cast<std::underlying_type<composer_V2_3::IComposerClient::DisplayCapability>::type
978 *>(capabilities.data()));
979
980 _hidl_cb(static_cast<Error>(error), capabilities);
981 return Void();
982 }
983
getPerFrameMetadataKeys_2_3(uint64_t display,getPerFrameMetadataKeys_2_3_cb _hidl_cb)984 Return<void> QtiComposerClient::getPerFrameMetadataKeys_2_3(uint64_t display,
985 getPerFrameMetadataKeys_2_3_cb _hidl_cb) {
986 std::vector<PerFrameMetadataKey> keys;
987 uint32_t count = 0;
988
989 auto error = hwc_session_->GetPerFrameMetadataKeys(display, &count, nullptr);
990 if (error != HWC2_ERROR_NONE) {
991 _hidl_cb(static_cast<Error>(error), keys);
992 return Void();
993 }
994
995 keys.resize(count);
996 error = hwc_session_->GetPerFrameMetadataKeys(display, &count,
997 reinterpret_cast<std::underlying_type<PerFrameMetadataKey>::type*>(keys.data()));
998
999 _hidl_cb(static_cast<Error>(error), keys);
1000 return Void();
1001 }
1002
getHdrCapabilities_2_3(uint64_t display,getHdrCapabilities_2_3_cb _hidl_cb)1003 Return<void> QtiComposerClient::getHdrCapabilities_2_3(uint64_t display,
1004 getHdrCapabilities_2_3_cb _hidl_cb) {
1005 uint32_t count = 0;
1006 hidl_vec<common_V1_2::Hdr> types;
1007 float max_lumi = 0.0f;
1008 float max_avg_lumi = 0.0f;
1009 float min_lumi = 0.0f;
1010
1011 auto error = hwc_session_->GetHdrCapabilities(display, &count, nullptr, &max_lumi,
1012 &max_avg_lumi, &min_lumi);
1013 if (error != HWC2_ERROR_NONE) {
1014 _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
1015 return Void();
1016 }
1017
1018 types.resize(count);
1019 error = hwc_session_->GetHdrCapabilities(display, &count,
1020 reinterpret_cast<std::underlying_type<common_V1_2::Hdr>::type*>(types.data()),
1021 &max_lumi, &max_avg_lumi, &min_lumi);
1022
1023 _hidl_cb(static_cast<Error>(error), types, max_lumi, max_avg_lumi, min_lumi);
1024 return Void();
1025 }
1026
getDisplayBrightnessSupport(uint64_t display,getDisplayBrightnessSupport_cb _hidl_cb)1027 Return<void> QtiComposerClient::getDisplayBrightnessSupport(uint64_t display,
1028 getDisplayBrightnessSupport_cb _hidl_cb) {
1029 bool support = false;
1030 auto error = hwc_session_->GetDisplayBrightnessSupport(display, &support);
1031
1032 _hidl_cb(static_cast<Error>(error), support);
1033 return Void();
1034 }
1035
setDisplayBrightness(uint64_t display,float brightness)1036 Return<Error> QtiComposerClient::setDisplayBrightness(uint64_t display, float brightness) {
1037 if (std::isnan(brightness) || brightness > 1.0f || (brightness < 0.0f && brightness != -1.0f)) {
1038 return Error::BAD_PARAMETER;
1039 }
1040
1041 auto error = hwc_session_->SetDisplayBrightness(display, brightness);
1042 return static_cast<Error>(error);
1043 }
1044
1045 // Methods from ::android::hardware::graphics::composer::V2_4::IComposerClient follow.
registerCallback_2_4(const sp<composer_V2_4::IComposerCallback> & callback)1046 Return<void> QtiComposerClient::registerCallback_2_4(
1047 const sp<composer_V2_4::IComposerCallback> &callback) {
1048 callback_ = sp<composer_V2_1::IComposerCallback>(callback.get());
1049 callback24_ = callback;
1050 mUseCallback24_ = true;
1051 enableCallback(callback != nullptr);
1052 return Void();
1053 }
1054
getDisplayCapabilities_2_4(uint64_t display,getDisplayCapabilities_2_4_cb _hidl_cb)1055 Return<void> QtiComposerClient::getDisplayCapabilities_2_4(uint64_t display,
1056 getDisplayCapabilities_2_4_cb _hidl_cb) {
1057 hidl_vec<HwcDisplayCapability> capabilities;
1058 uint32_t count = 0;
1059 auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
1060 if (error != HWC2_ERROR_NONE) {
1061 _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
1062 return Void();
1063 }
1064
1065 uint32_t count_2_4 = 0;
1066 error = hwc_session_->GetDisplayCapabilities_2_4(display, &count_2_4, nullptr);
1067 if (error != HWC2_ERROR_NONE) {
1068 _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
1069 return Void();
1070 }
1071
1072 capabilities.resize(count + count_2_4);
1073 error = hwc_session_->GetDisplayCapabilities(
1074 display, &count,
1075 reinterpret_cast<std::underlying_type<HwcDisplayCapability>::type *>(capabilities.data()));
1076 if (error != HWC2_ERROR_NONE) {
1077 _hidl_cb(static_cast<composer_V2_4::Error>(error), {});
1078 return Void();
1079 }
1080
1081 error = hwc_session_->GetDisplayCapabilities_2_4(
1082 display, &count_2_4,
1083 reinterpret_cast<std::underlying_type<HwcDisplayCapability>::type *>(capabilities.data() +
1084 count));
1085 if (error != HWC2_ERROR_NONE) {
1086 _hidl_cb(static_cast<composer_V2_4::Error>(error), {});
1087 return Void();
1088 }
1089
1090 _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
1091 return Void();
1092 }
1093
getDisplayConnectionType(uint64_t display,getDisplayConnectionType_cb _hidl_cb)1094 Return<void> QtiComposerClient::getDisplayConnectionType(uint64_t display,
1095 getDisplayConnectionType_cb _hidl_cb) {
1096 HwcDisplayConnectionType type;
1097 auto error = hwc_session_->GetDisplayConnectionType(display, &type);
1098 _hidl_cb(static_cast<composer_V2_4::Error>(error), type);
1099 return Void();
1100 }
1101
getDisplayAttribute_2_4(uint64_t display,uint32_t config,composer_V2_4::IComposerClient::Attribute attribute,getDisplayAttribute_2_4_cb _hidl_cb)1102 Return<void> QtiComposerClient::getDisplayAttribute_2_4(
1103 uint64_t display, uint32_t config, composer_V2_4::IComposerClient::Attribute attribute,
1104 getDisplayAttribute_2_4_cb _hidl_cb) {
1105 int32_t value = 0;
1106 auto error = hwc_session_->GetDisplayAttribute(display, config, attribute, &value);
1107 _hidl_cb(static_cast<composer_V2_4::Error>(error), value);
1108 return Void();
1109 }
1110
getDisplayVsyncPeriod(uint64_t display,getDisplayVsyncPeriod_cb _hidl_cb)1111 Return<void> QtiComposerClient::getDisplayVsyncPeriod(uint64_t display,
1112 getDisplayVsyncPeriod_cb _hidl_cb) {
1113 VsyncPeriodNanos vsync_period;
1114 auto error = hwc_session_->GetDisplayVsyncPeriod(display, &vsync_period);
1115 _hidl_cb(static_cast<composer_V2_4::Error>(error), vsync_period);
1116 return Void();
1117 }
1118
setActiveConfigWithConstraints(uint64_t display,uint32_t config,const VsyncPeriodChangeConstraints & vsyncPeriodChangeConstraints,setActiveConfigWithConstraints_cb _hidl_cb)1119 Return<void> QtiComposerClient::setActiveConfigWithConstraints(
1120 uint64_t display, uint32_t config,
1121 const VsyncPeriodChangeConstraints &vsyncPeriodChangeConstraints,
1122 setActiveConfigWithConstraints_cb _hidl_cb) {
1123 VsyncPeriodChangeTimeline timeline;
1124 timeline.newVsyncAppliedTimeNanos = systemTime();
1125 timeline.refreshRequired = false;
1126 timeline.refreshTimeNanos = 0;
1127
1128 auto error = hwc_session_->SetActiveConfigWithConstraints(
1129 display, config, &vsyncPeriodChangeConstraints, &timeline);
1130 _hidl_cb(static_cast<composer_V2_4::Error>(error), timeline);
1131 return Void();
1132 }
1133
setAutoLowLatencyMode(uint64_t display,bool on)1134 Return<composer_V2_4::Error> QtiComposerClient::setAutoLowLatencyMode(uint64_t display, bool on) {
1135 if (mDisplayData.find(display) == mDisplayData.end()) {
1136 return composer_V2_4::Error::BAD_DISPLAY;
1137 }
1138
1139 auto error = hwc_session_->SetAutoLowLatencyMode(display, on);
1140
1141 return static_cast<composer_V2_4::Error>(error);
1142 }
1143
getSupportedContentTypes(uint64_t display,getSupportedContentTypes_cb _hidl_cb)1144 Return<void> QtiComposerClient::getSupportedContentTypes(uint64_t display,
1145 getSupportedContentTypes_cb _hidl_cb) {
1146 hidl_vec<composer_V2_4::IComposerClient::ContentType> types;
1147 if (mDisplayData.find(display) == mDisplayData.end()) {
1148 _hidl_cb(composer_V2_4::Error::BAD_DISPLAY, types);
1149 return Void();
1150 }
1151 auto error = hwc_session_->GetSupportedContentTypes(display, &types);
1152 _hidl_cb(static_cast<composer_V2_4::Error>(error), types);
1153 return Void();
1154 }
1155
setContentType(uint64_t display,composer_V2_4::IComposerClient::ContentType type)1156 Return<composer_V2_4::Error> QtiComposerClient::setContentType(
1157 uint64_t display, composer_V2_4::IComposerClient::ContentType type) {
1158 if (mDisplayData.find(display) == mDisplayData.end()) {
1159 return composer_V2_4::Error::BAD_DISPLAY;
1160 }
1161 if (type == composer_V2_4::IComposerClient::ContentType::NONE) {
1162 return composer_V2_4::Error::NONE;
1163 }
1164 auto error = hwc_session_->SetContentType(display, type);
1165
1166 return static_cast<composer_V2_4::Error>(error);
1167 }
1168
getLayerGenericMetadataKeys(getLayerGenericMetadataKeys_cb _hidl_cb)1169 Return<void> QtiComposerClient::getLayerGenericMetadataKeys(
1170 getLayerGenericMetadataKeys_cb _hidl_cb) {
1171 hidl_vec<composer_V2_4::IComposerClient::LayerGenericMetadataKey> keys = {};
1172 _hidl_cb(composer_V2_4::Error::NONE, keys);
1173 return Void();
1174 }
1175
CommandReader(QtiComposerClient & client)1176 QtiComposerClient::CommandReader::CommandReader(QtiComposerClient& client)
1177 : mClient(client), mWriter(client.mWriter) {
1178 }
1179
parseCommonCmd(IComposerClient::Command command,uint16_t length)1180 bool QtiComposerClient::CommandReader::parseCommonCmd(
1181 IComposerClient::Command command, uint16_t length) {
1182 bool parsed = false;
1183
1184 switch (command) {
1185 // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
1186 case IComposerClient::Command::SELECT_DISPLAY:
1187 parsed = parseSelectDisplay(length);
1188 // Displays will not be removed while processing the command queue.
1189 if (parsed && mClient.mDisplayData.find(mDisplay) == mClient.mDisplayData.end()) {
1190 ALOGW("Command::SELECT_DISPLAY: Display %" PRId64 "not found. Dropping commands.", mDisplay);
1191 mDisplay = sdm::HWCCallbacks::kNumDisplays;
1192 }
1193 break;
1194 case IComposerClient::Command::SELECT_LAYER:
1195 parsed = parseSelectLayer(length);
1196 break;
1197 case IComposerClient::Command::SET_COLOR_TRANSFORM:
1198 parsed = parseSetColorTransform(length);
1199 break;
1200 case IComposerClient::Command::SET_CLIENT_TARGET:
1201 parsed = parseSetClientTarget(length);
1202 break;
1203 case IComposerClient::Command::SET_OUTPUT_BUFFER:
1204 parsed = parseSetOutputBuffer(length);
1205 break;
1206 case IComposerClient::Command::VALIDATE_DISPLAY:
1207 parsed = parseValidateDisplay(length);
1208 break;
1209 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
1210 parsed = parseAcceptDisplayChanges(length);
1211 break;
1212 case IComposerClient::Command::PRESENT_DISPLAY:
1213 parsed = parsePresentDisplay(length);
1214 break;
1215 case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
1216 parsed = parsePresentOrValidateDisplay(length);
1217 break;
1218 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
1219 parsed = parseSetLayerCursorPosition(length);
1220 break;
1221 case IComposerClient::Command::SET_LAYER_BUFFER:
1222 parsed = parseSetLayerBuffer(length);
1223 break;
1224 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
1225 parsed = parseSetLayerSurfaceDamage(length);
1226 break;
1227 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
1228 parsed = parseSetLayerBlendMode(length);
1229 break;
1230 case IComposerClient::Command::SET_LAYER_COLOR:
1231 parsed = parseSetLayerColor(length);
1232 break;
1233 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
1234 parsed = parseSetLayerCompositionType(length);
1235 break;
1236 case IComposerClient::Command::SET_LAYER_DATASPACE:
1237 parsed = parseSetLayerDataspace(length);
1238 break;
1239 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
1240 parsed = parseSetLayerDisplayFrame(length);
1241 break;
1242 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
1243 parsed = parseSetLayerPlaneAlpha(length);
1244 break;
1245 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
1246 parsed = parseSetLayerSidebandStream(length);
1247 break;
1248 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
1249 parsed = parseSetLayerSourceCrop(length);
1250 break;
1251 case IComposerClient::Command::SET_LAYER_TRANSFORM:
1252 parsed = parseSetLayerTransform(length);
1253 break;
1254 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
1255 parsed = parseSetLayerVisibleRegion(length);
1256 break;
1257 case IComposerClient::Command::SET_LAYER_Z_ORDER:
1258 parsed = parseSetLayerZOrder(length);
1259 break;
1260 // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
1261 case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA:
1262 parsed = parseSetLayerPerFrameMetadata(length);
1263 break;
1264 case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
1265 parsed = parseSetLayerFloatColor(length);
1266 break;
1267 // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
1268 case IComposerClient::Command::SET_LAYER_COLOR_TRANSFORM:
1269 parsed = parseSetLayerColorTransform(length);
1270 break;
1271 case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS:
1272 parsed = parseSetLayerPerFrameMetadataBlobs(length);
1273 break;
1274 default:
1275 parsed = false;
1276 break;
1277 }
1278
1279 return parsed;
1280 }
1281
parse()1282 Error QtiComposerClient::CommandReader::parse() {
1283 IQtiComposerClient::Command qticommand;
1284 uint16_t length;
1285
1286 while (!isEmpty()) {
1287 if (!beginCommand(qticommand, length)) {
1288 break;
1289 }
1290
1291 bool parsed = false;
1292 switch (qticommand) {
1293 case IQtiComposerClient::Command::SET_LAYER_TYPE:
1294 parsed = parseSetLayerType(length);
1295 break;
1296 case IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME:
1297 parsed = parseSetDisplayElapseTime(length);
1298 break;
1299 default:
1300 parsed = parseCommonCmd(static_cast<IComposerClient::Command>(qticommand), length);
1301 break;
1302 }
1303
1304 endCommand();
1305
1306 if (!parsed) {
1307 ALOGE("failed to parse command 0x%x, length %" PRIu16,
1308 qticommand, length);
1309 break;
1310 }
1311 }
1312
1313 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
1314 }
1315
parseSelectDisplay(uint16_t length)1316 bool QtiComposerClient::CommandReader::parseSelectDisplay(uint16_t length) {
1317 if (length != CommandWriter::kSelectDisplayLength) {
1318 return false;
1319 }
1320
1321 mDisplay = read64();
1322 mWriter.selectDisplay(mDisplay);
1323
1324 return true;
1325 }
1326
parseSelectLayer(uint16_t length)1327 bool QtiComposerClient::CommandReader::parseSelectLayer(uint16_t length) {
1328 if (length != CommandWriter::kSelectLayerLength) {
1329 return false;
1330 }
1331
1332 mLayer = read64();
1333
1334 return true;
1335 }
1336
parseSetColorTransform(uint16_t length)1337 bool QtiComposerClient::CommandReader::parseSetColorTransform(uint16_t length) {
1338 if (length != CommandWriter::kSetColorTransformLength) {
1339 return false;
1340 }
1341
1342 float matrix[16];
1343 for (int i = 0; i < 16; i++) {
1344 matrix[i] = readFloat();
1345 }
1346 auto transform = readSigned();
1347
1348 auto err = mClient.hwc_session_->SetColorTransform(mDisplay, matrix, transform);
1349 if (static_cast<Error>(err) != Error::NONE) {
1350 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1351 }
1352
1353 return true;
1354 }
1355
parseSetClientTarget(uint16_t length)1356 bool QtiComposerClient::CommandReader::parseSetClientTarget(uint16_t length) {
1357 // 4 parameters followed by N rectangles
1358 if ((length - 4) % 4 != 0) {
1359 return false;
1360 }
1361
1362 bool useCache = false;
1363 auto slot = read();
1364 auto clientTarget = readHandle(useCache);
1365 shared_ptr<Fence> fence = nullptr;
1366 readFence(&fence, "fbt");
1367 auto dataspace = readSigned();
1368 auto damage = readRegion((length - 4) / 4);
1369 hwc_region region = {damage.size(), damage.data()};
1370 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS, slot, useCache, clientTarget, &clientTarget);
1371 if (err == Error::NONE) {
1372 auto error = mClient.hwc_session_->SetClientTarget(mDisplay, clientTarget, fence,
1373 dataspace, region);
1374 err = static_cast<Error>(error);
1375 auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
1376 useCache, clientTarget);
1377 if (err == Error::NONE) {
1378 err = updateBufErr;
1379 }
1380 }
1381 if (err != Error::NONE) {
1382 mWriter.setError(getCommandLoc(), err);
1383 }
1384
1385 return true;
1386 }
1387
parseSetOutputBuffer(uint16_t length)1388 bool QtiComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length) {
1389 if (length != CommandWriter::kSetOutputBufferLength) {
1390 return false;
1391 }
1392
1393 bool useCache;
1394 auto slot = read();
1395 auto outputBuffer = readHandle(useCache);
1396 shared_ptr<Fence> fence = nullptr;
1397 readFence(&fence, "outbuf");
1398 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS, slot, useCache, outputBuffer, &outputBuffer);
1399 if (err == Error::NONE) {
1400 auto error = mClient.hwc_session_->SetOutputBuffer(mDisplay, outputBuffer, fence);
1401 err = static_cast<Error>(error);
1402 auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS, slot, useCache, outputBuffer);
1403 if (err == Error::NONE) {
1404 err = updateBufErr;
1405 }
1406 }
1407
1408 if (err != Error::NONE) {
1409 mWriter.setError(getCommandLoc(), err);
1410 }
1411
1412 return true;
1413 }
1414
validateDisplay(Display display,std::vector<Layer> & changedLayers,std::vector<IComposerClient::Composition> & compositionTypes,uint32_t & displayRequestMask,std::vector<Layer> & requestedLayers,std::vector<uint32_t> & requestMasks,IComposerClient::ClientTargetProperty & clientTargetProperty)1415 Error QtiComposerClient::CommandReader::validateDisplay(Display display,
1416 std::vector<Layer>& changedLayers,
1417 std::vector<IComposerClient::Composition>& compositionTypes,
1418 uint32_t& displayRequestMask,
1419 std::vector<Layer>& requestedLayers,
1420 std::vector<uint32_t>& requestMasks,
1421 IComposerClient::ClientTargetProperty& clientTargetProperty) {
1422 uint32_t types_count = 0;
1423 uint32_t reqs_count = 0;
1424
1425 auto err = mClient.hwc_session_->ValidateDisplay(mDisplay, &types_count, &reqs_count);
1426 if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
1427 return static_cast<Error>(err);
1428 }
1429
1430 err = mClient.hwc_session_->GetChangedCompositionTypes(mDisplay, &types_count, nullptr, nullptr);
1431 if (err != HWC2_ERROR_NONE) {
1432 return static_cast<Error>(err);
1433 }
1434
1435 changedLayers.resize(types_count);
1436 compositionTypes.resize(types_count);
1437 err = mClient.hwc_session_->GetChangedCompositionTypes(mDisplay, &types_count,
1438 changedLayers.data(),
1439 reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>(
1440 compositionTypes.data()));
1441
1442 if (err != HWC2_ERROR_NONE) {
1443 changedLayers.clear();
1444 compositionTypes.clear();
1445 return static_cast<Error>(err);
1446 }
1447
1448 int32_t display_reqs = 0;
1449 err = mClient.hwc_session_->GetDisplayRequests(mDisplay, &display_reqs, &reqs_count, nullptr,
1450 nullptr);
1451 if (err != HWC2_ERROR_NONE) {
1452 changedLayers.clear();
1453 compositionTypes.clear();
1454 return static_cast<Error>(err);
1455 }
1456
1457 requestedLayers.resize(reqs_count);
1458 requestMasks.resize(reqs_count);
1459 err = mClient.hwc_session_->GetDisplayRequests(mDisplay, &display_reqs, &reqs_count,
1460 requestedLayers.data(),
1461 reinterpret_cast<int32_t*>(requestMasks.data()));
1462 if (err != HWC2_ERROR_NONE) {
1463 changedLayers.clear();
1464 compositionTypes.clear();
1465
1466 requestedLayers.clear();
1467 requestMasks.clear();
1468 return static_cast<Error>(err);
1469 }
1470
1471 displayRequestMask = display_reqs;
1472
1473 err = mClient.hwc_session_->GetClientTargetProperty(mDisplay, &clientTargetProperty);
1474 if (err != HWC2_ERROR_NONE) {
1475 // todo: reset to default values
1476 return static_cast<Error>(err);
1477 }
1478
1479 return static_cast<Error>(err);
1480 }
1481
parseValidateDisplay(uint16_t length)1482 bool QtiComposerClient::CommandReader::parseValidateDisplay(uint16_t length) {
1483 if (length != CommandWriter::kValidateDisplayLength) {
1484 return false;
1485 }
1486
1487 std::vector<Layer> changedLayers;
1488 std::vector<IComposerClient::Composition> compositionTypes;
1489 uint32_t displayRequestMask;
1490 std::vector<Layer> requestedLayers;
1491 std::vector<uint32_t> requestMasks;
1492 IComposerClient::ClientTargetProperty clientTargetProperty;
1493
1494 auto err = validateDisplay(mDisplay, changedLayers, compositionTypes, displayRequestMask,
1495 requestedLayers, requestMasks, clientTargetProperty);
1496
1497 if (static_cast<Error>(err) == Error::NONE) {
1498 mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
1499 mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
1500 if (mClient.mUseCallback24_) {
1501 mWriter.setClientTargetProperty(clientTargetProperty);
1502 }
1503 } else {
1504 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1505 }
1506
1507 return true;
1508 }
1509
parseAcceptDisplayChanges(uint16_t length)1510 bool QtiComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length) {
1511 if (length != CommandWriter::kAcceptDisplayChangesLength) {
1512 return false;
1513 }
1514
1515 auto err = mClient.hwc_session_->AcceptDisplayChanges(mDisplay);
1516 if (static_cast<Error>(err) != Error::NONE) {
1517 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1518 }
1519
1520 return true;
1521 }
1522
presentDisplay(Display display,shared_ptr<Fence> * presentFence,std::vector<Layer> & layers,std::vector<shared_ptr<Fence>> & releaseFences)1523 Error QtiComposerClient::CommandReader::presentDisplay(Display display,
1524 shared_ptr<Fence>* presentFence,
1525 std::vector<Layer>& layers,
1526 std::vector<shared_ptr<Fence>>& releaseFences) {
1527 int32_t err = mClient.hwc_session_->PresentDisplay(display, presentFence);
1528 if (err != HWC2_ERROR_NONE) {
1529 return static_cast<Error>(err);
1530 }
1531
1532 uint32_t count = 0;
1533 err = mClient.hwc_session_->GetReleaseFences(display, &count, nullptr, nullptr);
1534 if (err != HWC2_ERROR_NONE) {
1535 ALOGW("failed to get release fences");
1536 return Error::NONE;
1537 }
1538
1539 layers.resize(count);
1540 releaseFences.resize(count);
1541 err = mClient.hwc_session_->GetReleaseFences(display, &count, layers.data(), &releaseFences);
1542 if (err != HWC2_ERROR_NONE) {
1543 ALOGW("failed to get release fences");
1544 layers.clear();
1545 releaseFences.clear();
1546 return Error::NONE;
1547 }
1548
1549 return static_cast<Error>(err);
1550 }
1551
parsePresentDisplay(uint16_t length)1552 bool QtiComposerClient::CommandReader::parsePresentDisplay(uint16_t length) {
1553 if (length != CommandWriter::kPresentDisplayLength) {
1554 return false;
1555 }
1556
1557 shared_ptr<Fence> presentFence = nullptr;
1558 std::vector<Layer> layers;
1559 std::vector<shared_ptr<Fence>> fences;
1560
1561 auto err = presentDisplay(mDisplay, &presentFence, layers, fences);
1562 if (err == Error::NONE) {
1563 mWriter.setPresentFence(presentFence);
1564 mWriter.setReleaseFences(layers, fences);
1565 } else {
1566 mWriter.setError(getCommandLoc(), err);
1567 }
1568
1569 return true;
1570 }
1571
parsePresentOrValidateDisplay(uint16_t length)1572 bool QtiComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length) {
1573 if (length != CommandWriter::kPresentOrValidateDisplayLength) {
1574 return false;
1575 }
1576
1577 // First try to Present as is.
1578 mClient.getCapabilities();
1579 if (mClient.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
1580 shared_ptr<Fence> presentFence = nullptr;
1581 std::vector<Layer> layers;
1582 std::vector<shared_ptr<Fence>> fences;
1583 auto err = presentDisplay(mDisplay, &presentFence, layers, fences);
1584 if (err == Error::NONE) {
1585 mWriter.setPresentOrValidateResult(1);
1586 mWriter.setPresentFence(presentFence);
1587 mWriter.setReleaseFences(layers, fences);
1588 return true;
1589 }
1590 }
1591
1592 // Present has failed. We need to fallback to validate
1593 std::vector<Layer> changedLayers;
1594 std::vector<IComposerClient::Composition> compositionTypes;
1595 uint32_t displayRequestMask = 0x0;
1596 std::vector<Layer> requestedLayers;
1597 std::vector<uint32_t> requestMasks;
1598 IComposerClient::ClientTargetProperty clientTargetProperty;
1599
1600 auto err = validateDisplay(mDisplay, changedLayers, compositionTypes, displayRequestMask,
1601 requestedLayers, requestMasks, clientTargetProperty);
1602 // mResources->setDisplayMustValidateState(mDisplay, false);
1603 if (err == Error::NONE) {
1604 mWriter.setPresentOrValidateResult(0);
1605 mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
1606 mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
1607 if (mClient.mUseCallback24_) {
1608 mWriter.setClientTargetProperty(clientTargetProperty);
1609 }
1610 } else {
1611 mWriter.setError(getCommandLoc(), err);
1612 }
1613
1614 return true;
1615 }
1616
parseSetLayerCursorPosition(uint16_t length)1617 bool QtiComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length) {
1618 if (length != CommandWriter::kSetLayerCursorPositionLength) {
1619 return false;
1620 }
1621
1622 auto err = mClient.hwc_session_->SetCursorPosition(mDisplay, mLayer, readSigned(), readSigned());
1623 if (static_cast<Error>(err) != Error::NONE) {
1624 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1625 }
1626
1627 return true;
1628 }
1629
parseSetLayerBuffer(uint16_t length)1630 bool QtiComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length) {
1631 if (length != CommandWriter::kSetLayerBufferLength) {
1632 return false;
1633 }
1634
1635 bool useCache;
1636 auto slot = read();
1637 auto buffer = readHandle(useCache);
1638 shared_ptr<Fence> fence = nullptr;
1639 readFence(&fence, "layer");
1640 auto error = lookupBuffer(BufferCache::LAYER_BUFFERS, slot, useCache, buffer, &buffer);
1641 if (error == Error::NONE) {
1642 auto err = mClient.hwc_session_->SetLayerBuffer(mDisplay, mLayer, buffer, fence);
1643 error = static_cast<Error>(err);
1644 auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot, useCache, buffer);
1645 if (static_cast<Error>(error) == Error::NONE) {
1646 error = updateBufErr;
1647 }
1648 }
1649 if (static_cast<Error>(error) != Error::NONE) {
1650 mWriter.setError(getCommandLoc(), static_cast<Error>(error));
1651 }
1652
1653 return true;
1654 }
1655
parseSetLayerSurfaceDamage(uint16_t length)1656 bool QtiComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length) {
1657 // N rectangles
1658 if (length % 4 != 0) {
1659 return false;
1660 }
1661
1662 auto damage = readRegion(length / 4);
1663 hwc_region region = {damage.size(), damage.data()};
1664 auto err = mClient.hwc_session_->SetLayerSurfaceDamage(mDisplay, mLayer, region);
1665 if (static_cast<Error>(err) != Error::NONE) {
1666 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1667 }
1668
1669 return true;
1670 }
1671
parseSetLayerBlendMode(uint16_t length)1672 bool QtiComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length) {
1673 if (length != CommandWriter::kSetLayerBlendModeLength) {
1674 return false;
1675 }
1676
1677 auto err = mClient.hwc_session_->SetLayerBlendMode(mDisplay, mLayer, readSigned());
1678 if (static_cast<Error>(err) != Error::NONE) {
1679 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1680 }
1681
1682 return true;
1683 }
1684
parseSetLayerColor(uint16_t length)1685 bool QtiComposerClient::CommandReader::parseSetLayerColor(uint16_t length) {
1686 if (length != CommandWriter::kSetLayerColorLength) {
1687 return false;
1688 }
1689 auto color = readColor();
1690 hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
1691 auto err = mClient.hwc_session_->SetLayerColor(mDisplay, mLayer, hwc_color);
1692 if (static_cast<Error>(err) != Error::NONE) {
1693 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1694 }
1695
1696 return true;
1697 }
1698
parseSetLayerCompositionType(uint16_t length)1699 bool QtiComposerClient::CommandReader::parseSetLayerCompositionType(uint16_t length) {
1700 if (length != CommandWriter::kSetLayerCompositionTypeLength) {
1701 return false;
1702 }
1703
1704 auto err = mClient.hwc_session_->SetLayerCompositionType(mDisplay, mLayer, readSigned());
1705 if (static_cast<Error>(err) != Error::NONE) {
1706 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1707 }
1708
1709 return true;
1710 }
1711
parseSetLayerDataspace(uint16_t length)1712 bool QtiComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length) {
1713 if (length != CommandWriter::kSetLayerDataspaceLength) {
1714 return false;
1715 }
1716
1717 auto err = mClient.hwc_session_->SetLayerDataspace(mDisplay, mLayer, readSigned());
1718 if (static_cast<Error>(err) != Error::NONE) {
1719 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1720 }
1721
1722 return true;
1723 }
1724
parseSetLayerDisplayFrame(uint16_t length)1725 bool QtiComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length) {
1726 if (length != CommandWriter::kSetLayerDisplayFrameLength) {
1727 return false;
1728 }
1729
1730 auto err = mClient.hwc_session_->SetLayerDisplayFrame(mDisplay, mLayer, readRect());
1731 if (static_cast<Error>(err) != Error::NONE) {
1732 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1733 }
1734
1735 return true;
1736 }
1737
parseSetLayerPlaneAlpha(uint16_t length)1738 bool QtiComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length) {
1739 if (length != CommandWriter::kSetLayerPlaneAlphaLength) {
1740 return false;
1741 }
1742
1743 auto err = mClient.hwc_session_->SetLayerPlaneAlpha(mDisplay, mLayer, readFloat());
1744 if (static_cast<Error>(err) != Error::NONE) {
1745 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1746 }
1747
1748 return true;
1749 }
1750
parseSetLayerSidebandStream(uint16_t length)1751 bool QtiComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length) {
1752 if (length != CommandWriter::kSetLayerSidebandStreamLength) {
1753 return false;
1754 }
1755
1756 // Sideband stream is not supported
1757 return true;
1758 }
1759
parseSetLayerSourceCrop(uint16_t length)1760 bool QtiComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length) {
1761 if (length != CommandWriter::kSetLayerSourceCropLength) {
1762 return false;
1763 }
1764
1765 auto err = mClient.hwc_session_->SetLayerSourceCrop(mDisplay, mLayer, readFRect());
1766 if (static_cast<Error>(err) != Error::NONE) {
1767 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1768 }
1769
1770 return true;
1771 }
1772
parseSetLayerTransform(uint16_t length)1773 bool QtiComposerClient::CommandReader::parseSetLayerTransform(uint16_t length) {
1774 if (length != CommandWriter::kSetLayerTransformLength) {
1775 return false;
1776 }
1777
1778 auto err = mClient.hwc_session_->SetLayerTransform(mDisplay, mLayer, readSigned());
1779 if (static_cast<Error>(err) != Error::NONE) {
1780 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1781 }
1782
1783 return true;
1784 }
1785
parseSetLayerVisibleRegion(uint16_t length)1786 bool QtiComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length) {
1787 // N rectangles
1788 if (length % 4 != 0) {
1789 return false;
1790 }
1791
1792 auto region = readRegion(length / 4);
1793 hwc_region visibleRegion = {region.size(), region.data()};
1794 auto err = mClient.hwc_session_->SetLayerVisibleRegion(mDisplay, mLayer, visibleRegion);
1795 if (static_cast<Error>(err) != Error::NONE) {
1796 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1797 }
1798
1799 return true;
1800 }
1801
parseSetLayerZOrder(uint16_t length)1802 bool QtiComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length) {
1803 if (length != CommandWriter::kSetLayerZOrderLength) {
1804 return false;
1805 }
1806
1807 auto err = mClient.hwc_session_->SetLayerZOrder(mDisplay, mLayer, read());
1808 if (static_cast<Error>(err) != Error::NONE) {
1809 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1810 }
1811
1812 return true;
1813 }
1814
parseSetLayerType(uint16_t length)1815 bool QtiComposerClient::CommandReader::parseSetLayerType(uint16_t length) {
1816 if (length != CommandWriter::kSetLayerTypeLength) {
1817 return false;
1818 }
1819
1820 auto err = mClient.hwc_session_->SetLayerType(mDisplay, mLayer,
1821 static_cast<IQtiComposerClient::LayerType>(read()));
1822 if (static_cast<Error>(err) != Error::NONE) {
1823 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1824 }
1825
1826 return true;
1827 }
1828
parseSetLayerPerFrameMetadata(uint16_t length)1829 bool QtiComposerClient::CommandReader::parseSetLayerPerFrameMetadata(uint16_t length) {
1830 // (key, value) pairs
1831 if (length % 2 != 0) {
1832 return false;
1833 }
1834
1835 std::vector<IComposerClient::PerFrameMetadata> metadata;
1836 metadata.reserve(length / 2);
1837 while (length > 0) {
1838 metadata.emplace_back(IComposerClient::PerFrameMetadata{
1839 static_cast<IComposerClient::PerFrameMetadataKey>(readSigned()),
1840 readFloat()});
1841 length -= 2;
1842 }
1843
1844 std::vector<int32_t> keys;
1845 std::vector<float> values;
1846 keys.reserve(metadata.size());
1847 values.reserve(metadata.size());
1848 for (const auto& m : metadata) {
1849 keys.push_back(static_cast<int32_t>(m.key));
1850 values.push_back(m.value);
1851 }
1852
1853 auto err = mClient.hwc_session_->SetLayerPerFrameMetadata(mDisplay, mLayer, metadata.size(),
1854 keys.data(), values.data());
1855 if (static_cast<Error>(err) != Error::NONE) {
1856 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1857 }
1858
1859 return true;
1860 }
1861
parseSetLayerFloatColor(uint16_t length)1862 bool QtiComposerClient::CommandReader::parseSetLayerFloatColor(uint16_t length) {
1863 if (length != CommandWriter::kSetLayerFloatColorLength) {
1864 return false;
1865 }
1866
1867 // setLayerFloatColor is not supported
1868 auto err = Error::UNSUPPORTED;
1869 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1870
1871 return true;
1872 }
1873
parseSetLayerColorTransform(uint16_t length)1874 bool QtiComposerClient::CommandReader::parseSetLayerColorTransform(uint16_t length) {
1875 if (length != CommandWriter::kSetLayerColorTransformLength) {
1876 return false;
1877 }
1878
1879 float matrix[16];
1880 for (int i = 0; i < 16; i++) {
1881 matrix[i] = readFloat();
1882 }
1883
1884 auto error = mClient.hwc_session_->SetLayerColorTransform(mDisplay, mLayer, matrix);
1885 if (static_cast<Error>(error) != Error::NONE) {
1886 mWriter.setError(getCommandLoc(), static_cast<Error>(error));
1887 }
1888
1889 return true;
1890 }
1891
parseSetLayerPerFrameMetadataBlobs(uint16_t length)1892 bool QtiComposerClient::CommandReader::parseSetLayerPerFrameMetadataBlobs(uint16_t length) {
1893 // must have at least one metadata blob
1894 // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
1895 if (length < 4) {
1896 return false;
1897 }
1898
1899 uint32_t numBlobs = read();
1900 length--;
1901 std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
1902
1903 for (size_t i = 0; i < numBlobs; i++) {
1904 IComposerClient::PerFrameMetadataKey key =
1905 static_cast<IComposerClient::PerFrameMetadataKey>(readSigned());
1906 uint32_t blobSize = read();
1907 length -= 2;
1908
1909 if (length * sizeof(uint32_t) < blobSize) {
1910 return false;
1911 }
1912
1913 metadata.push_back({key, std::vector<uint8_t>()});
1914 IComposerClient::PerFrameMetadataBlob& metadataBlob = metadata.back();
1915 metadataBlob.blob.resize(blobSize);
1916 readBlob(blobSize, metadataBlob.blob.data());
1917 }
1918
1919 std::vector<int32_t> keys;
1920 std::vector<uint32_t> sizes_of_metablob_;
1921 std::vector<uint8_t> blob_of_data_;
1922 keys.reserve(metadata.size());
1923 sizes_of_metablob_.reserve(metadata.size());
1924 for (const auto& m : metadata) {
1925 keys.push_back(static_cast<int32_t>(m.key));
1926 sizes_of_metablob_.push_back(m.blob.size());
1927 for (size_t i = 0; i < m.blob.size(); i++) {
1928 blob_of_data_.push_back(m.blob[i]);
1929 }
1930 }
1931 auto err = mClient.hwc_session_->SetLayerPerFrameMetadataBlobs(mDisplay, mLayer, metadata.size(),
1932 keys.data(),
1933 sizes_of_metablob_.data(),
1934 blob_of_data_.data());
1935 if (static_cast<Error>(err) != Error::NONE) {
1936 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1937 }
1938 return true;
1939 }
1940
parseSetDisplayElapseTime(uint16_t length)1941 bool QtiComposerClient::CommandReader::parseSetDisplayElapseTime(uint16_t length) {
1942 if (length < CommandWriter::kSetDisplayElapseTime) {
1943 return false;
1944 }
1945 uint64_t time = read64();
1946
1947 auto err = mClient.hwc_session_->SetDisplayElapseTime(mDisplay, time);
1948 if (static_cast<Error>(err) != Error::NONE) {
1949 mWriter.setError(getCommandLoc(), static_cast<Error>(err));
1950 }
1951
1952 return true;
1953 }
1954
readRect()1955 hwc_rect_t QtiComposerClient::CommandReader::readRect() {
1956 return hwc_rect_t{
1957 readSigned(),
1958 readSigned(),
1959 readSigned(),
1960 readSigned(),
1961 };
1962 }
1963
readRegion(size_t count)1964 std::vector<hwc_rect_t> QtiComposerClient::CommandReader::readRegion(size_t count) {
1965 std::vector<hwc_rect_t> region;
1966 region.reserve(count);
1967 while (count > 0) {
1968 region.emplace_back(readRect());
1969 count--;
1970 }
1971
1972 return region;
1973 }
1974
readFRect()1975 hwc_frect_t QtiComposerClient::CommandReader::readFRect() {
1976 return hwc_frect_t{
1977 readFloat(),
1978 readFloat(),
1979 readFloat(),
1980 readFloat(),
1981 };
1982 }
1983
lookupBufferCacheEntryLocked(BufferCache cache,uint32_t slot,BufferCacheEntry ** outEntry)1984 Error QtiComposerClient::CommandReader::lookupBufferCacheEntryLocked(BufferCache cache,
1985 uint32_t slot,
1986 BufferCacheEntry** outEntry) {
1987 auto dpy = mClient.mDisplayData.find(mDisplay);
1988 if (dpy == mClient.mDisplayData.end()) {
1989 return Error::BAD_DISPLAY;
1990 }
1991
1992 BufferCacheEntry* entry = nullptr;
1993 switch (cache) {
1994 case BufferCache::CLIENT_TARGETS:
1995 if (slot < dpy->second.ClientTargets.size()) {
1996 entry = &dpy->second.ClientTargets[slot];
1997 }
1998 break;
1999 case BufferCache::OUTPUT_BUFFERS:
2000 if (slot < dpy->second.OutputBuffers.size()) {
2001 entry = &dpy->second.OutputBuffers[slot];
2002 }
2003 break;
2004 case BufferCache::LAYER_BUFFERS:
2005 {
2006 auto ly = dpy->second.Layers.find(mLayer);
2007 if (ly == dpy->second.Layers.end()) {
2008 return Error::BAD_LAYER;
2009 }
2010 if (slot < ly->second.Buffers.size()) {
2011 entry = &ly->second.Buffers[slot];
2012 }
2013 }
2014 break;
2015 case BufferCache::LAYER_SIDEBAND_STREAMS:
2016 {
2017 auto ly = dpy->second.Layers.find(mLayer);
2018 if (ly == dpy->second.Layers.end()) {
2019 return Error::BAD_LAYER;
2020 }
2021 if (slot == 0) {
2022 entry = &ly->second.SidebandStream;
2023 }
2024 }
2025 break;
2026 default:
2027 break;
2028 }
2029
2030 if (!entry) {
2031 ALOGW("invalid buffer slot %" PRIu32, slot);
2032 return Error::BAD_PARAMETER;
2033 }
2034
2035 *outEntry = entry;
2036
2037 return Error::NONE;
2038 }
2039
lookupBuffer(BufferCache cache,uint32_t slot,bool useCache,buffer_handle_t handle,buffer_handle_t * outHandle)2040 Error QtiComposerClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
2041 bool useCache, buffer_handle_t handle,
2042 buffer_handle_t* outHandle) {
2043 if (useCache) {
2044 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
2045
2046 BufferCacheEntry* entry;
2047 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
2048 if (error != Error::NONE) {
2049 return error;
2050 }
2051
2052 // input handle is ignored
2053 *outHandle = entry->getHandle();
2054 } else if (cache == BufferCache::LAYER_SIDEBAND_STREAMS) {
2055 if (handle) {
2056 *outHandle = native_handle_clone(handle);
2057 if (*outHandle == nullptr) {
2058 return Error::NO_RESOURCES;
2059 }
2060 }
2061 } else {
2062 if (!mHandleImporter.importBuffer(handle)) {
2063 return Error::NO_RESOURCES;
2064 }
2065
2066 *outHandle = handle;
2067 }
2068
2069 return Error::NONE;
2070 }
2071
updateBuffer(BufferCache cache,uint32_t slot,bool useCache,buffer_handle_t handle)2072 Error QtiComposerClient::CommandReader::updateBuffer(BufferCache cache, uint32_t slot,
2073 bool useCache, buffer_handle_t handle) {
2074 // handle was looked up from cache
2075 if (useCache) {
2076 return Error::NONE;
2077 }
2078
2079 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
2080
2081 BufferCacheEntry* entry = nullptr;
2082 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
2083 if (error != Error::NONE) {
2084 return error;
2085 }
2086
2087 *entry = handle;
2088 return Error::NONE;
2089 }
2090 // Methods from ::android::hidl::base::V1_0::IBase follow.
2091
HIDL_FETCH_IQtiComposerClient(const char *)2092 IQtiComposerClient* HIDL_FETCH_IQtiComposerClient(const char* /* name */) {
2093 return QtiComposerClient::CreateQtiComposerClientInstance();
2094 }
2095
2096 } // namespace implementation
2097 } // namespace V3_0
2098 } // namespace composer
2099 } // namespace display
2100 } // namespace hardware
2101 } // namespace qti
2102 } // namespace vendor
2103