blob: 7f47a2ecd4a87abf01b6be96202c04e2612525a4 [file] [log] [blame]
Chia-I Wuaab99f52016-10-05 12:59:58 +08001/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#undef LOG_TAG
18#define LOG_TAG "HwcComposer"
19
20#include <inttypes.h>
21#include <log/log.h>
22
23#include "ComposerHal.h"
24
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -070025#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
26#include <gui/BufferQueue.h>
Wei Wangae211b42019-06-07 17:22:49 -070027#include <hidl/HidlTransportSupport.h>
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -070028#include <hidl/HidlTransportUtils.h>
29
Chia-I Wuaab99f52016-10-05 12:59:58 +080030namespace android {
31
32using hardware::Return;
33using hardware::hidl_vec;
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010034using hardware::hidl_handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080035
36namespace Hwc2 {
37
Lloyd Piquea822d522017-12-20 16:42:57 -080038Composer::~Composer() = default;
39
Chia-I Wuaab99f52016-10-05 12:59:58 +080040namespace {
41
42class BufferHandle {
43public:
Chih-Hung Hsieh22749042018-12-20 15:50:39 -080044 explicit BufferHandle(const native_handle_t* buffer) {
Chia-I Wuaab99f52016-10-05 12:59:58 +080045 // nullptr is not a valid handle to HIDL
46 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
47 }
48
Chih-Hung Hsieh22749042018-12-20 15:50:39 -080049 operator const hidl_handle&() const // NOLINT(google-explicit-constructor)
Chia-I Wuaab99f52016-10-05 12:59:58 +080050 {
51 return mHandle;
52 }
53
54private:
55 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010056 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080057};
58
59class FenceHandle
60{
61public:
62 FenceHandle(int fd, bool owned)
63 : mOwned(owned)
64 {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010065 native_handle_t* handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080066 if (fd >= 0) {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010067 handle = native_handle_init(mStorage, 1, 0);
68 handle->data[0] = fd;
Chia-I Wuaab99f52016-10-05 12:59:58 +080069 } else {
70 // nullptr is not a valid handle to HIDL
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010071 handle = native_handle_init(mStorage, 0, 0);
Chia-I Wuaab99f52016-10-05 12:59:58 +080072 }
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010073 mHandle = handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080074 }
75
76 ~FenceHandle()
77 {
78 if (mOwned) {
79 native_handle_close(mHandle);
80 }
81 }
82
Chih-Hung Hsieh22749042018-12-20 15:50:39 -080083 operator const hidl_handle&() const // NOLINT(google-explicit-constructor)
Chia-I Wuaab99f52016-10-05 12:59:58 +080084 {
85 return mHandle;
86 }
87
88private:
89 bool mOwned;
90 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010091 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080092};
93
94// assume NO_RESOURCES when Status::isOk returns false
95constexpr Error kDefaultError = Error::NO_RESOURCES;
96
97template<typename T, typename U>
98T unwrapRet(Return<T>& ret, const U& default_val)
99{
Steven Moreland9d021002017-01-03 17:10:54 -0800100 return (ret.isOk()) ? static_cast<T>(ret) :
Chia-I Wuaab99f52016-10-05 12:59:58 +0800101 static_cast<T>(default_val);
102}
103
104Error unwrapRet(Return<Error>& ret)
105{
106 return unwrapRet(ret, kDefaultError);
107}
108
Chia-I Wuaab99f52016-10-05 12:59:58 +0800109} // anonymous namespace
110
Lloyd Piquea822d522017-12-20 16:42:57 -0800111namespace impl {
112
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500113Composer::CommandWriter::CommandWriter(uint32_t initialMaxSize)
114 : CommandWriterBase(initialMaxSize) {}
115
116Composer::CommandWriter::~CommandWriter()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800117{
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500118}
119
120void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
121{
122 constexpr uint16_t kSetLayerInfoLength = 2;
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700123 beginCommand(static_cast<V2_1::IComposerClient::Command>(
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700124 IVrComposerClient::VrCommand::SET_LAYER_INFO),
125 kSetLayerInfoLength);
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500126 write(type);
127 write(appId);
128 endCommand();
129}
130
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400131void Composer::CommandWriter::setClientTargetMetadata(
132 const IVrComposerClient::BufferMetadata& metadata)
133{
134 constexpr uint16_t kSetClientTargetMetadataLength = 7;
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700135 beginCommand(static_cast<V2_1::IComposerClient::Command>(
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700136 IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
137 kSetClientTargetMetadataLength);
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400138 writeBufferMetadata(metadata);
139 endCommand();
140}
141
142void Composer::CommandWriter::setLayerBufferMetadata(
143 const IVrComposerClient::BufferMetadata& metadata)
144{
145 constexpr uint16_t kSetLayerBufferMetadataLength = 7;
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700146 beginCommand(static_cast<V2_1::IComposerClient::Command>(
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700147 IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
148 kSetLayerBufferMetadataLength);
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400149 writeBufferMetadata(metadata);
150 endCommand();
151}
152
153void Composer::CommandWriter::writeBufferMetadata(
154 const IVrComposerClient::BufferMetadata& metadata)
155{
156 write(metadata.width);
157 write(metadata.height);
158 write(metadata.stride);
159 write(metadata.layerCount);
160 writeSigned(static_cast<int32_t>(metadata.format));
161 write64(metadata.usage);
162}
163
Kalle Raitaa099a242017-01-11 11:17:29 -0800164Composer::Composer(const std::string& serviceName)
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800165 : mWriter(kWriterInitialSize),
Kalle Raitaa099a242017-01-11 11:17:29 -0800166 mIsUsingVrComposer(serviceName == std::string("vr"))
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500167{
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700168 mComposer = V2_1::IComposer::getService(serviceName);
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500169
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800170 if (mComposer == nullptr) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800171 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
172 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800173
Dominik Laskowskie9ef7c42018-03-12 19:34:30 -0700174 if (sp<IComposer> composer_2_3 = IComposer::castFrom(mComposer)) {
175 composer_2_3->createClient_2_3([&](const auto& tmpError, const auto& tmpClient) {
176 if (tmpError == Error::NONE) {
177 mClient = tmpClient;
178 mClient_2_2 = tmpClient;
179 mClient_2_3 = tmpClient;
180 }
181 });
182 } else {
183 mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
184 if (tmpError != Error::NONE) {
185 return;
186 }
187
188 mClient = tmpClient;
189 if (sp<V2_2::IComposer> composer_2_2 = V2_2::IComposer::castFrom(mComposer)) {
190 mClient_2_2 = V2_2::IComposerClient::castFrom(mClient);
191 LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr,
192 "IComposer 2.2 did not return IComposerClient 2.2");
193 }
194 });
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800195 }
Daniel Nicoaraa50abc22017-05-15 10:34:08 -0400196
Dominik Laskowskie9ef7c42018-03-12 19:34:30 -0700197 if (mClient == nullptr) {
198 LOG_ALWAYS_FATAL("failed to create composer client");
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700199 }
200
Daniel Nicoaraa50abc22017-05-15 10:34:08 -0400201 if (mIsUsingVrComposer) {
202 sp<IVrComposerClient> vrClient = IVrComposerClient::castFrom(mClient);
203 if (vrClient == nullptr) {
204 LOG_ALWAYS_FATAL("failed to create vr composer client");
205 }
206 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800207}
208
Lloyd Piquea822d522017-12-20 16:42:57 -0800209Composer::~Composer() = default;
210
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800211std::vector<IComposer::Capability> Composer::getCapabilities()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800212{
213 std::vector<IComposer::Capability> capabilities;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800214 mComposer->getCapabilities(
Chia-I Wuaab99f52016-10-05 12:59:58 +0800215 [&](const auto& tmpCapabilities) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800216 capabilities = tmpCapabilities;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800217 });
Chia-I Wuaab99f52016-10-05 12:59:58 +0800218 return capabilities;
219}
220
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800221std::string Composer::dumpDebugInfo()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800222{
223 std::string info;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800224 mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800225 info = tmpInfo.c_str();
226 });
227
228 return info;
229}
230
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800231void Composer::registerCallback(const sp<IComposerCallback>& callback)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800232{
Wei Wangae211b42019-06-07 17:22:49 -0700233 android::hardware::setMinSchedulerPolicy(callback, SCHED_FIFO, 2);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800234 auto ret = mClient->registerCallback(callback);
Steven Moreland9d021002017-01-03 17:10:54 -0800235 if (!ret.isOk()) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800236 ALOGE("failed to register IComposerCallback");
237 }
238}
239
Steven Thomasb02664d2017-07-26 18:48:28 -0700240bool Composer::isRemote() {
241 return mClient->isRemote();
242}
243
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700244void Composer::resetCommands() {
245 mWriter.reset();
246}
247
Chia-I Wuae5a6b82017-10-10 09:09:22 -0700248Error Composer::executeCommands() {
249 return execute();
250}
251
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800252uint32_t Composer::getMaxVirtualDisplayCount()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800253{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800254 auto ret = mClient->getMaxVirtualDisplayCount();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800255 return unwrapRet(ret, 0);
256}
257
258Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800259 PixelFormat* format, Display* outDisplay)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800260{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800261 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800262 Error error = kDefaultError;
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700263 if (mClient_2_2) {
Kevin DuBois73d0f482019-01-25 11:18:03 -0800264 mClient_2_2->createVirtualDisplay_2_2(width, height,
265 static_cast<types::V1_1::PixelFormat>(*format),
266 bufferSlotCount,
267 [&](const auto& tmpError, const auto& tmpDisplay,
268 const auto& tmpFormat) {
269 error = tmpError;
270 if (error != Error::NONE) {
271 return;
272 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800273
Kevin DuBois73d0f482019-01-25 11:18:03 -0800274 *outDisplay = tmpDisplay;
275 *format = static_cast<types::V1_2::PixelFormat>(
276 tmpFormat);
277 });
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700278 } else {
279 mClient->createVirtualDisplay(width, height,
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700280 static_cast<types::V1_0::PixelFormat>(*format), bufferSlotCount,
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700281 [&](const auto& tmpError, const auto& tmpDisplay,
282 const auto& tmpFormat) {
283 error = tmpError;
284 if (error != Error::NONE) {
285 return;
286 }
287
288 *outDisplay = tmpDisplay;
289 *format = static_cast<PixelFormat>(tmpFormat);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800290 });
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700291 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800292
293 return error;
294}
295
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800296Error Composer::destroyVirtualDisplay(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800297{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800298 auto ret = mClient->destroyVirtualDisplay(display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800299 return unwrapRet(ret);
300}
301
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800302Error Composer::acceptDisplayChanges(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800303{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800304 mWriter.selectDisplay(display);
305 mWriter.acceptDisplayChanges();
306 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800307}
308
Chia-I Wu67e376d2016-12-19 11:36:22 +0800309Error Composer::createLayer(Display display, Layer* outLayer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800310{
311 Error error = kDefaultError;
Chia-I Wu06d63de2017-01-04 14:58:51 +0800312 mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800313 [&](const auto& tmpError, const auto& tmpLayer) {
314 error = tmpError;
315 if (error != Error::NONE) {
316 return;
317 }
318
Chia-I Wu67e376d2016-12-19 11:36:22 +0800319 *outLayer = tmpLayer;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800320 });
321
322 return error;
323}
324
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800325Error Composer::destroyLayer(Display display, Layer layer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800326{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800327 auto ret = mClient->destroyLayer(display, layer);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800328 return unwrapRet(ret);
329}
330
Chia-I Wu67e376d2016-12-19 11:36:22 +0800331Error Composer::getActiveConfig(Display display, Config* outConfig)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800332{
333 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800334 mClient->getActiveConfig(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800335 [&](const auto& tmpError, const auto& tmpConfig) {
336 error = tmpError;
337 if (error != Error::NONE) {
338 return;
339 }
340
Chia-I Wu67e376d2016-12-19 11:36:22 +0800341 *outConfig = tmpConfig;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800342 });
343
344 return error;
345}
346
347Error Composer::getChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800348 std::vector<Layer>* outLayers,
349 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800350{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800351 mReader.takeChangedCompositionTypes(display, outLayers, outTypes);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800352 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800353}
354
355Error Composer::getColorModes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800356 std::vector<ColorMode>* outModes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800357{
358 Error error = kDefaultError;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800359
Valerie Hau9758ae02018-10-09 16:05:09 -0700360 if (mClient_2_3) {
361 mClient_2_3->getColorModes_2_3(display, [&](const auto& tmpError, const auto& tmpModes) {
362 error = tmpError;
363 if (error != Error::NONE) {
364 return;
365 }
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700366
Valerie Hau9758ae02018-10-09 16:05:09 -0700367 *outModes = tmpModes;
368 });
369 } else if (mClient_2_2) {
370 mClient_2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
371 error = tmpError;
372 if (error != Error::NONE) {
373 return;
374 }
375
376 for (types::V1_1::ColorMode colorMode : tmpModes) {
377 outModes->push_back(static_cast<ColorMode>(colorMode));
378 }
379 });
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700380 } else {
381 mClient->getColorModes(display,
382 [&](const auto& tmpError, const auto& tmpModes) {
383 error = tmpError;
384 if (error != Error::NONE) {
385 return;
386 }
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700387 for (types::V1_0::ColorMode colorMode : tmpModes) {
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700388 outModes->push_back(static_cast<ColorMode>(colorMode));
389 }
390 });
391 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800392
393 return error;
394}
395
396Error Composer::getDisplayAttribute(Display display, Config config,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800397 IComposerClient::Attribute attribute, int32_t* outValue)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800398{
399 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800400 mClient->getDisplayAttribute(display, config, attribute,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800401 [&](const auto& tmpError, const auto& tmpValue) {
402 error = tmpError;
403 if (error != Error::NONE) {
404 return;
405 }
406
Chia-I Wu67e376d2016-12-19 11:36:22 +0800407 *outValue = tmpValue;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800408 });
409
410 return error;
411}
412
413Error Composer::getDisplayConfigs(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800414 std::vector<Config>* outConfigs)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800415{
416 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800417 mClient->getDisplayConfigs(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800418 [&](const auto& tmpError, const auto& tmpConfigs) {
419 error = tmpError;
420 if (error != Error::NONE) {
421 return;
422 }
423
Chia-I Wu67e376d2016-12-19 11:36:22 +0800424 *outConfigs = tmpConfigs;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800425 });
426
427 return error;
428}
429
Chia-I Wu67e376d2016-12-19 11:36:22 +0800430Error Composer::getDisplayName(Display display, std::string* outName)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800431{
432 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800433 mClient->getDisplayName(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800434 [&](const auto& tmpError, const auto& tmpName) {
435 error = tmpError;
436 if (error != Error::NONE) {
437 return;
438 }
439
Chia-I Wu67e376d2016-12-19 11:36:22 +0800440 *outName = tmpName.c_str();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800441 });
442
443 return error;
444}
445
446Error Composer::getDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800447 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
448 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800449{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800450 mReader.takeDisplayRequests(display, outDisplayRequestMask,
451 outLayers, outLayerRequestMasks);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800452 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800453}
454
Chia-I Wu67e376d2016-12-19 11:36:22 +0800455Error Composer::getDisplayType(Display display,
456 IComposerClient::DisplayType* outType)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800457{
458 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800459 mClient->getDisplayType(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800460 [&](const auto& tmpError, const auto& tmpType) {
461 error = tmpError;
462 if (error != Error::NONE) {
463 return;
464 }
465
Chia-I Wu67e376d2016-12-19 11:36:22 +0800466 *outType = tmpType;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800467 });
468
469 return error;
470}
471
Chia-I Wu67e376d2016-12-19 11:36:22 +0800472Error Composer::getDozeSupport(Display display, bool* outSupport)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800473{
474 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800475 mClient->getDozeSupport(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800476 [&](const auto& tmpError, const auto& tmpSupport) {
477 error = tmpError;
478 if (error != Error::NONE) {
479 return;
480 }
481
Chia-I Wu67e376d2016-12-19 11:36:22 +0800482 *outSupport = tmpSupport;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800483 });
484
485 return error;
486}
487
Chia-I Wu67e376d2016-12-19 11:36:22 +0800488Error Composer::getHdrCapabilities(Display display,
489 std::vector<Hdr>* outTypes, float* outMaxLuminance,
490 float* outMaxAverageLuminance, float* outMinLuminance)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800491{
492 Error error = kDefaultError;
Valerie Haue9e843a2018-12-18 13:39:23 -0800493 if (mClient_2_3) {
494 mClient_2_3->getHdrCapabilities_2_3(display,
495 [&](const auto& tmpError, const auto& tmpTypes,
496 const auto& tmpMaxLuminance,
497 const auto& tmpMaxAverageLuminance,
498 const auto& tmpMinLuminance) {
499 error = tmpError;
500 if (error != Error::NONE) {
501 return;
502 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800503
Valerie Haue9e843a2018-12-18 13:39:23 -0800504 *outTypes = tmpTypes;
505 *outMaxLuminance = tmpMaxLuminance;
506 *outMaxAverageLuminance = tmpMaxAverageLuminance;
507 *outMinLuminance = tmpMinLuminance;
508 });
509 } else {
510 mClient->getHdrCapabilities(display,
511 [&](const auto& tmpError, const auto& tmpTypes,
512 const auto& tmpMaxLuminance,
513 const auto& tmpMaxAverageLuminance,
514 const auto& tmpMinLuminance) {
515 error = tmpError;
516 if (error != Error::NONE) {
517 return;
518 }
519
520 outTypes->clear();
521 for (auto type : tmpTypes) {
522 outTypes->push_back(static_cast<Hdr>(type));
523 }
524
525 *outMaxLuminance = tmpMaxLuminance;
526 *outMaxAverageLuminance = tmpMaxAverageLuminance;
527 *outMinLuminance = tmpMinLuminance;
528 });
529 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800530
531 return error;
532}
533
Chia-I Wu67e376d2016-12-19 11:36:22 +0800534Error Composer::getReleaseFences(Display display,
535 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800536{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800537 mReader.takeReleaseFences(display, outLayers, outReleaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800538 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800539}
540
Chia-I Wu67e376d2016-12-19 11:36:22 +0800541Error Composer::presentDisplay(Display display, int* outPresentFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800542{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800543 mWriter.selectDisplay(display);
544 mWriter.presentDisplay();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800545
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800546 Error error = execute();
547 if (error != Error::NONE) {
548 return error;
549 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800550
Chia-I Wu67e376d2016-12-19 11:36:22 +0800551 mReader.takePresentFence(display, outPresentFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800552
553 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800554}
555
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800556Error Composer::setActiveConfig(Display display, Config config)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800557{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800558 auto ret = mClient->setActiveConfig(display, config);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800559 return unwrapRet(ret);
560}
561
Chia-I Wu06d63de2017-01-04 14:58:51 +0800562Error Composer::setClientTarget(Display display, uint32_t slot,
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400563 const sp<GraphicBuffer>& target,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800564 int acquireFence, Dataspace dataspace,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800565 const std::vector<IComposerClient::Rect>& damage)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800566{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800567 mWriter.selectDisplay(display);
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400568 if (mIsUsingVrComposer && target.get()) {
569 IVrComposerClient::BufferMetadata metadata = {
570 .width = target->getWidth(),
571 .height = target->getHeight(),
572 .stride = target->getStride(),
573 .layerCount = target->getLayerCount(),
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700574 .format = static_cast<types::V1_0::PixelFormat>(target->getPixelFormat()),
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400575 .usage = target->getUsage(),
576 };
577 mWriter.setClientTargetMetadata(metadata);
578 }
579
580 const native_handle_t* handle = nullptr;
581 if (target.get()) {
582 handle = target->getNativeBuffer()->handle;
583 }
584
585 mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800586 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800587}
588
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700589Error Composer::setColorMode(Display display, ColorMode mode,
590 RenderIntent renderIntent)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800591{
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700592 hardware::Return<Error> ret(kDefaultError);
Valerie Hau9758ae02018-10-09 16:05:09 -0700593 if (mClient_2_3) {
594 ret = mClient_2_3->setColorMode_2_3(display, mode, renderIntent);
595 } else if (mClient_2_2) {
596 ret = mClient_2_2->setColorMode_2_2(display, static_cast<types::V1_1::ColorMode>(mode),
597 renderIntent);
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700598 } else {
599 ret = mClient->setColorMode(display,
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700600 static_cast<types::V1_0::ColorMode>(mode));
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700601 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800602 return unwrapRet(ret);
603}
604
605Error Composer::setColorTransform(Display display, const float* matrix,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800606 ColorTransform hint)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800607{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800608 mWriter.selectDisplay(display);
609 mWriter.setColorTransform(matrix, hint);
610 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800611}
612
613Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800614 int releaseFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800615{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800616 mWriter.selectDisplay(display);
617 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
618 return Error::NONE;
619}
Chia-I Wuaab99f52016-10-05 12:59:58 +0800620
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700621Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode) {
622 Return<Error> ret(Error::UNSUPPORTED);
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700623 if (mClient_2_2) {
624 ret = mClient_2_2->setPowerMode_2_2(display, mode);
625 } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) {
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700626 ret = mClient->setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700627 }
628
Chia-I Wuaab99f52016-10-05 12:59:58 +0800629 return unwrapRet(ret);
630}
631
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800632Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800633{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800634 auto ret = mClient->setVsyncEnabled(display, enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800635 return unwrapRet(ret);
636}
637
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800638Error Composer::setClientTargetSlotCount(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800639{
Chia-I Wu06d63de2017-01-04 14:58:51 +0800640 const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800641 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800642 return unwrapRet(ret);
643}
644
Chia-I Wu67e376d2016-12-19 11:36:22 +0800645Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
646 uint32_t* outNumRequests)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800647{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800648 mWriter.selectDisplay(display);
649 mWriter.validateDisplay();
650
651 Error error = execute();
652 if (error != Error::NONE) {
653 return error;
654 }
655
Chia-I Wu67e376d2016-12-19 11:36:22 +0800656 mReader.hasChanges(display, outNumTypes, outNumRequests);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800657
658 return Error::NONE;
659}
660
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700661Error Composer::presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
662 uint32_t* outNumRequests, int* outPresentFence, uint32_t* state) {
663 mWriter.selectDisplay(display);
664 mWriter.presentOrvalidateDisplay();
665
666 Error error = execute();
667 if (error != Error::NONE) {
668 return error;
669 }
670
671 mReader.takePresentOrValidateStage(display, state);
672
673 if (*state == 1) { // Present succeeded
674 mReader.takePresentFence(display, outPresentFence);
675 }
676
677 if (*state == 0) { // Validate succeeded.
678 mReader.hasChanges(display, outNumTypes, outNumRequests);
679 }
680
681 return Error::NONE;
682}
683
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800684Error Composer::setCursorPosition(Display display, Layer layer,
685 int32_t x, int32_t y)
686{
687 mWriter.selectDisplay(display);
688 mWriter.selectLayer(layer);
689 mWriter.setLayerCursorPosition(x, y);
690 return Error::NONE;
691}
692
693Error Composer::setLayerBuffer(Display display, Layer layer,
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400694 uint32_t slot, const sp<GraphicBuffer>& buffer, int acquireFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800695{
696 mWriter.selectDisplay(display);
697 mWriter.selectLayer(layer);
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400698 if (mIsUsingVrComposer && buffer.get()) {
699 IVrComposerClient::BufferMetadata metadata = {
700 .width = buffer->getWidth(),
701 .height = buffer->getHeight(),
702 .stride = buffer->getStride(),
703 .layerCount = buffer->getLayerCount(),
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700704 .format = static_cast<types::V1_0::PixelFormat>(buffer->getPixelFormat()),
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400705 .usage = buffer->getUsage(),
706 };
707 mWriter.setLayerBufferMetadata(metadata);
708 }
709
710 const native_handle_t* handle = nullptr;
711 if (buffer.get()) {
712 handle = buffer->getNativeBuffer()->handle;
713 }
714
715 mWriter.setLayerBuffer(slot, handle, acquireFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800716 return Error::NONE;
717}
718
719Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
720 const std::vector<IComposerClient::Rect>& damage)
721{
722 mWriter.selectDisplay(display);
723 mWriter.selectLayer(layer);
724 mWriter.setLayerSurfaceDamage(damage);
725 return Error::NONE;
726}
727
728Error Composer::setLayerBlendMode(Display display, Layer layer,
729 IComposerClient::BlendMode mode)
730{
731 mWriter.selectDisplay(display);
732 mWriter.selectLayer(layer);
733 mWriter.setLayerBlendMode(mode);
734 return Error::NONE;
735}
736
737Error Composer::setLayerColor(Display display, Layer layer,
738 const IComposerClient::Color& color)
739{
740 mWriter.selectDisplay(display);
741 mWriter.selectLayer(layer);
742 mWriter.setLayerColor(color);
743 return Error::NONE;
744}
745
746Error Composer::setLayerCompositionType(Display display, Layer layer,
747 IComposerClient::Composition type)
748{
749 mWriter.selectDisplay(display);
750 mWriter.selectLayer(layer);
751 mWriter.setLayerCompositionType(type);
752 return Error::NONE;
753}
754
755Error Composer::setLayerDataspace(Display display, Layer layer,
756 Dataspace dataspace)
757{
758 mWriter.selectDisplay(display);
759 mWriter.selectLayer(layer);
760 mWriter.setLayerDataspace(dataspace);
761 return Error::NONE;
762}
763
764Error Composer::setLayerDisplayFrame(Display display, Layer layer,
765 const IComposerClient::Rect& frame)
766{
767 mWriter.selectDisplay(display);
768 mWriter.selectLayer(layer);
769 mWriter.setLayerDisplayFrame(frame);
770 return Error::NONE;
771}
772
773Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
774 float alpha)
775{
776 mWriter.selectDisplay(display);
777 mWriter.selectLayer(layer);
778 mWriter.setLayerPlaneAlpha(alpha);
779 return Error::NONE;
780}
781
782Error Composer::setLayerSidebandStream(Display display, Layer layer,
783 const native_handle_t* stream)
784{
785 mWriter.selectDisplay(display);
786 mWriter.selectLayer(layer);
787 mWriter.setLayerSidebandStream(stream);
788 return Error::NONE;
789}
790
791Error Composer::setLayerSourceCrop(Display display, Layer layer,
792 const IComposerClient::FRect& crop)
793{
794 mWriter.selectDisplay(display);
795 mWriter.selectLayer(layer);
796 mWriter.setLayerSourceCrop(crop);
797 return Error::NONE;
798}
799
800Error Composer::setLayerTransform(Display display, Layer layer,
801 Transform transform)
802{
803 mWriter.selectDisplay(display);
804 mWriter.selectLayer(layer);
805 mWriter.setLayerTransform(transform);
806 return Error::NONE;
807}
808
809Error Composer::setLayerVisibleRegion(Display display, Layer layer,
810 const std::vector<IComposerClient::Rect>& visible)
811{
812 mWriter.selectDisplay(display);
813 mWriter.selectLayer(layer);
814 mWriter.setLayerVisibleRegion(visible);
815 return Error::NONE;
816}
817
818Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
819{
820 mWriter.selectDisplay(display);
821 mWriter.selectLayer(layer);
822 mWriter.setLayerZOrder(z);
823 return Error::NONE;
824}
825
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500826Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
827 uint32_t appId)
828{
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800829 if (mIsUsingVrComposer) {
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500830 mWriter.selectDisplay(display);
831 mWriter.selectLayer(layer);
832 mWriter.setLayerInfo(type, appId);
833 }
834 return Error::NONE;
835}
836
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800837Error Composer::execute()
838{
839 // prepare input command queue
840 bool queueChanged = false;
841 uint32_t commandLength = 0;
842 hidl_vec<hidl_handle> commandHandles;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800843 if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800844 mWriter.reset();
845 return Error::NO_RESOURCES;
846 }
847
848 // set up new input command queue if necessary
849 if (queueChanged) {
850 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
851 auto error = unwrapRet(ret);
852 if (error != Error::NONE) {
853 mWriter.reset();
854 return error;
855 }
856 }
857
Chia-I Wuae5a6b82017-10-10 09:09:22 -0700858 if (commandLength == 0) {
859 mWriter.reset();
860 return Error::NONE;
861 }
862
Chia-I Wuaab99f52016-10-05 12:59:58 +0800863 Error error = kDefaultError;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700864 hardware::Return<void> ret;
865 auto hidl_callback = [&](const auto& tmpError, const auto& tmpOutChanged,
866 const auto& tmpOutLength, const auto& tmpOutHandles)
867 {
868 error = tmpError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800869
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700870 // set up new output command queue if necessary
871 if (error == Error::NONE && tmpOutChanged) {
872 error = kDefaultError;
873 mClient->getOutputCommandQueue(
874 [&](const auto& tmpError,
875 const auto& tmpDescriptor)
876 {
877 error = tmpError;
878 if (error != Error::NONE) {
879 return;
880 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800881
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700882 mReader.setMQDescriptor(tmpDescriptor);
883 });
884 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800885
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700886 if (error != Error::NONE) {
887 return;
888 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800889
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700890 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
891 error = mReader.parse();
892 mReader.reset();
893 } else {
894 error = Error::NO_RESOURCES;
895 }
896 };
897 if (mClient_2_2) {
898 ret = mClient_2_2->executeCommands_2_2(commandLength, commandHandles, hidl_callback);
899 } else {
900 ret = mClient->executeCommands(commandLength, commandHandles, hidl_callback);
901 }
Chia-I Wuc0b2b0c2017-09-08 10:14:34 -0700902 // executeCommands can fail because of out-of-fd and we do not want to
903 // abort() in that case
904 if (!ret.isOk()) {
905 ALOGE("executeCommands failed because of %s", ret.description().c_str());
906 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800907
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800908 if (error == Error::NONE) {
909 std::vector<CommandReader::CommandError> commandErrors =
910 mReader.takeErrors();
911
912 for (const auto& cmdErr : commandErrors) {
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700913 auto command =
914 static_cast<IComposerClient::Command>(mWriter.getCommand(cmdErr.location));
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800915
916 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700917 command == IComposerClient::Command::PRESENT_DISPLAY ||
918 command == IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800919 error = cmdErr.error;
920 } else {
921 ALOGW("command 0x%x generated error %d",
922 command, cmdErr.error);
923 }
924 }
925 }
926
927 mWriter.reset();
928
Chia-I Wuaab99f52016-10-05 12:59:58 +0800929 return error;
930}
931
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700932// Composer HAL 2.2
933
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700934Error Composer::setLayerPerFrameMetadata(Display display, Layer layer,
935 const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) {
936 if (!mClient_2_2) {
937 return Error::UNSUPPORTED;
938 }
939
940 mWriter.selectDisplay(display);
941 mWriter.selectLayer(layer);
942 mWriter.setLayerPerFrameMetadata(perFrameMetadatas);
943 return Error::NONE;
944}
945
Chia-I Wud7e01d72018-06-21 13:39:09 +0800946std::vector<IComposerClient::PerFrameMetadataKey> Composer::getPerFrameMetadataKeys(
947 Display display) {
948 std::vector<IComposerClient::PerFrameMetadataKey> keys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700949 if (!mClient_2_2) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800950 return keys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700951 }
952
953 Error error = kDefaultError;
Valerie Haue9e843a2018-12-18 13:39:23 -0800954 if (mClient_2_3) {
955 mClient_2_3->getPerFrameMetadataKeys_2_3(display,
956 [&](const auto& tmpError, const auto& tmpKeys) {
957 error = tmpError;
958 if (error != Error::NONE) {
959 ALOGW("getPerFrameMetadataKeys failed "
960 "with %d",
961 tmpError);
962 return;
963 }
964 keys = tmpKeys;
965 });
966 } else {
967 mClient_2_2
968 ->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
969 error = tmpError;
970 if (error != Error::NONE) {
971 ALOGW("getPerFrameMetadataKeys failed with %d", tmpError);
972 return;
973 }
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700974
Valerie Haue9e843a2018-12-18 13:39:23 -0800975 keys.clear();
976 for (auto key : tmpKeys) {
977 keys.push_back(static_cast<IComposerClient::PerFrameMetadataKey>(key));
978 }
979 });
980 }
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700981
Chia-I Wud7e01d72018-06-21 13:39:09 +0800982 return keys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700983}
984
985Error Composer::getRenderIntents(Display display, ColorMode colorMode,
986 std::vector<RenderIntent>* outRenderIntents) {
987 if (!mClient_2_2) {
988 outRenderIntents->push_back(RenderIntent::COLORIMETRIC);
989 return Error::NONE;
990 }
991
992 Error error = kDefaultError;
Valerie Hau9758ae02018-10-09 16:05:09 -0700993
994 auto getRenderIntentsLambda = [&](const auto& tmpError, const auto& tmpKeys) {
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700995 error = tmpError;
996 if (error != Error::NONE) {
997 return;
998 }
999
1000 *outRenderIntents = tmpKeys;
Valerie Hau9758ae02018-10-09 16:05:09 -07001001 };
1002
1003 if (mClient_2_3) {
1004 mClient_2_3->getRenderIntents_2_3(display, colorMode, getRenderIntentsLambda);
1005 } else {
1006 mClient_2_2->getRenderIntents(display, static_cast<types::V1_1::ColorMode>(colorMode),
1007 getRenderIntentsLambda);
1008 }
Peiyong Lin0e7a7912018-04-05 14:36:36 -07001009
1010 return error;
1011}
1012
1013Error Composer::getDataspaceSaturationMatrix(Dataspace dataspace, mat4* outMatrix)
1014{
1015 if (!mClient_2_2) {
1016 *outMatrix = mat4();
1017 return Error::NONE;
1018 }
1019
1020 Error error = kDefaultError;
Valerie Hau9758ae02018-10-09 16:05:09 -07001021 mClient_2_2->getDataspaceSaturationMatrix(static_cast<types::V1_1::Dataspace>(dataspace),
1022 [&](const auto& tmpError, const auto& tmpMatrix) {
1023 error = tmpError;
1024 if (error != Error::NONE) {
1025 return;
1026 }
1027 *outMatrix = mat4(tmpMatrix.data());
1028 });
Peiyong Lin0e7a7912018-04-05 14:36:36 -07001029
1030 return error;
1031}
1032
Dominik Laskowskie9ef7c42018-03-12 19:34:30 -07001033// Composer HAL 2.3
1034
1035Error Composer::getDisplayIdentificationData(Display display, uint8_t* outPort,
1036 std::vector<uint8_t>* outData) {
1037 if (!mClient_2_3) {
1038 return Error::UNSUPPORTED;
1039 }
1040
1041 Error error = kDefaultError;
1042 mClient_2_3->getDisplayIdentificationData(display,
1043 [&](const auto& tmpError, const auto& tmpPort,
1044 const auto& tmpData) {
1045 error = tmpError;
1046 if (error != Error::NONE) {
1047 return;
1048 }
1049
1050 *outPort = tmpPort;
1051 *outData = tmpData;
1052 });
1053
1054 return error;
1055}
1056
Peiyong Lin698147a2018-09-14 13:27:18 -07001057Error Composer::setLayerColorTransform(Display display, Layer layer, const float* matrix)
1058{
1059 if (!mClient_2_3) {
1060 return Error::UNSUPPORTED;
1061 }
1062
1063 mWriter.selectDisplay(display);
1064 mWriter.selectLayer(layer);
1065 mWriter.setLayerColorTransform(matrix);
1066 return Error::NONE;
1067}
1068
Kevin DuBois9c0a1762018-10-16 13:32:31 -07001069Error Composer::getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat,
1070 Dataspace* outDataspace,
1071 uint8_t* outComponentMask) {
1072 if (!outFormat || !outDataspace || !outComponentMask) {
1073 return Error::BAD_PARAMETER;
1074 }
1075 if (!mClient_2_3) {
1076 return Error::UNSUPPORTED;
1077 }
1078 Error error = kDefaultError;
1079 mClient_2_3->getDisplayedContentSamplingAttributes(display,
1080 [&](const auto tmpError,
1081 const auto& tmpFormat,
1082 const auto& tmpDataspace,
1083 const auto& tmpComponentMask) {
1084 error = tmpError;
1085 if (error == Error::NONE) {
1086 *outFormat = tmpFormat;
1087 *outDataspace = tmpDataspace;
1088 *outComponentMask =
1089 static_cast<uint8_t>(
1090 tmpComponentMask);
1091 }
1092 });
1093 return error;
1094}
1095
Peiyong Lined531a32018-10-26 18:27:56 -07001096Error Composer::getDisplayCapabilities(Display display,
1097 std::vector<DisplayCapability>* outCapabilities) {
1098 if (!mClient_2_3) {
1099 return Error::UNSUPPORTED;
1100 }
1101 Error error = kDefaultError;
1102 mClient_2_3->getDisplayCapabilities(display,
1103 [&](const auto& tmpError, const auto& tmpCapabilities) {
1104 error = tmpError;
1105 if (error != Error::NONE) {
1106 return;
1107 }
1108 *outCapabilities = tmpCapabilities;
1109 });
1110 return error;
1111}
1112
Kevin DuBois74e53772018-11-19 10:52:38 -08001113Error Composer::setDisplayContentSamplingEnabled(Display display, bool enabled,
1114 uint8_t componentMask, uint64_t maxFrames) {
1115 if (!mClient_2_3) {
1116 return Error::UNSUPPORTED;
1117 }
1118
1119 auto enable = enabled ? V2_3::IComposerClient::DisplayedContentSampling::ENABLE
1120 : V2_3::IComposerClient::DisplayedContentSampling::DISABLE;
1121 return mClient_2_3->setDisplayedContentSamplingEnabled(display, enable, componentMask,
1122 maxFrames);
1123}
1124
Kevin DuBois1d4249a2018-08-29 10:45:14 -07001125Error Composer::getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp,
1126 DisplayedFrameStats* outStats) {
1127 if (!outStats) {
1128 return Error::BAD_PARAMETER;
1129 }
1130 if (!mClient_2_3) {
1131 return Error::UNSUPPORTED;
1132 }
1133 Error error = kDefaultError;
1134 mClient_2_3->getDisplayedContentSample(display, maxFrames, timestamp,
1135 [&](const auto tmpError, auto tmpNumFrames,
1136 const auto& tmpSamples0, const auto& tmpSamples1,
1137 const auto& tmpSamples2, const auto& tmpSamples3) {
1138 error = tmpError;
1139 if (error == Error::NONE) {
1140 outStats->numFrames = tmpNumFrames;
1141 outStats->component_0_sample = tmpSamples0;
1142 outStats->component_1_sample = tmpSamples1;
1143 outStats->component_2_sample = tmpSamples2;
1144 outStats->component_3_sample = tmpSamples3;
1145 }
1146 });
1147 return error;
1148}
1149
Valerie Haue9e843a2018-12-18 13:39:23 -08001150Error Composer::setLayerPerFrameMetadataBlobs(
1151 Display display, Layer layer,
1152 const std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) {
1153 if (!mClient_2_3) {
1154 return Error::UNSUPPORTED;
1155 }
1156
1157 mWriter.selectDisplay(display);
1158 mWriter.selectLayer(layer);
1159 mWriter.setLayerPerFrameMetadataBlobs(metadata);
1160 return Error::NONE;
1161}
1162
Dan Gittik57e63c52019-01-18 16:37:54 +00001163Error Composer::setDisplayBrightness(Display display, float brightness) {
1164 if (!mClient_2_3) {
1165 return Error::UNSUPPORTED;
1166 }
1167 return mClient_2_3->setDisplayBrightness(display, brightness);
1168}
1169
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001170CommandReader::~CommandReader()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001171{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001172 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001173}
1174
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001175Error CommandReader::parse()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001176{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001177 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001178
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001179 IComposerClient::Command command;
1180 uint16_t length = 0;
1181
1182 while (!isEmpty()) {
Dominik Laskowski6231aaf2018-04-02 17:10:23 -07001183 auto command_2_1 = reinterpret_cast<V2_1::IComposerClient::Command*>(&command);
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -07001184 if (!beginCommand(command_2_1, &length)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001185 break;
1186 }
1187
1188 bool parsed = false;
1189 switch (command) {
1190 case IComposerClient::Command::SELECT_DISPLAY:
1191 parsed = parseSelectDisplay(length);
1192 break;
1193 case IComposerClient::Command::SET_ERROR:
1194 parsed = parseSetError(length);
1195 break;
1196 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
1197 parsed = parseSetChangedCompositionTypes(length);
1198 break;
1199 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
1200 parsed = parseSetDisplayRequests(length);
1201 break;
1202 case IComposerClient::Command::SET_PRESENT_FENCE:
1203 parsed = parseSetPresentFence(length);
1204 break;
1205 case IComposerClient::Command::SET_RELEASE_FENCES:
1206 parsed = parseSetReleaseFences(length);
1207 break;
Fabien Sanglard249c0ae2017-06-19 19:22:36 -07001208 case IComposerClient::Command ::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT:
1209 parsed = parseSetPresentOrValidateDisplayResult(length);
1210 break;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001211 default:
1212 parsed = false;
1213 break;
1214 }
1215
1216 endCommand();
1217
1218 if (!parsed) {
1219 ALOGE("failed to parse command 0x%x length %" PRIu16,
1220 command, length);
1221 break;
1222 }
1223 }
1224
1225 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001226}
1227
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001228bool CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001229{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -05001230 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001231 return false;
1232 }
Chia-I Wuaab99f52016-10-05 12:59:58 +08001233
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001234 mCurrentReturnData = &mReturnData[read64()];
1235
1236 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001237}
1238
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001239bool CommandReader::parseSetError(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001240{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -05001241 if (length != CommandWriterBase::kSetErrorLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001242 return false;
1243 }
1244
1245 auto location = read();
1246 auto error = static_cast<Error>(readSigned());
1247
1248 mErrors.emplace_back(CommandError{location, error});
1249
1250 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001251}
1252
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001253bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001254{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001255 // (layer id, composition type) pairs
1256 if (length % 3 != 0 || !mCurrentReturnData) {
1257 return false;
1258 }
1259
1260 uint32_t count = length / 3;
1261 mCurrentReturnData->changedLayers.reserve(count);
1262 mCurrentReturnData->compositionTypes.reserve(count);
1263 while (count > 0) {
1264 auto layer = read64();
1265 auto type = static_cast<IComposerClient::Composition>(readSigned());
1266
1267 mCurrentReturnData->changedLayers.push_back(layer);
1268 mCurrentReturnData->compositionTypes.push_back(type);
1269
1270 count--;
1271 }
1272
1273 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001274}
1275
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001276bool CommandReader::parseSetDisplayRequests(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001277{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001278 // display requests followed by (layer id, layer requests) pairs
1279 if (length % 3 != 1 || !mCurrentReturnData) {
1280 return false;
1281 }
1282
1283 mCurrentReturnData->displayRequests = read();
1284
1285 uint32_t count = (length - 1) / 3;
1286 mCurrentReturnData->requestedLayers.reserve(count);
1287 mCurrentReturnData->requestMasks.reserve(count);
1288 while (count > 0) {
1289 auto layer = read64();
1290 auto layerRequestMask = read();
1291
1292 mCurrentReturnData->requestedLayers.push_back(layer);
1293 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
1294
1295 count--;
1296 }
1297
1298 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001299}
1300
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001301bool CommandReader::parseSetPresentFence(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001302{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -05001303 if (length != CommandWriterBase::kSetPresentFenceLength ||
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001304 !mCurrentReturnData) {
1305 return false;
1306 }
1307
1308 if (mCurrentReturnData->presentFence >= 0) {
1309 close(mCurrentReturnData->presentFence);
1310 }
1311 mCurrentReturnData->presentFence = readFence();
1312
1313 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001314}
1315
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001316bool CommandReader::parseSetReleaseFences(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001317{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001318 // (layer id, release fence index) pairs
1319 if (length % 3 != 0 || !mCurrentReturnData) {
1320 return false;
1321 }
1322
1323 uint32_t count = length / 3;
1324 mCurrentReturnData->releasedLayers.reserve(count);
1325 mCurrentReturnData->releaseFences.reserve(count);
1326 while (count > 0) {
1327 auto layer = read64();
1328 auto fence = readFence();
1329
1330 mCurrentReturnData->releasedLayers.push_back(layer);
1331 mCurrentReturnData->releaseFences.push_back(fence);
1332
1333 count--;
1334 }
1335
1336 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001337}
1338
Fabien Sanglard249c0ae2017-06-19 19:22:36 -07001339bool CommandReader::parseSetPresentOrValidateDisplayResult(uint16_t length)
1340{
1341 if (length != CommandWriterBase::kPresentOrValidateDisplayResultLength || !mCurrentReturnData) {
1342 return false;
1343 }
1344 mCurrentReturnData->presentOrValidateState = read();
1345 return true;
1346}
1347
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001348void CommandReader::resetData()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001349{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001350 mErrors.clear();
1351
1352 for (auto& data : mReturnData) {
1353 if (data.second.presentFence >= 0) {
1354 close(data.second.presentFence);
1355 }
1356 for (auto fence : data.second.releaseFences) {
1357 if (fence >= 0) {
1358 close(fence);
1359 }
1360 }
1361 }
1362
1363 mReturnData.clear();
1364 mCurrentReturnData = nullptr;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001365}
1366
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001367std::vector<CommandReader::CommandError> CommandReader::takeErrors()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001368{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001369 return std::move(mErrors);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001370}
1371
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001372bool CommandReader::hasChanges(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001373 uint32_t* outNumChangedCompositionTypes,
1374 uint32_t* outNumLayerRequestMasks) const
Chia-I Wuaab99f52016-10-05 12:59:58 +08001375{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001376 auto found = mReturnData.find(display);
1377 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001378 *outNumChangedCompositionTypes = 0;
1379 *outNumLayerRequestMasks = 0;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001380 return false;
1381 }
1382
1383 const ReturnData& data = found->second;
1384
Chia-I Wu67e376d2016-12-19 11:36:22 +08001385 *outNumChangedCompositionTypes = data.compositionTypes.size();
1386 *outNumLayerRequestMasks = data.requestMasks.size();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001387
1388 return !(data.compositionTypes.empty() && data.requestMasks.empty());
Chia-I Wuaab99f52016-10-05 12:59:58 +08001389}
1390
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001391void CommandReader::takeChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001392 std::vector<Layer>* outLayers,
1393 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001394{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001395 auto found = mReturnData.find(display);
1396 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001397 outLayers->clear();
1398 outTypes->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001399 return;
1400 }
1401
1402 ReturnData& data = found->second;
1403
Chia-I Wu67e376d2016-12-19 11:36:22 +08001404 *outLayers = std::move(data.changedLayers);
1405 *outTypes = std::move(data.compositionTypes);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001406}
1407
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001408void CommandReader::takeDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001409 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
1410 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001411{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001412 auto found = mReturnData.find(display);
1413 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001414 *outDisplayRequestMask = 0;
1415 outLayers->clear();
1416 outLayerRequestMasks->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001417 return;
1418 }
Chia-I Wuaab99f52016-10-05 12:59:58 +08001419
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001420 ReturnData& data = found->second;
1421
Chia-I Wu67e376d2016-12-19 11:36:22 +08001422 *outDisplayRequestMask = data.displayRequests;
1423 *outLayers = std::move(data.requestedLayers);
1424 *outLayerRequestMasks = std::move(data.requestMasks);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001425}
1426
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001427void CommandReader::takeReleaseFences(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001428 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001429{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001430 auto found = mReturnData.find(display);
1431 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001432 outLayers->clear();
1433 outReleaseFences->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001434 return;
1435 }
1436
1437 ReturnData& data = found->second;
1438
Chia-I Wu67e376d2016-12-19 11:36:22 +08001439 *outLayers = std::move(data.releasedLayers);
1440 *outReleaseFences = std::move(data.releaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001441}
1442
Chia-I Wu67e376d2016-12-19 11:36:22 +08001443void CommandReader::takePresentFence(Display display, int* outPresentFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001444{
1445 auto found = mReturnData.find(display);
1446 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001447 *outPresentFence = -1;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001448 return;
1449 }
1450
1451 ReturnData& data = found->second;
1452
Chia-I Wu67e376d2016-12-19 11:36:22 +08001453 *outPresentFence = data.presentFence;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001454 data.presentFence = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001455}
1456
Fabien Sanglard249c0ae2017-06-19 19:22:36 -07001457void CommandReader::takePresentOrValidateStage(Display display, uint32_t* state) {
1458 auto found = mReturnData.find(display);
1459 if (found == mReturnData.end()) {
1460 *state= -1;
1461 return;
1462 }
1463 ReturnData& data = found->second;
1464 *state = data.presentOrValidateState;
1465}
1466
Lloyd Piquea822d522017-12-20 16:42:57 -08001467} // namespace impl
1468
Chia-I Wuaab99f52016-10-05 12:59:58 +08001469} // namespace Hwc2
1470
1471} // namespace android