blob: 6cb1af19ecbd8729205b7fc4a888ff1e44eaab24 [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
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -050020#include <android/dvr/composer/1.0/IVrComposerClient.h>
Chia-I Wuaab99f52016-10-05 12:59:58 +080021#include <inttypes.h>
22#include <log/log.h>
Chia-I Wu06d63de2017-01-04 14:58:51 +080023#include <gui/BufferQueue.h>
Chia-I Wuaab99f52016-10-05 12:59:58 +080024
25#include "ComposerHal.h"
26
27namespace android {
28
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -050029using dvr::composer::V1_0::IVrComposerClient;
Chia-I Wuaab99f52016-10-05 12:59:58 +080030using hardware::Return;
31using hardware::hidl_vec;
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010032using hardware::hidl_handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080033
34namespace Hwc2 {
35
36namespace {
37
38class BufferHandle {
39public:
40 BufferHandle(const native_handle_t* buffer)
41 {
42 // nullptr is not a valid handle to HIDL
43 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
44 }
45
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010046 operator const hidl_handle&() const
Chia-I Wuaab99f52016-10-05 12:59:58 +080047 {
48 return mHandle;
49 }
50
51private:
52 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010053 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080054};
55
56class FenceHandle
57{
58public:
59 FenceHandle(int fd, bool owned)
60 : mOwned(owned)
61 {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010062 native_handle_t* handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080063 if (fd >= 0) {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010064 handle = native_handle_init(mStorage, 1, 0);
65 handle->data[0] = fd;
Chia-I Wuaab99f52016-10-05 12:59:58 +080066 } else {
67 // nullptr is not a valid handle to HIDL
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010068 handle = native_handle_init(mStorage, 0, 0);
Chia-I Wuaab99f52016-10-05 12:59:58 +080069 }
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010070 mHandle = handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080071 }
72
73 ~FenceHandle()
74 {
75 if (mOwned) {
76 native_handle_close(mHandle);
77 }
78 }
79
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010080 operator const hidl_handle&() const
Chia-I Wuaab99f52016-10-05 12:59:58 +080081 {
82 return mHandle;
83 }
84
85private:
86 bool mOwned;
87 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010088 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080089};
90
91// assume NO_RESOURCES when Status::isOk returns false
92constexpr Error kDefaultError = Error::NO_RESOURCES;
93
94template<typename T, typename U>
95T unwrapRet(Return<T>& ret, const U& default_val)
96{
Steven Moreland9d021002017-01-03 17:10:54 -080097 return (ret.isOk()) ? static_cast<T>(ret) :
Chia-I Wuaab99f52016-10-05 12:59:58 +080098 static_cast<T>(default_val);
99}
100
101Error unwrapRet(Return<Error>& ret)
102{
103 return unwrapRet(ret, kDefaultError);
104}
105
Chia-I Wuaab99f52016-10-05 12:59:58 +0800106} // anonymous namespace
107
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500108Composer::CommandWriter::CommandWriter(uint32_t initialMaxSize)
109 : CommandWriterBase(initialMaxSize) {}
110
111Composer::CommandWriter::~CommandWriter()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800112{
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500113}
114
115void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
116{
117 constexpr uint16_t kSetLayerInfoLength = 2;
118 beginCommand(
119 static_cast<IComposerClient::Command>(
120 IVrComposerClient::VrCommand::SET_LAYER_INFO),
121 kSetLayerInfoLength);
122 write(type);
123 write(appId);
124 endCommand();
125}
126
127Composer::Composer() : mWriter(kWriterInitialSize)
128{
129#if defined(IN_VR_MODE)
130 mIsInVrMode = true;
131#endif
132
133 if (mIsInVrMode) {
134 mComposer = IComposer::getService("vr_hwcomposer");
135 } else {
136 mComposer = IComposer::getService("hwcomposer");
137 }
138
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800139 if (mComposer == nullptr) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800140 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
141 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800142
143 mComposer->createClient(
144 [&](const auto& tmpError, const auto& tmpClient)
145 {
146 if (tmpError == Error::NONE) {
147 mClient = tmpClient;
148 }
149 });
150 if (mClient == nullptr) {
151 LOG_ALWAYS_FATAL("failed to create composer client");
152 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800153}
154
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800155std::vector<IComposer::Capability> Composer::getCapabilities()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800156{
157 std::vector<IComposer::Capability> capabilities;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800158 mComposer->getCapabilities(
Chia-I Wuaab99f52016-10-05 12:59:58 +0800159 [&](const auto& tmpCapabilities) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800160 capabilities = tmpCapabilities;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800161 });
162
163 return capabilities;
164}
165
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800166std::string Composer::dumpDebugInfo()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800167{
168 std::string info;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800169 mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800170 info = tmpInfo.c_str();
171 });
172
173 return info;
174}
175
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800176void Composer::registerCallback(const sp<IComposerCallback>& callback)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800177{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800178 auto ret = mClient->registerCallback(callback);
Steven Moreland9d021002017-01-03 17:10:54 -0800179 if (!ret.isOk()) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800180 ALOGE("failed to register IComposerCallback");
181 }
182}
183
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800184uint32_t Composer::getMaxVirtualDisplayCount()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800185{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800186 auto ret = mClient->getMaxVirtualDisplayCount();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800187 return unwrapRet(ret, 0);
188}
189
190Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800191 PixelFormat* format, Display* outDisplay)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800192{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800193 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800194 Error error = kDefaultError;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800195 mClient->createVirtualDisplay(width, height, *format, bufferSlotCount,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800196 [&](const auto& tmpError, const auto& tmpDisplay,
197 const auto& tmpFormat) {
198 error = tmpError;
199 if (error != Error::NONE) {
200 return;
201 }
202
Chia-I Wu67e376d2016-12-19 11:36:22 +0800203 *outDisplay = tmpDisplay;
204 *format = tmpFormat;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800205 });
206
207 return error;
208}
209
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800210Error Composer::destroyVirtualDisplay(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800211{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800212 auto ret = mClient->destroyVirtualDisplay(display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800213 return unwrapRet(ret);
214}
215
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800216Error Composer::acceptDisplayChanges(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800217{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800218 mWriter.selectDisplay(display);
219 mWriter.acceptDisplayChanges();
220 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800221}
222
Chia-I Wu67e376d2016-12-19 11:36:22 +0800223Error Composer::createLayer(Display display, Layer* outLayer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800224{
225 Error error = kDefaultError;
Chia-I Wu06d63de2017-01-04 14:58:51 +0800226 mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800227 [&](const auto& tmpError, const auto& tmpLayer) {
228 error = tmpError;
229 if (error != Error::NONE) {
230 return;
231 }
232
Chia-I Wu67e376d2016-12-19 11:36:22 +0800233 *outLayer = tmpLayer;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800234 });
235
236 return error;
237}
238
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800239Error Composer::destroyLayer(Display display, Layer layer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800240{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800241 auto ret = mClient->destroyLayer(display, layer);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800242 return unwrapRet(ret);
243}
244
Chia-I Wu67e376d2016-12-19 11:36:22 +0800245Error Composer::getActiveConfig(Display display, Config* outConfig)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800246{
247 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800248 mClient->getActiveConfig(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800249 [&](const auto& tmpError, const auto& tmpConfig) {
250 error = tmpError;
251 if (error != Error::NONE) {
252 return;
253 }
254
Chia-I Wu67e376d2016-12-19 11:36:22 +0800255 *outConfig = tmpConfig;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800256 });
257
258 return error;
259}
260
261Error Composer::getChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800262 std::vector<Layer>* outLayers,
263 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800264{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800265 mReader.takeChangedCompositionTypes(display, outLayers, outTypes);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800266 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800267}
268
269Error Composer::getColorModes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800270 std::vector<ColorMode>* outModes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800271{
272 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800273 mClient->getColorModes(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800274 [&](const auto& tmpError, const auto& tmpModes) {
275 error = tmpError;
276 if (error != Error::NONE) {
277 return;
278 }
279
Chia-I Wu67e376d2016-12-19 11:36:22 +0800280 *outModes = tmpModes;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800281 });
282
283 return error;
284}
285
286Error Composer::getDisplayAttribute(Display display, Config config,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800287 IComposerClient::Attribute attribute, int32_t* outValue)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800288{
289 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800290 mClient->getDisplayAttribute(display, config, attribute,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800291 [&](const auto& tmpError, const auto& tmpValue) {
292 error = tmpError;
293 if (error != Error::NONE) {
294 return;
295 }
296
Chia-I Wu67e376d2016-12-19 11:36:22 +0800297 *outValue = tmpValue;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800298 });
299
300 return error;
301}
302
303Error Composer::getDisplayConfigs(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800304 std::vector<Config>* outConfigs)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800305{
306 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800307 mClient->getDisplayConfigs(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800308 [&](const auto& tmpError, const auto& tmpConfigs) {
309 error = tmpError;
310 if (error != Error::NONE) {
311 return;
312 }
313
Chia-I Wu67e376d2016-12-19 11:36:22 +0800314 *outConfigs = tmpConfigs;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800315 });
316
317 return error;
318}
319
Chia-I Wu67e376d2016-12-19 11:36:22 +0800320Error Composer::getDisplayName(Display display, std::string* outName)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800321{
322 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800323 mClient->getDisplayName(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800324 [&](const auto& tmpError, const auto& tmpName) {
325 error = tmpError;
326 if (error != Error::NONE) {
327 return;
328 }
329
Chia-I Wu67e376d2016-12-19 11:36:22 +0800330 *outName = tmpName.c_str();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800331 });
332
333 return error;
334}
335
336Error Composer::getDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800337 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
338 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800339{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800340 mReader.takeDisplayRequests(display, outDisplayRequestMask,
341 outLayers, outLayerRequestMasks);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800342 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800343}
344
Chia-I Wu67e376d2016-12-19 11:36:22 +0800345Error Composer::getDisplayType(Display display,
346 IComposerClient::DisplayType* outType)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800347{
348 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800349 mClient->getDisplayType(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800350 [&](const auto& tmpError, const auto& tmpType) {
351 error = tmpError;
352 if (error != Error::NONE) {
353 return;
354 }
355
Chia-I Wu67e376d2016-12-19 11:36:22 +0800356 *outType = tmpType;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800357 });
358
359 return error;
360}
361
Chia-I Wu67e376d2016-12-19 11:36:22 +0800362Error Composer::getDozeSupport(Display display, bool* outSupport)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800363{
364 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800365 mClient->getDozeSupport(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800366 [&](const auto& tmpError, const auto& tmpSupport) {
367 error = tmpError;
368 if (error != Error::NONE) {
369 return;
370 }
371
Chia-I Wu67e376d2016-12-19 11:36:22 +0800372 *outSupport = tmpSupport;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800373 });
374
375 return error;
376}
377
Chia-I Wu67e376d2016-12-19 11:36:22 +0800378Error Composer::getHdrCapabilities(Display display,
379 std::vector<Hdr>* outTypes, float* outMaxLuminance,
380 float* outMaxAverageLuminance, float* outMinLuminance)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800381{
382 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800383 mClient->getHdrCapabilities(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800384 [&](const auto& tmpError, const auto& tmpTypes,
385 const auto& tmpMaxLuminance,
386 const auto& tmpMaxAverageLuminance,
387 const auto& tmpMinLuminance) {
388 error = tmpError;
389 if (error != Error::NONE) {
390 return;
391 }
392
Chia-I Wu67e376d2016-12-19 11:36:22 +0800393 *outTypes = tmpTypes;
394 *outMaxLuminance = tmpMaxLuminance;
395 *outMaxAverageLuminance = tmpMaxAverageLuminance;
396 *outMinLuminance = tmpMinLuminance;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800397 });
398
399 return error;
400}
401
Chia-I Wu67e376d2016-12-19 11:36:22 +0800402Error Composer::getReleaseFences(Display display,
403 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800404{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800405 mReader.takeReleaseFences(display, outLayers, outReleaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800406 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800407}
408
Chia-I Wu67e376d2016-12-19 11:36:22 +0800409Error Composer::presentDisplay(Display display, int* outPresentFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800410{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800411 mWriter.selectDisplay(display);
412 mWriter.presentDisplay();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800413
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800414 Error error = execute();
415 if (error != Error::NONE) {
416 return error;
417 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800418
Chia-I Wu67e376d2016-12-19 11:36:22 +0800419 mReader.takePresentFence(display, outPresentFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800420
421 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800422}
423
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800424Error Composer::setActiveConfig(Display display, Config config)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800425{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800426 auto ret = mClient->setActiveConfig(display, config);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800427 return unwrapRet(ret);
428}
429
Chia-I Wu06d63de2017-01-04 14:58:51 +0800430Error Composer::setClientTarget(Display display, uint32_t slot,
431 const native_handle_t* target,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800432 int acquireFence, Dataspace dataspace,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800433 const std::vector<IComposerClient::Rect>& damage)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800434{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800435 mWriter.selectDisplay(display);
Chia-I Wu06d63de2017-01-04 14:58:51 +0800436 mWriter.setClientTarget(slot, target, acquireFence, dataspace, damage);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800437 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800438}
439
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800440Error Composer::setColorMode(Display display, ColorMode mode)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800441{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800442 auto ret = mClient->setColorMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800443 return unwrapRet(ret);
444}
445
446Error Composer::setColorTransform(Display display, const float* matrix,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800447 ColorTransform hint)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800448{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800449 mWriter.selectDisplay(display);
450 mWriter.setColorTransform(matrix, hint);
451 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800452}
453
454Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800455 int releaseFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800456{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800457 mWriter.selectDisplay(display);
458 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
459 return Error::NONE;
460}
Chia-I Wuaab99f52016-10-05 12:59:58 +0800461
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800462Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
463{
464 auto ret = mClient->setPowerMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800465 return unwrapRet(ret);
466}
467
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800468Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800469{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800470 auto ret = mClient->setVsyncEnabled(display, enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800471 return unwrapRet(ret);
472}
473
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800474Error Composer::setClientTargetSlotCount(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800475{
Chia-I Wu06d63de2017-01-04 14:58:51 +0800476 const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800477 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800478 return unwrapRet(ret);
479}
480
Chia-I Wu67e376d2016-12-19 11:36:22 +0800481Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
482 uint32_t* outNumRequests)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800483{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800484 mWriter.selectDisplay(display);
485 mWriter.validateDisplay();
486
487 Error error = execute();
488 if (error != Error::NONE) {
489 return error;
490 }
491
Chia-I Wu67e376d2016-12-19 11:36:22 +0800492 mReader.hasChanges(display, outNumTypes, outNumRequests);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800493
494 return Error::NONE;
495}
496
497Error Composer::setCursorPosition(Display display, Layer layer,
498 int32_t x, int32_t y)
499{
500 mWriter.selectDisplay(display);
501 mWriter.selectLayer(layer);
502 mWriter.setLayerCursorPosition(x, y);
503 return Error::NONE;
504}
505
506Error Composer::setLayerBuffer(Display display, Layer layer,
Chia-I Wu06d63de2017-01-04 14:58:51 +0800507 uint32_t slot, const native_handle_t* buffer, int acquireFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800508{
509 mWriter.selectDisplay(display);
510 mWriter.selectLayer(layer);
Chia-I Wu06d63de2017-01-04 14:58:51 +0800511 mWriter.setLayerBuffer(slot, buffer, acquireFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800512 return Error::NONE;
513}
514
515Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
516 const std::vector<IComposerClient::Rect>& damage)
517{
518 mWriter.selectDisplay(display);
519 mWriter.selectLayer(layer);
520 mWriter.setLayerSurfaceDamage(damage);
521 return Error::NONE;
522}
523
524Error Composer::setLayerBlendMode(Display display, Layer layer,
525 IComposerClient::BlendMode mode)
526{
527 mWriter.selectDisplay(display);
528 mWriter.selectLayer(layer);
529 mWriter.setLayerBlendMode(mode);
530 return Error::NONE;
531}
532
533Error Composer::setLayerColor(Display display, Layer layer,
534 const IComposerClient::Color& color)
535{
536 mWriter.selectDisplay(display);
537 mWriter.selectLayer(layer);
538 mWriter.setLayerColor(color);
539 return Error::NONE;
540}
541
542Error Composer::setLayerCompositionType(Display display, Layer layer,
543 IComposerClient::Composition type)
544{
545 mWriter.selectDisplay(display);
546 mWriter.selectLayer(layer);
547 mWriter.setLayerCompositionType(type);
548 return Error::NONE;
549}
550
551Error Composer::setLayerDataspace(Display display, Layer layer,
552 Dataspace dataspace)
553{
554 mWriter.selectDisplay(display);
555 mWriter.selectLayer(layer);
556 mWriter.setLayerDataspace(dataspace);
557 return Error::NONE;
558}
559
560Error Composer::setLayerDisplayFrame(Display display, Layer layer,
561 const IComposerClient::Rect& frame)
562{
563 mWriter.selectDisplay(display);
564 mWriter.selectLayer(layer);
565 mWriter.setLayerDisplayFrame(frame);
566 return Error::NONE;
567}
568
569Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
570 float alpha)
571{
572 mWriter.selectDisplay(display);
573 mWriter.selectLayer(layer);
574 mWriter.setLayerPlaneAlpha(alpha);
575 return Error::NONE;
576}
577
578Error Composer::setLayerSidebandStream(Display display, Layer layer,
579 const native_handle_t* stream)
580{
581 mWriter.selectDisplay(display);
582 mWriter.selectLayer(layer);
583 mWriter.setLayerSidebandStream(stream);
584 return Error::NONE;
585}
586
587Error Composer::setLayerSourceCrop(Display display, Layer layer,
588 const IComposerClient::FRect& crop)
589{
590 mWriter.selectDisplay(display);
591 mWriter.selectLayer(layer);
592 mWriter.setLayerSourceCrop(crop);
593 return Error::NONE;
594}
595
596Error Composer::setLayerTransform(Display display, Layer layer,
597 Transform transform)
598{
599 mWriter.selectDisplay(display);
600 mWriter.selectLayer(layer);
601 mWriter.setLayerTransform(transform);
602 return Error::NONE;
603}
604
605Error Composer::setLayerVisibleRegion(Display display, Layer layer,
606 const std::vector<IComposerClient::Rect>& visible)
607{
608 mWriter.selectDisplay(display);
609 mWriter.selectLayer(layer);
610 mWriter.setLayerVisibleRegion(visible);
611 return Error::NONE;
612}
613
614Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
615{
616 mWriter.selectDisplay(display);
617 mWriter.selectLayer(layer);
618 mWriter.setLayerZOrder(z);
619 return Error::NONE;
620}
621
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500622Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
623 uint32_t appId)
624{
625 if (mIsInVrMode)
626 {
627 mWriter.selectDisplay(display);
628 mWriter.selectLayer(layer);
629 mWriter.setLayerInfo(type, appId);
630 }
631 return Error::NONE;
632}
633
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800634Error Composer::execute()
635{
636 // prepare input command queue
637 bool queueChanged = false;
638 uint32_t commandLength = 0;
639 hidl_vec<hidl_handle> commandHandles;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800640 if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800641 mWriter.reset();
642 return Error::NO_RESOURCES;
643 }
644
645 // set up new input command queue if necessary
646 if (queueChanged) {
647 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
648 auto error = unwrapRet(ret);
649 if (error != Error::NONE) {
650 mWriter.reset();
651 return error;
652 }
653 }
654
Chia-I Wuaab99f52016-10-05 12:59:58 +0800655 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800656 mClient->executeCommands(commandLength, commandHandles,
657 [&](const auto& tmpError, const auto& tmpOutChanged,
658 const auto& tmpOutLength, const auto& tmpOutHandles)
659 {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800660 error = tmpError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800661
662 // set up new output command queue if necessary
663 if (error == Error::NONE && tmpOutChanged) {
664 error = kDefaultError;
665 mClient->getOutputCommandQueue(
666 [&](const auto& tmpError,
667 const auto& tmpDescriptor)
668 {
669 error = tmpError;
670 if (error != Error::NONE) {
671 return;
672 }
673
674 mReader.setMQDescriptor(tmpDescriptor);
675 });
676 }
677
Chia-I Wuaab99f52016-10-05 12:59:58 +0800678 if (error != Error::NONE) {
679 return;
680 }
681
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800682 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
683 error = mReader.parse();
684 mReader.reset();
685 } else {
686 error = Error::NO_RESOURCES;
687 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800688 });
689
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800690 if (error == Error::NONE) {
691 std::vector<CommandReader::CommandError> commandErrors =
692 mReader.takeErrors();
693
694 for (const auto& cmdErr : commandErrors) {
695 auto command = mWriter.getCommand(cmdErr.location);
696
697 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
698 command == IComposerClient::Command::PRESENT_DISPLAY) {
699 error = cmdErr.error;
700 } else {
701 ALOGW("command 0x%x generated error %d",
702 command, cmdErr.error);
703 }
704 }
705 }
706
707 mWriter.reset();
708
Chia-I Wuaab99f52016-10-05 12:59:58 +0800709 return error;
710}
711
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800712CommandReader::~CommandReader()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800713{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800714 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800715}
716
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800717Error CommandReader::parse()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800718{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800719 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800720
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800721 IComposerClient::Command command;
722 uint16_t length = 0;
723
724 while (!isEmpty()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800725 if (!beginCommand(&command, &length)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800726 break;
727 }
728
729 bool parsed = false;
730 switch (command) {
731 case IComposerClient::Command::SELECT_DISPLAY:
732 parsed = parseSelectDisplay(length);
733 break;
734 case IComposerClient::Command::SET_ERROR:
735 parsed = parseSetError(length);
736 break;
737 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
738 parsed = parseSetChangedCompositionTypes(length);
739 break;
740 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
741 parsed = parseSetDisplayRequests(length);
742 break;
743 case IComposerClient::Command::SET_PRESENT_FENCE:
744 parsed = parseSetPresentFence(length);
745 break;
746 case IComposerClient::Command::SET_RELEASE_FENCES:
747 parsed = parseSetReleaseFences(length);
748 break;
749 default:
750 parsed = false;
751 break;
752 }
753
754 endCommand();
755
756 if (!parsed) {
757 ALOGE("failed to parse command 0x%x length %" PRIu16,
758 command, length);
759 break;
760 }
761 }
762
763 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800764}
765
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800766bool CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800767{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -0500768 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800769 return false;
770 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800771
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800772 mCurrentReturnData = &mReturnData[read64()];
773
774 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800775}
776
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800777bool CommandReader::parseSetError(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800778{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -0500779 if (length != CommandWriterBase::kSetErrorLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800780 return false;
781 }
782
783 auto location = read();
784 auto error = static_cast<Error>(readSigned());
785
786 mErrors.emplace_back(CommandError{location, error});
787
788 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800789}
790
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800791bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800792{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800793 // (layer id, composition type) pairs
794 if (length % 3 != 0 || !mCurrentReturnData) {
795 return false;
796 }
797
798 uint32_t count = length / 3;
799 mCurrentReturnData->changedLayers.reserve(count);
800 mCurrentReturnData->compositionTypes.reserve(count);
801 while (count > 0) {
802 auto layer = read64();
803 auto type = static_cast<IComposerClient::Composition>(readSigned());
804
805 mCurrentReturnData->changedLayers.push_back(layer);
806 mCurrentReturnData->compositionTypes.push_back(type);
807
808 count--;
809 }
810
811 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800812}
813
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800814bool CommandReader::parseSetDisplayRequests(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800815{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800816 // display requests followed by (layer id, layer requests) pairs
817 if (length % 3 != 1 || !mCurrentReturnData) {
818 return false;
819 }
820
821 mCurrentReturnData->displayRequests = read();
822
823 uint32_t count = (length - 1) / 3;
824 mCurrentReturnData->requestedLayers.reserve(count);
825 mCurrentReturnData->requestMasks.reserve(count);
826 while (count > 0) {
827 auto layer = read64();
828 auto layerRequestMask = read();
829
830 mCurrentReturnData->requestedLayers.push_back(layer);
831 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
832
833 count--;
834 }
835
836 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800837}
838
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800839bool CommandReader::parseSetPresentFence(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800840{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -0500841 if (length != CommandWriterBase::kSetPresentFenceLength ||
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800842 !mCurrentReturnData) {
843 return false;
844 }
845
846 if (mCurrentReturnData->presentFence >= 0) {
847 close(mCurrentReturnData->presentFence);
848 }
849 mCurrentReturnData->presentFence = readFence();
850
851 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800852}
853
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800854bool CommandReader::parseSetReleaseFences(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800855{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800856 // (layer id, release fence index) pairs
857 if (length % 3 != 0 || !mCurrentReturnData) {
858 return false;
859 }
860
861 uint32_t count = length / 3;
862 mCurrentReturnData->releasedLayers.reserve(count);
863 mCurrentReturnData->releaseFences.reserve(count);
864 while (count > 0) {
865 auto layer = read64();
866 auto fence = readFence();
867
868 mCurrentReturnData->releasedLayers.push_back(layer);
869 mCurrentReturnData->releaseFences.push_back(fence);
870
871 count--;
872 }
873
874 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800875}
876
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800877void CommandReader::resetData()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800878{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800879 mErrors.clear();
880
881 for (auto& data : mReturnData) {
882 if (data.second.presentFence >= 0) {
883 close(data.second.presentFence);
884 }
885 for (auto fence : data.second.releaseFences) {
886 if (fence >= 0) {
887 close(fence);
888 }
889 }
890 }
891
892 mReturnData.clear();
893 mCurrentReturnData = nullptr;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800894}
895
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800896std::vector<CommandReader::CommandError> CommandReader::takeErrors()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800897{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800898 return std::move(mErrors);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800899}
900
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800901bool CommandReader::hasChanges(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800902 uint32_t* outNumChangedCompositionTypes,
903 uint32_t* outNumLayerRequestMasks) const
Chia-I Wuaab99f52016-10-05 12:59:58 +0800904{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800905 auto found = mReturnData.find(display);
906 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800907 *outNumChangedCompositionTypes = 0;
908 *outNumLayerRequestMasks = 0;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800909 return false;
910 }
911
912 const ReturnData& data = found->second;
913
Chia-I Wu67e376d2016-12-19 11:36:22 +0800914 *outNumChangedCompositionTypes = data.compositionTypes.size();
915 *outNumLayerRequestMasks = data.requestMasks.size();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800916
917 return !(data.compositionTypes.empty() && data.requestMasks.empty());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800918}
919
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800920void CommandReader::takeChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800921 std::vector<Layer>* outLayers,
922 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800923{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800924 auto found = mReturnData.find(display);
925 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800926 outLayers->clear();
927 outTypes->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800928 return;
929 }
930
931 ReturnData& data = found->second;
932
Chia-I Wu67e376d2016-12-19 11:36:22 +0800933 *outLayers = std::move(data.changedLayers);
934 *outTypes = std::move(data.compositionTypes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800935}
936
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800937void CommandReader::takeDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800938 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
939 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800940{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800941 auto found = mReturnData.find(display);
942 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800943 *outDisplayRequestMask = 0;
944 outLayers->clear();
945 outLayerRequestMasks->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800946 return;
947 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800948
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800949 ReturnData& data = found->second;
950
Chia-I Wu67e376d2016-12-19 11:36:22 +0800951 *outDisplayRequestMask = data.displayRequests;
952 *outLayers = std::move(data.requestedLayers);
953 *outLayerRequestMasks = std::move(data.requestMasks);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800954}
955
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800956void CommandReader::takeReleaseFences(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800957 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800958{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800959 auto found = mReturnData.find(display);
960 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800961 outLayers->clear();
962 outReleaseFences->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800963 return;
964 }
965
966 ReturnData& data = found->second;
967
Chia-I Wu67e376d2016-12-19 11:36:22 +0800968 *outLayers = std::move(data.releasedLayers);
969 *outReleaseFences = std::move(data.releaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800970}
971
Chia-I Wu67e376d2016-12-19 11:36:22 +0800972void CommandReader::takePresentFence(Display display, int* outPresentFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800973{
974 auto found = mReturnData.find(display);
975 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800976 *outPresentFence = -1;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800977 return;
978 }
979
980 ReturnData& data = found->second;
981
Chia-I Wu67e376d2016-12-19 11:36:22 +0800982 *outPresentFence = data.presentFence;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800983 data.presentFence = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800984}
985
986} // namespace Hwc2
987
988} // namespace android