blob: 1bd9616f7c9cf1bcc0313e3f57d1c27f8cb122c9 [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>
23
24#include "ComposerHal.h"
25
26namespace android {
27
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -050028using dvr::composer::V1_0::IVrComposerClient;
Chia-I Wuaab99f52016-10-05 12:59:58 +080029using hardware::Return;
30using hardware::hidl_vec;
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010031using hardware::hidl_handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080032
33namespace Hwc2 {
34
35namespace {
36
37class BufferHandle {
38public:
39 BufferHandle(const native_handle_t* buffer)
40 {
41 // nullptr is not a valid handle to HIDL
42 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
43 }
44
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010045 operator const hidl_handle&() const
Chia-I Wuaab99f52016-10-05 12:59:58 +080046 {
47 return mHandle;
48 }
49
50private:
51 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010052 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080053};
54
55class FenceHandle
56{
57public:
58 FenceHandle(int fd, bool owned)
59 : mOwned(owned)
60 {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010061 native_handle_t* handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080062 if (fd >= 0) {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010063 handle = native_handle_init(mStorage, 1, 0);
64 handle->data[0] = fd;
Chia-I Wuaab99f52016-10-05 12:59:58 +080065 } else {
66 // nullptr is not a valid handle to HIDL
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010067 handle = native_handle_init(mStorage, 0, 0);
Chia-I Wuaab99f52016-10-05 12:59:58 +080068 }
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010069 mHandle = handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080070 }
71
72 ~FenceHandle()
73 {
74 if (mOwned) {
75 native_handle_close(mHandle);
76 }
77 }
78
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010079 operator const hidl_handle&() const
Chia-I Wuaab99f52016-10-05 12:59:58 +080080 {
81 return mHandle;
82 }
83
84private:
85 bool mOwned;
86 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010087 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080088};
89
90// assume NO_RESOURCES when Status::isOk returns false
91constexpr Error kDefaultError = Error::NO_RESOURCES;
92
93template<typename T, typename U>
94T unwrapRet(Return<T>& ret, const U& default_val)
95{
Steven Moreland9d021002017-01-03 17:10:54 -080096 return (ret.isOk()) ? static_cast<T>(ret) :
Chia-I Wuaab99f52016-10-05 12:59:58 +080097 static_cast<T>(default_val);
98}
99
100Error unwrapRet(Return<Error>& ret)
101{
102 return unwrapRet(ret, kDefaultError);
103}
104
Chia-I Wuaab99f52016-10-05 12:59:58 +0800105} // anonymous namespace
106
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500107Composer::CommandWriter::CommandWriter(uint32_t initialMaxSize)
108 : CommandWriterBase(initialMaxSize) {}
109
110Composer::CommandWriter::~CommandWriter()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800111{
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500112}
113
114void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
115{
116 constexpr uint16_t kSetLayerInfoLength = 2;
117 beginCommand(
118 static_cast<IComposerClient::Command>(
119 IVrComposerClient::VrCommand::SET_LAYER_INFO),
120 kSetLayerInfoLength);
121 write(type);
122 write(appId);
123 endCommand();
124}
125
126Composer::Composer() : mWriter(kWriterInitialSize)
127{
128#if defined(IN_VR_MODE)
129 mIsInVrMode = true;
130#endif
131
132 if (mIsInVrMode) {
133 mComposer = IComposer::getService("vr_hwcomposer");
134 } else {
135 mComposer = IComposer::getService("hwcomposer");
136 }
137
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800138 if (mComposer == nullptr) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800139 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
140 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800141
142 mComposer->createClient(
143 [&](const auto& tmpError, const auto& tmpClient)
144 {
145 if (tmpError == Error::NONE) {
146 mClient = tmpClient;
147 }
148 });
149 if (mClient == nullptr) {
150 LOG_ALWAYS_FATAL("failed to create composer client");
151 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800152}
153
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800154std::vector<IComposer::Capability> Composer::getCapabilities()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800155{
156 std::vector<IComposer::Capability> capabilities;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800157 mComposer->getCapabilities(
Chia-I Wuaab99f52016-10-05 12:59:58 +0800158 [&](const auto& tmpCapabilities) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800159 capabilities = tmpCapabilities;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800160 });
161
162 return capabilities;
163}
164
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800165std::string Composer::dumpDebugInfo()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800166{
167 std::string info;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800168 mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800169 info = tmpInfo.c_str();
170 });
171
172 return info;
173}
174
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800175void Composer::registerCallback(const sp<IComposerCallback>& callback)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800176{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800177 auto ret = mClient->registerCallback(callback);
Steven Moreland9d021002017-01-03 17:10:54 -0800178 if (!ret.isOk()) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800179 ALOGE("failed to register IComposerCallback");
180 }
181}
182
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800183uint32_t Composer::getMaxVirtualDisplayCount()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800184{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800185 auto ret = mClient->getMaxVirtualDisplayCount();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800186 return unwrapRet(ret, 0);
187}
188
189Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800190 PixelFormat* format, Display* outDisplay)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800191{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800192 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800193 Error error = kDefaultError;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800194 mClient->createVirtualDisplay(width, height, *format, bufferSlotCount,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800195 [&](const auto& tmpError, const auto& tmpDisplay,
196 const auto& tmpFormat) {
197 error = tmpError;
198 if (error != Error::NONE) {
199 return;
200 }
201
Chia-I Wu67e376d2016-12-19 11:36:22 +0800202 *outDisplay = tmpDisplay;
203 *format = tmpFormat;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800204 });
205
206 return error;
207}
208
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800209Error Composer::destroyVirtualDisplay(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800210{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800211 auto ret = mClient->destroyVirtualDisplay(display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800212 return unwrapRet(ret);
213}
214
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800215Error Composer::acceptDisplayChanges(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800216{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800217 mWriter.selectDisplay(display);
218 mWriter.acceptDisplayChanges();
219 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800220}
221
Chia-I Wu67e376d2016-12-19 11:36:22 +0800222Error Composer::createLayer(Display display, Layer* outLayer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800223{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800224 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800225 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800226 mClient->createLayer(display, bufferSlotCount,
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
430Error Composer::setClientTarget(Display display, const native_handle_t* target,
431 int acquireFence, Dataspace dataspace,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800432 const std::vector<IComposerClient::Rect>& damage)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800433{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800434 mWriter.selectDisplay(display);
435 mWriter.setClientTarget(0, target, acquireFence, dataspace, damage);
436 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800437}
438
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800439Error Composer::setColorMode(Display display, ColorMode mode)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800440{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800441 auto ret = mClient->setColorMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800442 return unwrapRet(ret);
443}
444
445Error Composer::setColorTransform(Display display, const float* matrix,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800446 ColorTransform hint)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800447{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800448 mWriter.selectDisplay(display);
449 mWriter.setColorTransform(matrix, hint);
450 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800451}
452
453Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800454 int releaseFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800455{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800456 mWriter.selectDisplay(display);
457 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
458 return Error::NONE;
459}
Chia-I Wuaab99f52016-10-05 12:59:58 +0800460
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800461Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
462{
463 auto ret = mClient->setPowerMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800464 return unwrapRet(ret);
465}
466
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800467Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800468{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800469 auto ret = mClient->setVsyncEnabled(display, enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800470 return unwrapRet(ret);
471}
472
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800473Error Composer::setClientTargetSlotCount(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800474{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800475 const uint32_t bufferSlotCount = 1;
476 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800477 return unwrapRet(ret);
478}
479
Chia-I Wu67e376d2016-12-19 11:36:22 +0800480Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
481 uint32_t* outNumRequests)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800482{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800483 mWriter.selectDisplay(display);
484 mWriter.validateDisplay();
485
486 Error error = execute();
487 if (error != Error::NONE) {
488 return error;
489 }
490
Chia-I Wu67e376d2016-12-19 11:36:22 +0800491 mReader.hasChanges(display, outNumTypes, outNumRequests);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800492
493 return Error::NONE;
494}
495
496Error Composer::setCursorPosition(Display display, Layer layer,
497 int32_t x, int32_t y)
498{
499 mWriter.selectDisplay(display);
500 mWriter.selectLayer(layer);
501 mWriter.setLayerCursorPosition(x, y);
502 return Error::NONE;
503}
504
505Error Composer::setLayerBuffer(Display display, Layer layer,
506 const native_handle_t* buffer, int acquireFence)
507{
508 mWriter.selectDisplay(display);
509 mWriter.selectLayer(layer);
510 mWriter.setLayerBuffer(0, buffer, acquireFence);
511 return Error::NONE;
512}
513
514Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
515 const std::vector<IComposerClient::Rect>& damage)
516{
517 mWriter.selectDisplay(display);
518 mWriter.selectLayer(layer);
519 mWriter.setLayerSurfaceDamage(damage);
520 return Error::NONE;
521}
522
523Error Composer::setLayerBlendMode(Display display, Layer layer,
524 IComposerClient::BlendMode mode)
525{
526 mWriter.selectDisplay(display);
527 mWriter.selectLayer(layer);
528 mWriter.setLayerBlendMode(mode);
529 return Error::NONE;
530}
531
532Error Composer::setLayerColor(Display display, Layer layer,
533 const IComposerClient::Color& color)
534{
535 mWriter.selectDisplay(display);
536 mWriter.selectLayer(layer);
537 mWriter.setLayerColor(color);
538 return Error::NONE;
539}
540
541Error Composer::setLayerCompositionType(Display display, Layer layer,
542 IComposerClient::Composition type)
543{
544 mWriter.selectDisplay(display);
545 mWriter.selectLayer(layer);
546 mWriter.setLayerCompositionType(type);
547 return Error::NONE;
548}
549
550Error Composer::setLayerDataspace(Display display, Layer layer,
551 Dataspace dataspace)
552{
553 mWriter.selectDisplay(display);
554 mWriter.selectLayer(layer);
555 mWriter.setLayerDataspace(dataspace);
556 return Error::NONE;
557}
558
559Error Composer::setLayerDisplayFrame(Display display, Layer layer,
560 const IComposerClient::Rect& frame)
561{
562 mWriter.selectDisplay(display);
563 mWriter.selectLayer(layer);
564 mWriter.setLayerDisplayFrame(frame);
565 return Error::NONE;
566}
567
568Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
569 float alpha)
570{
571 mWriter.selectDisplay(display);
572 mWriter.selectLayer(layer);
573 mWriter.setLayerPlaneAlpha(alpha);
574 return Error::NONE;
575}
576
577Error Composer::setLayerSidebandStream(Display display, Layer layer,
578 const native_handle_t* stream)
579{
580 mWriter.selectDisplay(display);
581 mWriter.selectLayer(layer);
582 mWriter.setLayerSidebandStream(stream);
583 return Error::NONE;
584}
585
586Error Composer::setLayerSourceCrop(Display display, Layer layer,
587 const IComposerClient::FRect& crop)
588{
589 mWriter.selectDisplay(display);
590 mWriter.selectLayer(layer);
591 mWriter.setLayerSourceCrop(crop);
592 return Error::NONE;
593}
594
595Error Composer::setLayerTransform(Display display, Layer layer,
596 Transform transform)
597{
598 mWriter.selectDisplay(display);
599 mWriter.selectLayer(layer);
600 mWriter.setLayerTransform(transform);
601 return Error::NONE;
602}
603
604Error Composer::setLayerVisibleRegion(Display display, Layer layer,
605 const std::vector<IComposerClient::Rect>& visible)
606{
607 mWriter.selectDisplay(display);
608 mWriter.selectLayer(layer);
609 mWriter.setLayerVisibleRegion(visible);
610 return Error::NONE;
611}
612
613Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
614{
615 mWriter.selectDisplay(display);
616 mWriter.selectLayer(layer);
617 mWriter.setLayerZOrder(z);
618 return Error::NONE;
619}
620
Daniel Nicoara2f5f8a52016-12-20 16:11:58 -0500621Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type,
622 uint32_t appId)
623{
624 if (mIsInVrMode)
625 {
626 mWriter.selectDisplay(display);
627 mWriter.selectLayer(layer);
628 mWriter.setLayerInfo(type, appId);
629 }
630 return Error::NONE;
631}
632
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800633Error Composer::execute()
634{
635 // prepare input command queue
636 bool queueChanged = false;
637 uint32_t commandLength = 0;
638 hidl_vec<hidl_handle> commandHandles;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800639 if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800640 mWriter.reset();
641 return Error::NO_RESOURCES;
642 }
643
644 // set up new input command queue if necessary
645 if (queueChanged) {
646 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
647 auto error = unwrapRet(ret);
648 if (error != Error::NONE) {
649 mWriter.reset();
650 return error;
651 }
652 }
653
Chia-I Wuaab99f52016-10-05 12:59:58 +0800654 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800655 mClient->executeCommands(commandLength, commandHandles,
656 [&](const auto& tmpError, const auto& tmpOutChanged,
657 const auto& tmpOutLength, const auto& tmpOutHandles)
658 {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800659 error = tmpError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800660
661 // set up new output command queue if necessary
662 if (error == Error::NONE && tmpOutChanged) {
663 error = kDefaultError;
664 mClient->getOutputCommandQueue(
665 [&](const auto& tmpError,
666 const auto& tmpDescriptor)
667 {
668 error = tmpError;
669 if (error != Error::NONE) {
670 return;
671 }
672
673 mReader.setMQDescriptor(tmpDescriptor);
674 });
675 }
676
Chia-I Wuaab99f52016-10-05 12:59:58 +0800677 if (error != Error::NONE) {
678 return;
679 }
680
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800681 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
682 error = mReader.parse();
683 mReader.reset();
684 } else {
685 error = Error::NO_RESOURCES;
686 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800687 });
688
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800689 if (error == Error::NONE) {
690 std::vector<CommandReader::CommandError> commandErrors =
691 mReader.takeErrors();
692
693 for (const auto& cmdErr : commandErrors) {
694 auto command = mWriter.getCommand(cmdErr.location);
695
696 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
697 command == IComposerClient::Command::PRESENT_DISPLAY) {
698 error = cmdErr.error;
699 } else {
700 ALOGW("command 0x%x generated error %d",
701 command, cmdErr.error);
702 }
703 }
704 }
705
706 mWriter.reset();
707
Chia-I Wuaab99f52016-10-05 12:59:58 +0800708 return error;
709}
710
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800711CommandReader::~CommandReader()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800712{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800713 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800714}
715
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800716Error CommandReader::parse()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800717{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800718 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800719
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800720 IComposerClient::Command command;
721 uint16_t length = 0;
722
723 while (!isEmpty()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800724 if (!beginCommand(&command, &length)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800725 break;
726 }
727
728 bool parsed = false;
729 switch (command) {
730 case IComposerClient::Command::SELECT_DISPLAY:
731 parsed = parseSelectDisplay(length);
732 break;
733 case IComposerClient::Command::SET_ERROR:
734 parsed = parseSetError(length);
735 break;
736 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
737 parsed = parseSetChangedCompositionTypes(length);
738 break;
739 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
740 parsed = parseSetDisplayRequests(length);
741 break;
742 case IComposerClient::Command::SET_PRESENT_FENCE:
743 parsed = parseSetPresentFence(length);
744 break;
745 case IComposerClient::Command::SET_RELEASE_FENCES:
746 parsed = parseSetReleaseFences(length);
747 break;
748 default:
749 parsed = false;
750 break;
751 }
752
753 endCommand();
754
755 if (!parsed) {
756 ALOGE("failed to parse command 0x%x length %" PRIu16,
757 command, length);
758 break;
759 }
760 }
761
762 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800763}
764
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800765bool CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800766{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -0500767 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800768 return false;
769 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800770
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800771 mCurrentReturnData = &mReturnData[read64()];
772
773 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800774}
775
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800776bool CommandReader::parseSetError(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800777{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -0500778 if (length != CommandWriterBase::kSetErrorLength) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800779 return false;
780 }
781
782 auto location = read();
783 auto error = static_cast<Error>(readSigned());
784
785 mErrors.emplace_back(CommandError{location, error});
786
787 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800788}
789
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800790bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800791{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800792 // (layer id, composition type) pairs
793 if (length % 3 != 0 || !mCurrentReturnData) {
794 return false;
795 }
796
797 uint32_t count = length / 3;
798 mCurrentReturnData->changedLayers.reserve(count);
799 mCurrentReturnData->compositionTypes.reserve(count);
800 while (count > 0) {
801 auto layer = read64();
802 auto type = static_cast<IComposerClient::Composition>(readSigned());
803
804 mCurrentReturnData->changedLayers.push_back(layer);
805 mCurrentReturnData->compositionTypes.push_back(type);
806
807 count--;
808 }
809
810 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800811}
812
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800813bool CommandReader::parseSetDisplayRequests(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800814{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800815 // display requests followed by (layer id, layer requests) pairs
816 if (length % 3 != 1 || !mCurrentReturnData) {
817 return false;
818 }
819
820 mCurrentReturnData->displayRequests = read();
821
822 uint32_t count = (length - 1) / 3;
823 mCurrentReturnData->requestedLayers.reserve(count);
824 mCurrentReturnData->requestMasks.reserve(count);
825 while (count > 0) {
826 auto layer = read64();
827 auto layerRequestMask = read();
828
829 mCurrentReturnData->requestedLayers.push_back(layer);
830 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
831
832 count--;
833 }
834
835 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800836}
837
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800838bool CommandReader::parseSetPresentFence(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800839{
Daniel Nicoara3c9cbd42017-01-17 12:04:06 -0500840 if (length != CommandWriterBase::kSetPresentFenceLength ||
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800841 !mCurrentReturnData) {
842 return false;
843 }
844
845 if (mCurrentReturnData->presentFence >= 0) {
846 close(mCurrentReturnData->presentFence);
847 }
848 mCurrentReturnData->presentFence = readFence();
849
850 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800851}
852
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800853bool CommandReader::parseSetReleaseFences(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800854{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800855 // (layer id, release fence index) pairs
856 if (length % 3 != 0 || !mCurrentReturnData) {
857 return false;
858 }
859
860 uint32_t count = length / 3;
861 mCurrentReturnData->releasedLayers.reserve(count);
862 mCurrentReturnData->releaseFences.reserve(count);
863 while (count > 0) {
864 auto layer = read64();
865 auto fence = readFence();
866
867 mCurrentReturnData->releasedLayers.push_back(layer);
868 mCurrentReturnData->releaseFences.push_back(fence);
869
870 count--;
871 }
872
873 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800874}
875
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800876void CommandReader::resetData()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800877{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800878 mErrors.clear();
879
880 for (auto& data : mReturnData) {
881 if (data.second.presentFence >= 0) {
882 close(data.second.presentFence);
883 }
884 for (auto fence : data.second.releaseFences) {
885 if (fence >= 0) {
886 close(fence);
887 }
888 }
889 }
890
891 mReturnData.clear();
892 mCurrentReturnData = nullptr;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800893}
894
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800895std::vector<CommandReader::CommandError> CommandReader::takeErrors()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800896{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800897 return std::move(mErrors);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800898}
899
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800900bool CommandReader::hasChanges(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800901 uint32_t* outNumChangedCompositionTypes,
902 uint32_t* outNumLayerRequestMasks) const
Chia-I Wuaab99f52016-10-05 12:59:58 +0800903{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800904 auto found = mReturnData.find(display);
905 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800906 *outNumChangedCompositionTypes = 0;
907 *outNumLayerRequestMasks = 0;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800908 return false;
909 }
910
911 const ReturnData& data = found->second;
912
Chia-I Wu67e376d2016-12-19 11:36:22 +0800913 *outNumChangedCompositionTypes = data.compositionTypes.size();
914 *outNumLayerRequestMasks = data.requestMasks.size();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800915
916 return !(data.compositionTypes.empty() && data.requestMasks.empty());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800917}
918
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800919void CommandReader::takeChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800920 std::vector<Layer>* outLayers,
921 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800922{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800923 auto found = mReturnData.find(display);
924 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800925 outLayers->clear();
926 outTypes->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800927 return;
928 }
929
930 ReturnData& data = found->second;
931
Chia-I Wu67e376d2016-12-19 11:36:22 +0800932 *outLayers = std::move(data.changedLayers);
933 *outTypes = std::move(data.compositionTypes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800934}
935
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800936void CommandReader::takeDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800937 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
938 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800939{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800940 auto found = mReturnData.find(display);
941 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800942 *outDisplayRequestMask = 0;
943 outLayers->clear();
944 outLayerRequestMasks->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800945 return;
946 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800947
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800948 ReturnData& data = found->second;
949
Chia-I Wu67e376d2016-12-19 11:36:22 +0800950 *outDisplayRequestMask = data.displayRequests;
951 *outLayers = std::move(data.requestedLayers);
952 *outLayerRequestMasks = std::move(data.requestMasks);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800953}
954
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800955void CommandReader::takeReleaseFences(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800956 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800957{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800958 auto found = mReturnData.find(display);
959 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800960 outLayers->clear();
961 outReleaseFences->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800962 return;
963 }
964
965 ReturnData& data = found->second;
966
Chia-I Wu67e376d2016-12-19 11:36:22 +0800967 *outLayers = std::move(data.releasedLayers);
968 *outReleaseFences = std::move(data.releaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800969}
970
Chia-I Wu67e376d2016-12-19 11:36:22 +0800971void CommandReader::takePresentFence(Display display, int* outPresentFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800972{
973 auto found = mReturnData.find(display);
974 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800975 *outPresentFence = -1;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800976 return;
977 }
978
979 ReturnData& data = found->second;
980
Chia-I Wu67e376d2016-12-19 11:36:22 +0800981 *outPresentFence = data.presentFence;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800982 data.presentFence = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800983}
984
985} // namespace Hwc2
986
987} // namespace android