blob: 163b26cd361bfcb40ea8dc17a957ac093faa6b32 [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>
27#include <hidl/HidlTransportUtils.h>
28
Chia-I Wuaab99f52016-10-05 12:59:58 +080029namespace android {
30
31using hardware::Return;
32using hardware::hidl_vec;
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010033using hardware::hidl_handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080034
35namespace Hwc2 {
36
Lloyd Piquea822d522017-12-20 16:42:57 -080037Composer::~Composer() = default;
38
Chia-I Wuaab99f52016-10-05 12:59:58 +080039namespace {
40
41class BufferHandle {
42public:
43 BufferHandle(const native_handle_t* buffer)
44 {
45 // nullptr is not a valid handle to HIDL
46 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
47 }
48
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010049 operator const hidl_handle&() const
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
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010083 operator const hidl_handle&() const
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 });
218
219 return capabilities;
220}
221
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800222std::string Composer::dumpDebugInfo()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800223{
224 std::string info;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800225 mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800226 info = tmpInfo.c_str();
227 });
228
229 return info;
230}
231
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800232void Composer::registerCallback(const sp<IComposerCallback>& callback)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800233{
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) {
264 mClient_2_2->createVirtualDisplay_2_2(width, height, *format, bufferSlotCount,
265 [&](const auto& tmpError, const auto& tmpDisplay,
266 const auto& tmpFormat) {
267 error = tmpError;
268 if (error != Error::NONE) {
269 return;
270 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800271
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700272 *outDisplay = tmpDisplay;
273 *format = tmpFormat;
274 });
275 } else {
276 mClient->createVirtualDisplay(width, height,
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700277 static_cast<types::V1_0::PixelFormat>(*format), bufferSlotCount,
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700278 [&](const auto& tmpError, const auto& tmpDisplay,
279 const auto& tmpFormat) {
280 error = tmpError;
281 if (error != Error::NONE) {
282 return;
283 }
284
285 *outDisplay = tmpDisplay;
286 *format = static_cast<PixelFormat>(tmpFormat);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800287 });
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700288 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800289
290 return error;
291}
292
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800293Error Composer::destroyVirtualDisplay(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800294{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800295 auto ret = mClient->destroyVirtualDisplay(display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800296 return unwrapRet(ret);
297}
298
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800299Error Composer::acceptDisplayChanges(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800300{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800301 mWriter.selectDisplay(display);
302 mWriter.acceptDisplayChanges();
303 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800304}
305
Chia-I Wu67e376d2016-12-19 11:36:22 +0800306Error Composer::createLayer(Display display, Layer* outLayer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800307{
308 Error error = kDefaultError;
Chia-I Wu06d63de2017-01-04 14:58:51 +0800309 mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800310 [&](const auto& tmpError, const auto& tmpLayer) {
311 error = tmpError;
312 if (error != Error::NONE) {
313 return;
314 }
315
Chia-I Wu67e376d2016-12-19 11:36:22 +0800316 *outLayer = tmpLayer;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800317 });
318
319 return error;
320}
321
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800322Error Composer::destroyLayer(Display display, Layer layer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800323{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800324 auto ret = mClient->destroyLayer(display, layer);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800325 return unwrapRet(ret);
326}
327
Chia-I Wu67e376d2016-12-19 11:36:22 +0800328Error Composer::getActiveConfig(Display display, Config* outConfig)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800329{
330 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800331 mClient->getActiveConfig(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800332 [&](const auto& tmpError, const auto& tmpConfig) {
333 error = tmpError;
334 if (error != Error::NONE) {
335 return;
336 }
337
Chia-I Wu67e376d2016-12-19 11:36:22 +0800338 *outConfig = tmpConfig;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800339 });
340
341 return error;
342}
343
344Error Composer::getChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800345 std::vector<Layer>* outLayers,
346 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800347{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800348 mReader.takeChangedCompositionTypes(display, outLayers, outTypes);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800349 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800350}
351
352Error Composer::getColorModes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800353 std::vector<ColorMode>* outModes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800354{
355 Error error = kDefaultError;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800356
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700357 if (mClient_2_2) {
358 mClient_2_2->getColorModes_2_2(display,
359 [&](const auto& tmpError, const auto& tmpModes) {
360 error = tmpError;
361 if (error != Error::NONE) {
362 return;
363 }
364
365 *outModes = tmpModes;
366 });
367 } else {
368 mClient->getColorModes(display,
369 [&](const auto& tmpError, const auto& tmpModes) {
370 error = tmpError;
371 if (error != Error::NONE) {
372 return;
373 }
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700374 for (types::V1_0::ColorMode colorMode : tmpModes) {
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700375 outModes->push_back(static_cast<ColorMode>(colorMode));
376 }
377 });
378 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800379
380 return error;
381}
382
383Error Composer::getDisplayAttribute(Display display, Config config,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800384 IComposerClient::Attribute attribute, int32_t* outValue)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800385{
386 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800387 mClient->getDisplayAttribute(display, config, attribute,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800388 [&](const auto& tmpError, const auto& tmpValue) {
389 error = tmpError;
390 if (error != Error::NONE) {
391 return;
392 }
393
Chia-I Wu67e376d2016-12-19 11:36:22 +0800394 *outValue = tmpValue;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800395 });
396
397 return error;
398}
399
400Error Composer::getDisplayConfigs(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800401 std::vector<Config>* outConfigs)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800402{
403 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800404 mClient->getDisplayConfigs(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800405 [&](const auto& tmpError, const auto& tmpConfigs) {
406 error = tmpError;
407 if (error != Error::NONE) {
408 return;
409 }
410
Chia-I Wu67e376d2016-12-19 11:36:22 +0800411 *outConfigs = tmpConfigs;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800412 });
413
414 return error;
415}
416
Chia-I Wu67e376d2016-12-19 11:36:22 +0800417Error Composer::getDisplayName(Display display, std::string* outName)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800418{
419 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800420 mClient->getDisplayName(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800421 [&](const auto& tmpError, const auto& tmpName) {
422 error = tmpError;
423 if (error != Error::NONE) {
424 return;
425 }
426
Chia-I Wu67e376d2016-12-19 11:36:22 +0800427 *outName = tmpName.c_str();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800428 });
429
430 return error;
431}
432
433Error Composer::getDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800434 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
435 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800436{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800437 mReader.takeDisplayRequests(display, outDisplayRequestMask,
438 outLayers, outLayerRequestMasks);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800439 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800440}
441
Chia-I Wu67e376d2016-12-19 11:36:22 +0800442Error Composer::getDisplayType(Display display,
443 IComposerClient::DisplayType* outType)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800444{
445 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800446 mClient->getDisplayType(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800447 [&](const auto& tmpError, const auto& tmpType) {
448 error = tmpError;
449 if (error != Error::NONE) {
450 return;
451 }
452
Chia-I Wu67e376d2016-12-19 11:36:22 +0800453 *outType = tmpType;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800454 });
455
456 return error;
457}
458
Chia-I Wu67e376d2016-12-19 11:36:22 +0800459Error Composer::getDozeSupport(Display display, bool* outSupport)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800460{
461 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800462 mClient->getDozeSupport(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800463 [&](const auto& tmpError, const auto& tmpSupport) {
464 error = tmpError;
465 if (error != Error::NONE) {
466 return;
467 }
468
Chia-I Wu67e376d2016-12-19 11:36:22 +0800469 *outSupport = tmpSupport;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800470 });
471
472 return error;
473}
474
Chia-I Wu67e376d2016-12-19 11:36:22 +0800475Error Composer::getHdrCapabilities(Display display,
476 std::vector<Hdr>* outTypes, float* outMaxLuminance,
477 float* outMaxAverageLuminance, float* outMinLuminance)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800478{
479 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800480 mClient->getHdrCapabilities(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800481 [&](const auto& tmpError, const auto& tmpTypes,
482 const auto& tmpMaxLuminance,
483 const auto& tmpMaxAverageLuminance,
484 const auto& tmpMinLuminance) {
485 error = tmpError;
486 if (error != Error::NONE) {
487 return;
488 }
489
Chia-I Wu67e376d2016-12-19 11:36:22 +0800490 *outTypes = tmpTypes;
491 *outMaxLuminance = tmpMaxLuminance;
492 *outMaxAverageLuminance = tmpMaxAverageLuminance;
493 *outMinLuminance = tmpMinLuminance;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800494 });
495
496 return error;
497}
498
Chia-I Wu67e376d2016-12-19 11:36:22 +0800499Error Composer::getReleaseFences(Display display,
500 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800501{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800502 mReader.takeReleaseFences(display, outLayers, outReleaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800503 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800504}
505
Chia-I Wu67e376d2016-12-19 11:36:22 +0800506Error Composer::presentDisplay(Display display, int* outPresentFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800507{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800508 mWriter.selectDisplay(display);
509 mWriter.presentDisplay();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800510
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800511 Error error = execute();
512 if (error != Error::NONE) {
513 return error;
514 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800515
Chia-I Wu67e376d2016-12-19 11:36:22 +0800516 mReader.takePresentFence(display, outPresentFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800517
518 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800519}
520
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800521Error Composer::setActiveConfig(Display display, Config config)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800522{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800523 auto ret = mClient->setActiveConfig(display, config);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800524 return unwrapRet(ret);
525}
526
Chia-I Wu06d63de2017-01-04 14:58:51 +0800527Error Composer::setClientTarget(Display display, uint32_t slot,
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400528 const sp<GraphicBuffer>& target,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800529 int acquireFence, Dataspace dataspace,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800530 const std::vector<IComposerClient::Rect>& damage)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800531{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800532 mWriter.selectDisplay(display);
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400533 if (mIsUsingVrComposer && target.get()) {
534 IVrComposerClient::BufferMetadata metadata = {
535 .width = target->getWidth(),
536 .height = target->getHeight(),
537 .stride = target->getStride(),
538 .layerCount = target->getLayerCount(),
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700539 .format = static_cast<types::V1_0::PixelFormat>(target->getPixelFormat()),
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400540 .usage = target->getUsage(),
541 };
542 mWriter.setClientTargetMetadata(metadata);
543 }
544
545 const native_handle_t* handle = nullptr;
546 if (target.get()) {
547 handle = target->getNativeBuffer()->handle;
548 }
549
550 mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800551 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800552}
553
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700554Error Composer::setColorMode(Display display, ColorMode mode,
555 RenderIntent renderIntent)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800556{
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700557 hardware::Return<Error> ret(kDefaultError);
558 if (mClient_2_2) {
559 ret = mClient_2_2->setColorMode_2_2(display, mode, renderIntent);
560 } else {
561 ret = mClient->setColorMode(display,
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700562 static_cast<types::V1_0::ColorMode>(mode));
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700563 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800564 return unwrapRet(ret);
565}
566
567Error Composer::setColorTransform(Display display, const float* matrix,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800568 ColorTransform hint)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800569{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800570 mWriter.selectDisplay(display);
571 mWriter.setColorTransform(matrix, hint);
572 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800573}
574
575Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800576 int releaseFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800577{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800578 mWriter.selectDisplay(display);
579 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
580 return Error::NONE;
581}
Chia-I Wuaab99f52016-10-05 12:59:58 +0800582
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700583Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode) {
584 Return<Error> ret(Error::UNSUPPORTED);
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700585 if (mClient_2_2) {
586 ret = mClient_2_2->setPowerMode_2_2(display, mode);
587 } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) {
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700588 ret = mClient->setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700589 }
590
Chia-I Wuaab99f52016-10-05 12:59:58 +0800591 return unwrapRet(ret);
592}
593
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800594Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800595{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800596 auto ret = mClient->setVsyncEnabled(display, enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800597 return unwrapRet(ret);
598}
599
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800600Error Composer::setClientTargetSlotCount(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800601{
Chia-I Wu06d63de2017-01-04 14:58:51 +0800602 const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800603 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800604 return unwrapRet(ret);
605}
606
Chia-I Wu67e376d2016-12-19 11:36:22 +0800607Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
608 uint32_t* outNumRequests)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800609{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800610 mWriter.selectDisplay(display);
611 mWriter.validateDisplay();
612
613 Error error = execute();
614 if (error != Error::NONE) {
615 return error;
616 }
617
Chia-I Wu67e376d2016-12-19 11:36:22 +0800618 mReader.hasChanges(display, outNumTypes, outNumRequests);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800619
620 return Error::NONE;
621}
622
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700623Error Composer::presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
624 uint32_t* outNumRequests, int* outPresentFence, uint32_t* state) {
625 mWriter.selectDisplay(display);
626 mWriter.presentOrvalidateDisplay();
627
628 Error error = execute();
629 if (error != Error::NONE) {
630 return error;
631 }
632
633 mReader.takePresentOrValidateStage(display, state);
634
635 if (*state == 1) { // Present succeeded
636 mReader.takePresentFence(display, outPresentFence);
637 }
638
639 if (*state == 0) { // Validate succeeded.
640 mReader.hasChanges(display, outNumTypes, outNumRequests);
641 }
642
643 return Error::NONE;
644}
645
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800646Error Composer::setCursorPosition(Display display, Layer layer,
647 int32_t x, int32_t y)
648{
649 mWriter.selectDisplay(display);
650 mWriter.selectLayer(layer);
651 mWriter.setLayerCursorPosition(x, y);
652 return Error::NONE;
653}
654
655Error Composer::setLayerBuffer(Display display, Layer layer,
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400656 uint32_t slot, const sp<GraphicBuffer>& buffer, int acquireFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800657{
658 mWriter.selectDisplay(display);
659 mWriter.selectLayer(layer);
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400660 if (mIsUsingVrComposer && buffer.get()) {
661 IVrComposerClient::BufferMetadata metadata = {
662 .width = buffer->getWidth(),
663 .height = buffer->getHeight(),
664 .stride = buffer->getStride(),
665 .layerCount = buffer->getLayerCount(),
Dominik Laskowski6231aaf2018-04-02 17:10:23 -0700666 .format = static_cast<types::V1_0::PixelFormat>(buffer->getPixelFormat()),
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400667 .usage = buffer->getUsage(),
668 };
669 mWriter.setLayerBufferMetadata(metadata);
670 }
671
672 const native_handle_t* handle = nullptr;
673 if (buffer.get()) {
674 handle = buffer->getNativeBuffer()->handle;
675 }
676
677 mWriter.setLayerBuffer(slot, handle, acquireFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800678 return Error::NONE;
679}
680
681Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
682 const std::vector<IComposerClient::Rect>& damage)
683{
684 mWriter.selectDisplay(display);
685 mWriter.selectLayer(layer);
686 mWriter.setLayerSurfaceDamage(damage);
687 return Error::NONE;
688}
689
690Error Composer::setLayerBlendMode(Display display, Layer layer,
691 IComposerClient::BlendMode mode)
692{
693 mWriter.selectDisplay(display);
694 mWriter.selectLayer(layer);
695 mWriter.setLayerBlendMode(mode);
696 return Error::NONE;
697}
698
699Error Composer::setLayerColor(Display display, Layer layer,
700 const IComposerClient::Color& color)
701{
702 mWriter.selectDisplay(display);
703 mWriter.selectLayer(layer);
704 mWriter.setLayerColor(color);
705 return Error::NONE;
706}
707
708Error Composer::setLayerCompositionType(Display display, Layer layer,
709 IComposerClient::Composition type)
710{
711 mWriter.selectDisplay(display);
712 mWriter.selectLayer(layer);
713 mWriter.setLayerCompositionType(type);
714 return Error::NONE;
715}
716
717Error Composer::setLayerDataspace(Display display, Layer layer,
718 Dataspace dataspace)
719{
720 mWriter.selectDisplay(display);
721 mWriter.selectLayer(layer);
722 mWriter.setLayerDataspace(dataspace);
723 return Error::NONE;
724}
725
726Error Composer::setLayerDisplayFrame(Display display, Layer layer,
727 const IComposerClient::Rect& frame)
728{
729 mWriter.selectDisplay(display);
730 mWriter.selectLayer(layer);
731 mWriter.setLayerDisplayFrame(frame);
732 return Error::NONE;
733}
734
735Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
736 float alpha)
737{
738 mWriter.selectDisplay(display);
739 mWriter.selectLayer(layer);
740 mWriter.setLayerPlaneAlpha(alpha);
741 return Error::NONE;
742}
743
744Error Composer::setLayerSidebandStream(Display display, Layer layer,
745 const native_handle_t* stream)
746{
747 mWriter.selectDisplay(display);
748 mWriter.selectLayer(layer);
749 mWriter.setLayerSidebandStream(stream);
750 return Error::NONE;
751}
752
753Error Composer::setLayerSourceCrop(Display display, Layer layer,
754 const IComposerClient::FRect& crop)
755{
756 mWriter.selectDisplay(display);
757 mWriter.selectLayer(layer);
758 mWriter.setLayerSourceCrop(crop);
759 return Error::NONE;
760}
761
762Error Composer::setLayerTransform(Display display, Layer layer,
763 Transform transform)
764{
765 mWriter.selectDisplay(display);
766 mWriter.selectLayer(layer);
767 mWriter.setLayerTransform(transform);
768 return Error::NONE;
769}
770
771Error Composer::setLayerVisibleRegion(Display display, Layer layer,
772 const std::vector<IComposerClient::Rect>& visible)
773{
774 mWriter.selectDisplay(display);
775 mWriter.selectLayer(layer);
776 mWriter.setLayerVisibleRegion(visible);
777 return Error::NONE;
778}
779
780Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
781{
782 mWriter.selectDisplay(display);
783 mWriter.selectLayer(layer);
784 mWriter.setLayerZOrder(z);
785 return Error::NONE;
786}
787
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500788Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
789 uint32_t appId)
790{
Hendrik Wagenaar87670ff2017-02-01 12:10:46 -0800791 if (mIsUsingVrComposer) {
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500792 mWriter.selectDisplay(display);
793 mWriter.selectLayer(layer);
794 mWriter.setLayerInfo(type, appId);
795 }
796 return Error::NONE;
797}
798
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800799Error Composer::execute()
800{
801 // prepare input command queue
802 bool queueChanged = false;
803 uint32_t commandLength = 0;
804 hidl_vec<hidl_handle> commandHandles;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800805 if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800806 mWriter.reset();
807 return Error::NO_RESOURCES;
808 }
809
810 // set up new input command queue if necessary
811 if (queueChanged) {
812 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
813 auto error = unwrapRet(ret);
814 if (error != Error::NONE) {
815 mWriter.reset();
816 return error;
817 }
818 }
819
Chia-I Wuae5a6b82017-10-10 09:09:22 -0700820 if (commandLength == 0) {
821 mWriter.reset();
822 return Error::NONE;
823 }
824
Chia-I Wuaab99f52016-10-05 12:59:58 +0800825 Error error = kDefaultError;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700826 hardware::Return<void> ret;
827 auto hidl_callback = [&](const auto& tmpError, const auto& tmpOutChanged,
828 const auto& tmpOutLength, const auto& tmpOutHandles)
829 {
830 error = tmpError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800831
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700832 // set up new output command queue if necessary
833 if (error == Error::NONE && tmpOutChanged) {
834 error = kDefaultError;
835 mClient->getOutputCommandQueue(
836 [&](const auto& tmpError,
837 const auto& tmpDescriptor)
838 {
839 error = tmpError;
840 if (error != Error::NONE) {
841 return;
842 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800843
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700844 mReader.setMQDescriptor(tmpDescriptor);
845 });
846 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800847
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700848 if (error != Error::NONE) {
849 return;
850 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800851
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700852 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
853 error = mReader.parse();
854 mReader.reset();
855 } else {
856 error = Error::NO_RESOURCES;
857 }
858 };
859 if (mClient_2_2) {
860 ret = mClient_2_2->executeCommands_2_2(commandLength, commandHandles, hidl_callback);
861 } else {
862 ret = mClient->executeCommands(commandLength, commandHandles, hidl_callback);
863 }
Chia-I Wuc0b2b0c2017-09-08 10:14:34 -0700864 // executeCommands can fail because of out-of-fd and we do not want to
865 // abort() in that case
866 if (!ret.isOk()) {
867 ALOGE("executeCommands failed because of %s", ret.description().c_str());
868 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800869
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800870 if (error == Error::NONE) {
871 std::vector<CommandReader::CommandError> commandErrors =
872 mReader.takeErrors();
873
874 for (const auto& cmdErr : commandErrors) {
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700875 auto command =
876 static_cast<IComposerClient::Command>(mWriter.getCommand(cmdErr.location));
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800877
878 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700879 command == IComposerClient::Command::PRESENT_DISPLAY ||
880 command == IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800881 error = cmdErr.error;
882 } else {
883 ALOGW("command 0x%x generated error %d",
884 command, cmdErr.error);
885 }
886 }
887 }
888
889 mWriter.reset();
890
Chia-I Wuaab99f52016-10-05 12:59:58 +0800891 return error;
892}
893
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700894// Composer HAL 2.2
895
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700896Error Composer::setLayerPerFrameMetadata(Display display, Layer layer,
897 const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) {
898 if (!mClient_2_2) {
899 return Error::UNSUPPORTED;
900 }
901
902 mWriter.selectDisplay(display);
903 mWriter.selectLayer(layer);
904 mWriter.setLayerPerFrameMetadata(perFrameMetadatas);
905 return Error::NONE;
906}
907
Chia-I Wud7e01d72018-06-21 13:39:09 +0800908std::vector<IComposerClient::PerFrameMetadataKey> Composer::getPerFrameMetadataKeys(
909 Display display) {
910 std::vector<IComposerClient::PerFrameMetadataKey> keys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700911 if (!mClient_2_2) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800912 return keys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700913 }
914
915 Error error = kDefaultError;
916 mClient_2_2->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
917 error = tmpError;
918 if (error != Error::NONE) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800919 ALOGW("getPerFrameMetadataKeys failed with %d", tmpError);
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700920 return;
921 }
922
Chia-I Wud7e01d72018-06-21 13:39:09 +0800923 keys = tmpKeys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700924 });
925
Chia-I Wud7e01d72018-06-21 13:39:09 +0800926 return keys;
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700927}
928
929Error Composer::getRenderIntents(Display display, ColorMode colorMode,
930 std::vector<RenderIntent>* outRenderIntents) {
931 if (!mClient_2_2) {
932 outRenderIntents->push_back(RenderIntent::COLORIMETRIC);
933 return Error::NONE;
934 }
935
936 Error error = kDefaultError;
937 mClient_2_2->getRenderIntents(display, colorMode,
938 [&](const auto& tmpError, const auto& tmpKeys) {
939 error = tmpError;
940 if (error != Error::NONE) {
941 return;
942 }
943
944 *outRenderIntents = tmpKeys;
945 });
946
947 return error;
948}
949
950Error Composer::getDataspaceSaturationMatrix(Dataspace dataspace, mat4* outMatrix)
951{
952 if (!mClient_2_2) {
953 *outMatrix = mat4();
954 return Error::NONE;
955 }
956
957 Error error = kDefaultError;
958 mClient_2_2->getDataspaceSaturationMatrix(dataspace, [&](const auto& tmpError, const auto& tmpMatrix) {
959 error = tmpError;
960 if (error != Error::NONE) {
961 return;
962 }
963
964 *outMatrix = mat4(tmpMatrix.data());
965 });
966
967 return error;
968}
969
Dominik Laskowskie9ef7c42018-03-12 19:34:30 -0700970// Composer HAL 2.3
971
972Error Composer::getDisplayIdentificationData(Display display, uint8_t* outPort,
973 std::vector<uint8_t>* outData) {
974 if (!mClient_2_3) {
975 return Error::UNSUPPORTED;
976 }
977
978 Error error = kDefaultError;
979 mClient_2_3->getDisplayIdentificationData(display,
980 [&](const auto& tmpError, const auto& tmpPort,
981 const auto& tmpData) {
982 error = tmpError;
983 if (error != Error::NONE) {
984 return;
985 }
986
987 *outPort = tmpPort;
988 *outData = tmpData;
989 });
990
991 return error;
992}
993
Peiyong Lin698147a2018-09-14 13:27:18 -0700994Error Composer::setLayerColorTransform(Display display, Layer layer, const float* matrix)
995{
996 if (!mClient_2_3) {
997 return Error::UNSUPPORTED;
998 }
999
1000 mWriter.selectDisplay(display);
1001 mWriter.selectLayer(layer);
1002 mWriter.setLayerColorTransform(matrix);
1003 return Error::NONE;
1004}
1005
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001006CommandReader::~CommandReader()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001007{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001008 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001009}
1010
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001011Error CommandReader::parse()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001012{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001013 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001014
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001015 IComposerClient::Command command;
1016 uint16_t length = 0;
1017
1018 while (!isEmpty()) {
Dominik Laskowski6231aaf2018-04-02 17:10:23 -07001019 auto command_2_1 = reinterpret_cast<V2_1::IComposerClient::Command*>(&command);
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -07001020 if (!beginCommand(command_2_1, &length)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001021 break;
1022 }
1023
1024 bool parsed = false;
1025 switch (command) {
1026 case IComposerClient::Command::SELECT_DISPLAY:
1027 parsed = parseSelectDisplay(length);
1028 break;
1029 case IComposerClient::Command::SET_ERROR:
1030 parsed = parseSetError(length);
1031 break;
1032 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
1033 parsed = parseSetChangedCompositionTypes(length);
1034 break;
1035 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
1036 parsed = parseSetDisplayRequests(length);
1037 break;
1038 case IComposerClient::Command::SET_PRESENT_FENCE:
1039 parsed = parseSetPresentFence(length);
1040 break;
1041 case IComposerClient::Command::SET_RELEASE_FENCES:
1042 parsed = parseSetReleaseFences(length);
1043 break;
Fabien Sanglard249c0ae2017-06-19 19:22:36 -07001044 case IComposerClient::Command ::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT:
1045 parsed = parseSetPresentOrValidateDisplayResult(length);
1046 break;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001047 default:
1048 parsed = false;
1049 break;
1050 }
1051
1052 endCommand();
1053
1054 if (!parsed) {
1055 ALOGE("failed to parse command 0x%x length %" PRIu16,
1056 command, length);
1057 break;
1058 }
1059 }
1060
1061 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001062}
1063
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001064bool CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001065{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -05001066 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001067 return false;
1068 }
Chia-I Wuaab99f52016-10-05 12:59:58 +08001069
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001070 mCurrentReturnData = &mReturnData[read64()];
1071
1072 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001073}
1074
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001075bool CommandReader::parseSetError(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001076{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -05001077 if (length != CommandWriterBase::kSetErrorLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001078 return false;
1079 }
1080
1081 auto location = read();
1082 auto error = static_cast<Error>(readSigned());
1083
1084 mErrors.emplace_back(CommandError{location, error});
1085
1086 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001087}
1088
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001089bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001090{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001091 // (layer id, composition type) pairs
1092 if (length % 3 != 0 || !mCurrentReturnData) {
1093 return false;
1094 }
1095
1096 uint32_t count = length / 3;
1097 mCurrentReturnData->changedLayers.reserve(count);
1098 mCurrentReturnData->compositionTypes.reserve(count);
1099 while (count > 0) {
1100 auto layer = read64();
1101 auto type = static_cast<IComposerClient::Composition>(readSigned());
1102
1103 mCurrentReturnData->changedLayers.push_back(layer);
1104 mCurrentReturnData->compositionTypes.push_back(type);
1105
1106 count--;
1107 }
1108
1109 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001110}
1111
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001112bool CommandReader::parseSetDisplayRequests(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001113{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001114 // display requests followed by (layer id, layer requests) pairs
1115 if (length % 3 != 1 || !mCurrentReturnData) {
1116 return false;
1117 }
1118
1119 mCurrentReturnData->displayRequests = read();
1120
1121 uint32_t count = (length - 1) / 3;
1122 mCurrentReturnData->requestedLayers.reserve(count);
1123 mCurrentReturnData->requestMasks.reserve(count);
1124 while (count > 0) {
1125 auto layer = read64();
1126 auto layerRequestMask = read();
1127
1128 mCurrentReturnData->requestedLayers.push_back(layer);
1129 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
1130
1131 count--;
1132 }
1133
1134 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001135}
1136
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001137bool CommandReader::parseSetPresentFence(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001138{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -05001139 if (length != CommandWriterBase::kSetPresentFenceLength ||
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001140 !mCurrentReturnData) {
1141 return false;
1142 }
1143
1144 if (mCurrentReturnData->presentFence >= 0) {
1145 close(mCurrentReturnData->presentFence);
1146 }
1147 mCurrentReturnData->presentFence = readFence();
1148
1149 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001150}
1151
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001152bool CommandReader::parseSetReleaseFences(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001153{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001154 // (layer id, release fence index) pairs
1155 if (length % 3 != 0 || !mCurrentReturnData) {
1156 return false;
1157 }
1158
1159 uint32_t count = length / 3;
1160 mCurrentReturnData->releasedLayers.reserve(count);
1161 mCurrentReturnData->releaseFences.reserve(count);
1162 while (count > 0) {
1163 auto layer = read64();
1164 auto fence = readFence();
1165
1166 mCurrentReturnData->releasedLayers.push_back(layer);
1167 mCurrentReturnData->releaseFences.push_back(fence);
1168
1169 count--;
1170 }
1171
1172 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001173}
1174
Fabien Sanglard249c0ae2017-06-19 19:22:36 -07001175bool CommandReader::parseSetPresentOrValidateDisplayResult(uint16_t length)
1176{
1177 if (length != CommandWriterBase::kPresentOrValidateDisplayResultLength || !mCurrentReturnData) {
1178 return false;
1179 }
1180 mCurrentReturnData->presentOrValidateState = read();
1181 return true;
1182}
1183
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001184void CommandReader::resetData()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001185{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001186 mErrors.clear();
1187
1188 for (auto& data : mReturnData) {
1189 if (data.second.presentFence >= 0) {
1190 close(data.second.presentFence);
1191 }
1192 for (auto fence : data.second.releaseFences) {
1193 if (fence >= 0) {
1194 close(fence);
1195 }
1196 }
1197 }
1198
1199 mReturnData.clear();
1200 mCurrentReturnData = nullptr;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001201}
1202
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001203std::vector<CommandReader::CommandError> CommandReader::takeErrors()
Chia-I Wuaab99f52016-10-05 12:59:58 +08001204{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001205 return std::move(mErrors);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001206}
1207
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001208bool CommandReader::hasChanges(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001209 uint32_t* outNumChangedCompositionTypes,
1210 uint32_t* outNumLayerRequestMasks) const
Chia-I Wuaab99f52016-10-05 12:59:58 +08001211{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001212 auto found = mReturnData.find(display);
1213 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001214 *outNumChangedCompositionTypes = 0;
1215 *outNumLayerRequestMasks = 0;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001216 return false;
1217 }
1218
1219 const ReturnData& data = found->second;
1220
Chia-I Wu67e376d2016-12-19 11:36:22 +08001221 *outNumChangedCompositionTypes = data.compositionTypes.size();
1222 *outNumLayerRequestMasks = data.requestMasks.size();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001223
1224 return !(data.compositionTypes.empty() && data.requestMasks.empty());
Chia-I Wuaab99f52016-10-05 12:59:58 +08001225}
1226
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001227void CommandReader::takeChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001228 std::vector<Layer>* outLayers,
1229 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001230{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001231 auto found = mReturnData.find(display);
1232 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001233 outLayers->clear();
1234 outTypes->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001235 return;
1236 }
1237
1238 ReturnData& data = found->second;
1239
Chia-I Wu67e376d2016-12-19 11:36:22 +08001240 *outLayers = std::move(data.changedLayers);
1241 *outTypes = std::move(data.compositionTypes);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001242}
1243
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001244void CommandReader::takeDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001245 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
1246 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001247{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001248 auto found = mReturnData.find(display);
1249 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001250 *outDisplayRequestMask = 0;
1251 outLayers->clear();
1252 outLayerRequestMasks->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001253 return;
1254 }
Chia-I Wuaab99f52016-10-05 12:59:58 +08001255
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001256 ReturnData& data = found->second;
1257
Chia-I Wu67e376d2016-12-19 11:36:22 +08001258 *outDisplayRequestMask = data.displayRequests;
1259 *outLayers = std::move(data.requestedLayers);
1260 *outLayerRequestMasks = std::move(data.requestMasks);
Chia-I Wuaab99f52016-10-05 12:59:58 +08001261}
1262
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001263void CommandReader::takeReleaseFences(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +08001264 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +08001265{
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001266 auto found = mReturnData.find(display);
1267 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001268 outLayers->clear();
1269 outReleaseFences->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001270 return;
1271 }
1272
1273 ReturnData& data = found->second;
1274
Chia-I Wu67e376d2016-12-19 11:36:22 +08001275 *outLayers = std::move(data.releasedLayers);
1276 *outReleaseFences = std::move(data.releaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001277}
1278
Chia-I Wu67e376d2016-12-19 11:36:22 +08001279void CommandReader::takePresentFence(Display display, int* outPresentFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001280{
1281 auto found = mReturnData.find(display);
1282 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +08001283 *outPresentFence = -1;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001284 return;
1285 }
1286
1287 ReturnData& data = found->second;
1288
Chia-I Wu67e376d2016-12-19 11:36:22 +08001289 *outPresentFence = data.presentFence;
Chia-I Wucd8d7f02016-11-16 11:02:31 +08001290 data.presentFence = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +08001291}
1292
Fabien Sanglard249c0ae2017-06-19 19:22:36 -07001293void CommandReader::takePresentOrValidateStage(Display display, uint32_t* state) {
1294 auto found = mReturnData.find(display);
1295 if (found == mReturnData.end()) {
1296 *state= -1;
1297 return;
1298 }
1299 ReturnData& data = found->second;
1300 *state = data.presentOrValidateState;
1301}
1302
Lloyd Piquea822d522017-12-20 16:42:57 -08001303} // namespace impl
1304
Chia-I Wuaab99f52016-10-05 12:59:58 +08001305} // namespace Hwc2
1306
1307} // namespace android