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