blob: b952fd7801ed508133ca04e4eb9ae266cd0e5b8a [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
25namespace android {
26
27using hardware::Return;
28using hardware::hidl_vec;
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010029using hardware::hidl_handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080030
31namespace Hwc2 {
32
33namespace {
34
35class BufferHandle {
36public:
37 BufferHandle(const native_handle_t* buffer)
38 {
39 // nullptr is not a valid handle to HIDL
40 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
41 }
42
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010043 operator const hidl_handle&() const
Chia-I Wuaab99f52016-10-05 12:59:58 +080044 {
45 return mHandle;
46 }
47
48private:
49 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010050 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080051};
52
53class FenceHandle
54{
55public:
56 FenceHandle(int fd, bool owned)
57 : mOwned(owned)
58 {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010059 native_handle_t* handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080060 if (fd >= 0) {
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010061 handle = native_handle_init(mStorage, 1, 0);
62 handle->data[0] = fd;
Chia-I Wuaab99f52016-10-05 12:59:58 +080063 } else {
64 // nullptr is not a valid handle to HIDL
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010065 handle = native_handle_init(mStorage, 0, 0);
Chia-I Wuaab99f52016-10-05 12:59:58 +080066 }
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010067 mHandle = handle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080068 }
69
70 ~FenceHandle()
71 {
72 if (mOwned) {
73 native_handle_close(mHandle);
74 }
75 }
76
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010077 operator const hidl_handle&() const
Chia-I Wuaab99f52016-10-05 12:59:58 +080078 {
79 return mHandle;
80 }
81
82private:
83 bool mOwned;
84 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
Martijn Coenen7c5a92f2016-11-21 10:01:07 +010085 hidl_handle mHandle;
Chia-I Wuaab99f52016-10-05 12:59:58 +080086};
87
88// assume NO_RESOURCES when Status::isOk returns false
89constexpr Error kDefaultError = Error::NO_RESOURCES;
90
91template<typename T, typename U>
92T unwrapRet(Return<T>& ret, const U& default_val)
93{
Steven Moreland9d021002017-01-03 17:10:54 -080094 return (ret.isOk()) ? static_cast<T>(ret) :
Chia-I Wuaab99f52016-10-05 12:59:58 +080095 static_cast<T>(default_val);
96}
97
98Error unwrapRet(Return<Error>& ret)
99{
100 return unwrapRet(ret, kDefaultError);
101}
102
Chia-I Wuaab99f52016-10-05 12:59:58 +0800103} // anonymous namespace
104
105Composer::Composer()
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800106 : mWriter(kWriterInitialSize)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800107{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800108 mComposer = IComposer::getService("hwcomposer");
109 if (mComposer == nullptr) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800110 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
111 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800112
113 mComposer->createClient(
114 [&](const auto& tmpError, const auto& tmpClient)
115 {
116 if (tmpError == Error::NONE) {
117 mClient = tmpClient;
118 }
119 });
120 if (mClient == nullptr) {
121 LOG_ALWAYS_FATAL("failed to create composer client");
122 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800123}
124
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800125std::vector<IComposer::Capability> Composer::getCapabilities()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800126{
127 std::vector<IComposer::Capability> capabilities;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800128 mComposer->getCapabilities(
Chia-I Wuaab99f52016-10-05 12:59:58 +0800129 [&](const auto& tmpCapabilities) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800130 capabilities = tmpCapabilities;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800131 });
132
133 return capabilities;
134}
135
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800136std::string Composer::dumpDebugInfo()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800137{
138 std::string info;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800139 mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800140 info = tmpInfo.c_str();
141 });
142
143 return info;
144}
145
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800146void Composer::registerCallback(const sp<IComposerCallback>& callback)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800147{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800148 auto ret = mClient->registerCallback(callback);
Steven Moreland9d021002017-01-03 17:10:54 -0800149 if (!ret.isOk()) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800150 ALOGE("failed to register IComposerCallback");
151 }
152}
153
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800154uint32_t Composer::getMaxVirtualDisplayCount()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800155{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800156 auto ret = mClient->getMaxVirtualDisplayCount();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800157 return unwrapRet(ret, 0);
158}
159
160Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800161 PixelFormat* format, Display* outDisplay)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800162{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800163 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800164 Error error = kDefaultError;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800165 mClient->createVirtualDisplay(width, height, *format, bufferSlotCount,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800166 [&](const auto& tmpError, const auto& tmpDisplay,
167 const auto& tmpFormat) {
168 error = tmpError;
169 if (error != Error::NONE) {
170 return;
171 }
172
Chia-I Wu67e376d2016-12-19 11:36:22 +0800173 *outDisplay = tmpDisplay;
174 *format = tmpFormat;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800175 });
176
177 return error;
178}
179
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800180Error Composer::destroyVirtualDisplay(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800181{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800182 auto ret = mClient->destroyVirtualDisplay(display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800183 return unwrapRet(ret);
184}
185
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800186Error Composer::acceptDisplayChanges(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800187{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800188 mWriter.selectDisplay(display);
189 mWriter.acceptDisplayChanges();
190 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800191}
192
Chia-I Wu67e376d2016-12-19 11:36:22 +0800193Error Composer::createLayer(Display display, Layer* outLayer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800194{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800195 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800196 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800197 mClient->createLayer(display, bufferSlotCount,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800198 [&](const auto& tmpError, const auto& tmpLayer) {
199 error = tmpError;
200 if (error != Error::NONE) {
201 return;
202 }
203
Chia-I Wu67e376d2016-12-19 11:36:22 +0800204 *outLayer = tmpLayer;
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::destroyLayer(Display display, Layer layer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800211{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800212 auto ret = mClient->destroyLayer(display, layer);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800213 return unwrapRet(ret);
214}
215
Chia-I Wu67e376d2016-12-19 11:36:22 +0800216Error Composer::getActiveConfig(Display display, Config* outConfig)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800217{
218 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800219 mClient->getActiveConfig(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800220 [&](const auto& tmpError, const auto& tmpConfig) {
221 error = tmpError;
222 if (error != Error::NONE) {
223 return;
224 }
225
Chia-I Wu67e376d2016-12-19 11:36:22 +0800226 *outConfig = tmpConfig;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800227 });
228
229 return error;
230}
231
232Error Composer::getChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800233 std::vector<Layer>* outLayers,
234 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800235{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800236 mReader.takeChangedCompositionTypes(display, outLayers, outTypes);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800237 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800238}
239
240Error Composer::getColorModes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800241 std::vector<ColorMode>* outModes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800242{
243 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800244 mClient->getColorModes(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800245 [&](const auto& tmpError, const auto& tmpModes) {
246 error = tmpError;
247 if (error != Error::NONE) {
248 return;
249 }
250
Chia-I Wu67e376d2016-12-19 11:36:22 +0800251 *outModes = tmpModes;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800252 });
253
254 return error;
255}
256
257Error Composer::getDisplayAttribute(Display display, Config config,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800258 IComposerClient::Attribute attribute, int32_t* outValue)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800259{
260 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800261 mClient->getDisplayAttribute(display, config, attribute,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800262 [&](const auto& tmpError, const auto& tmpValue) {
263 error = tmpError;
264 if (error != Error::NONE) {
265 return;
266 }
267
Chia-I Wu67e376d2016-12-19 11:36:22 +0800268 *outValue = tmpValue;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800269 });
270
271 return error;
272}
273
274Error Composer::getDisplayConfigs(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800275 std::vector<Config>* outConfigs)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800276{
277 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800278 mClient->getDisplayConfigs(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800279 [&](const auto& tmpError, const auto& tmpConfigs) {
280 error = tmpError;
281 if (error != Error::NONE) {
282 return;
283 }
284
Chia-I Wu67e376d2016-12-19 11:36:22 +0800285 *outConfigs = tmpConfigs;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800286 });
287
288 return error;
289}
290
Chia-I Wu67e376d2016-12-19 11:36:22 +0800291Error Composer::getDisplayName(Display display, std::string* outName)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800292{
293 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800294 mClient->getDisplayName(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800295 [&](const auto& tmpError, const auto& tmpName) {
296 error = tmpError;
297 if (error != Error::NONE) {
298 return;
299 }
300
Chia-I Wu67e376d2016-12-19 11:36:22 +0800301 *outName = tmpName.c_str();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800302 });
303
304 return error;
305}
306
307Error Composer::getDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800308 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
309 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800310{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800311 mReader.takeDisplayRequests(display, outDisplayRequestMask,
312 outLayers, outLayerRequestMasks);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800313 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800314}
315
Chia-I Wu67e376d2016-12-19 11:36:22 +0800316Error Composer::getDisplayType(Display display,
317 IComposerClient::DisplayType* outType)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800318{
319 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800320 mClient->getDisplayType(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800321 [&](const auto& tmpError, const auto& tmpType) {
322 error = tmpError;
323 if (error != Error::NONE) {
324 return;
325 }
326
Chia-I Wu67e376d2016-12-19 11:36:22 +0800327 *outType = tmpType;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800328 });
329
330 return error;
331}
332
Chia-I Wu67e376d2016-12-19 11:36:22 +0800333Error Composer::getDozeSupport(Display display, bool* outSupport)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800334{
335 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800336 mClient->getDozeSupport(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800337 [&](const auto& tmpError, const auto& tmpSupport) {
338 error = tmpError;
339 if (error != Error::NONE) {
340 return;
341 }
342
Chia-I Wu67e376d2016-12-19 11:36:22 +0800343 *outSupport = tmpSupport;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800344 });
345
346 return error;
347}
348
Chia-I Wu67e376d2016-12-19 11:36:22 +0800349Error Composer::getHdrCapabilities(Display display,
350 std::vector<Hdr>* outTypes, float* outMaxLuminance,
351 float* outMaxAverageLuminance, float* outMinLuminance)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800352{
353 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800354 mClient->getHdrCapabilities(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800355 [&](const auto& tmpError, const auto& tmpTypes,
356 const auto& tmpMaxLuminance,
357 const auto& tmpMaxAverageLuminance,
358 const auto& tmpMinLuminance) {
359 error = tmpError;
360 if (error != Error::NONE) {
361 return;
362 }
363
Chia-I Wu67e376d2016-12-19 11:36:22 +0800364 *outTypes = tmpTypes;
365 *outMaxLuminance = tmpMaxLuminance;
366 *outMaxAverageLuminance = tmpMaxAverageLuminance;
367 *outMinLuminance = tmpMinLuminance;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800368 });
369
370 return error;
371}
372
Chia-I Wu67e376d2016-12-19 11:36:22 +0800373Error Composer::getReleaseFences(Display display,
374 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800375{
Chia-I Wu67e376d2016-12-19 11:36:22 +0800376 mReader.takeReleaseFences(display, outLayers, outReleaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800377 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800378}
379
Chia-I Wu67e376d2016-12-19 11:36:22 +0800380Error Composer::presentDisplay(Display display, int* outPresentFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800381{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800382 mWriter.selectDisplay(display);
383 mWriter.presentDisplay();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800384
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800385 Error error = execute();
386 if (error != Error::NONE) {
387 return error;
388 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800389
Chia-I Wu67e376d2016-12-19 11:36:22 +0800390 mReader.takePresentFence(display, outPresentFence);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800391
392 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800393}
394
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800395Error Composer::setActiveConfig(Display display, Config config)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800396{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800397 auto ret = mClient->setActiveConfig(display, config);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800398 return unwrapRet(ret);
399}
400
401Error Composer::setClientTarget(Display display, const native_handle_t* target,
402 int acquireFence, Dataspace dataspace,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800403 const std::vector<IComposerClient::Rect>& damage)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800404{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800405 mWriter.selectDisplay(display);
406 mWriter.setClientTarget(0, target, acquireFence, dataspace, damage);
407 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800408}
409
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800410Error Composer::setColorMode(Display display, ColorMode mode)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800411{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800412 auto ret = mClient->setColorMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800413 return unwrapRet(ret);
414}
415
416Error Composer::setColorTransform(Display display, const float* matrix,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800417 ColorTransform hint)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800418{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800419 mWriter.selectDisplay(display);
420 mWriter.setColorTransform(matrix, hint);
421 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800422}
423
424Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800425 int releaseFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800426{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800427 mWriter.selectDisplay(display);
428 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
429 return Error::NONE;
430}
Chia-I Wuaab99f52016-10-05 12:59:58 +0800431
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800432Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
433{
434 auto ret = mClient->setPowerMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800435 return unwrapRet(ret);
436}
437
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800438Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800439{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800440 auto ret = mClient->setVsyncEnabled(display, enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800441 return unwrapRet(ret);
442}
443
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800444Error Composer::setClientTargetSlotCount(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800445{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800446 const uint32_t bufferSlotCount = 1;
447 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800448 return unwrapRet(ret);
449}
450
Chia-I Wu67e376d2016-12-19 11:36:22 +0800451Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
452 uint32_t* outNumRequests)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800453{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800454 mWriter.selectDisplay(display);
455 mWriter.validateDisplay();
456
457 Error error = execute();
458 if (error != Error::NONE) {
459 return error;
460 }
461
Chia-I Wu67e376d2016-12-19 11:36:22 +0800462 mReader.hasChanges(display, outNumTypes, outNumRequests);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800463
464 return Error::NONE;
465}
466
467Error Composer::setCursorPosition(Display display, Layer layer,
468 int32_t x, int32_t y)
469{
470 mWriter.selectDisplay(display);
471 mWriter.selectLayer(layer);
472 mWriter.setLayerCursorPosition(x, y);
473 return Error::NONE;
474}
475
476Error Composer::setLayerBuffer(Display display, Layer layer,
477 const native_handle_t* buffer, int acquireFence)
478{
479 mWriter.selectDisplay(display);
480 mWriter.selectLayer(layer);
481 mWriter.setLayerBuffer(0, buffer, acquireFence);
482 return Error::NONE;
483}
484
485Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
486 const std::vector<IComposerClient::Rect>& damage)
487{
488 mWriter.selectDisplay(display);
489 mWriter.selectLayer(layer);
490 mWriter.setLayerSurfaceDamage(damage);
491 return Error::NONE;
492}
493
494Error Composer::setLayerBlendMode(Display display, Layer layer,
495 IComposerClient::BlendMode mode)
496{
497 mWriter.selectDisplay(display);
498 mWriter.selectLayer(layer);
499 mWriter.setLayerBlendMode(mode);
500 return Error::NONE;
501}
502
503Error Composer::setLayerColor(Display display, Layer layer,
504 const IComposerClient::Color& color)
505{
506 mWriter.selectDisplay(display);
507 mWriter.selectLayer(layer);
508 mWriter.setLayerColor(color);
509 return Error::NONE;
510}
511
512Error Composer::setLayerCompositionType(Display display, Layer layer,
513 IComposerClient::Composition type)
514{
515 mWriter.selectDisplay(display);
516 mWriter.selectLayer(layer);
517 mWriter.setLayerCompositionType(type);
518 return Error::NONE;
519}
520
521Error Composer::setLayerDataspace(Display display, Layer layer,
522 Dataspace dataspace)
523{
524 mWriter.selectDisplay(display);
525 mWriter.selectLayer(layer);
526 mWriter.setLayerDataspace(dataspace);
527 return Error::NONE;
528}
529
530Error Composer::setLayerDisplayFrame(Display display, Layer layer,
531 const IComposerClient::Rect& frame)
532{
533 mWriter.selectDisplay(display);
534 mWriter.selectLayer(layer);
535 mWriter.setLayerDisplayFrame(frame);
536 return Error::NONE;
537}
538
539Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
540 float alpha)
541{
542 mWriter.selectDisplay(display);
543 mWriter.selectLayer(layer);
544 mWriter.setLayerPlaneAlpha(alpha);
545 return Error::NONE;
546}
547
548Error Composer::setLayerSidebandStream(Display display, Layer layer,
549 const native_handle_t* stream)
550{
551 mWriter.selectDisplay(display);
552 mWriter.selectLayer(layer);
553 mWriter.setLayerSidebandStream(stream);
554 return Error::NONE;
555}
556
557Error Composer::setLayerSourceCrop(Display display, Layer layer,
558 const IComposerClient::FRect& crop)
559{
560 mWriter.selectDisplay(display);
561 mWriter.selectLayer(layer);
562 mWriter.setLayerSourceCrop(crop);
563 return Error::NONE;
564}
565
566Error Composer::setLayerTransform(Display display, Layer layer,
567 Transform transform)
568{
569 mWriter.selectDisplay(display);
570 mWriter.selectLayer(layer);
571 mWriter.setLayerTransform(transform);
572 return Error::NONE;
573}
574
575Error Composer::setLayerVisibleRegion(Display display, Layer layer,
576 const std::vector<IComposerClient::Rect>& visible)
577{
578 mWriter.selectDisplay(display);
579 mWriter.selectLayer(layer);
580 mWriter.setLayerVisibleRegion(visible);
581 return Error::NONE;
582}
583
584Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
585{
586 mWriter.selectDisplay(display);
587 mWriter.selectLayer(layer);
588 mWriter.setLayerZOrder(z);
589 return Error::NONE;
590}
591
592Error Composer::execute()
593{
594 // prepare input command queue
595 bool queueChanged = false;
596 uint32_t commandLength = 0;
597 hidl_vec<hidl_handle> commandHandles;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800598 if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800599 mWriter.reset();
600 return Error::NO_RESOURCES;
601 }
602
603 // set up new input command queue if necessary
604 if (queueChanged) {
605 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
606 auto error = unwrapRet(ret);
607 if (error != Error::NONE) {
608 mWriter.reset();
609 return error;
610 }
611 }
612
Chia-I Wuaab99f52016-10-05 12:59:58 +0800613 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800614 mClient->executeCommands(commandLength, commandHandles,
615 [&](const auto& tmpError, const auto& tmpOutChanged,
616 const auto& tmpOutLength, const auto& tmpOutHandles)
617 {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800618 error = tmpError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800619
620 // set up new output command queue if necessary
621 if (error == Error::NONE && tmpOutChanged) {
622 error = kDefaultError;
623 mClient->getOutputCommandQueue(
624 [&](const auto& tmpError,
625 const auto& tmpDescriptor)
626 {
627 error = tmpError;
628 if (error != Error::NONE) {
629 return;
630 }
631
632 mReader.setMQDescriptor(tmpDescriptor);
633 });
634 }
635
Chia-I Wuaab99f52016-10-05 12:59:58 +0800636 if (error != Error::NONE) {
637 return;
638 }
639
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800640 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
641 error = mReader.parse();
642 mReader.reset();
643 } else {
644 error = Error::NO_RESOURCES;
645 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800646 });
647
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800648 if (error == Error::NONE) {
649 std::vector<CommandReader::CommandError> commandErrors =
650 mReader.takeErrors();
651
652 for (const auto& cmdErr : commandErrors) {
653 auto command = mWriter.getCommand(cmdErr.location);
654
655 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
656 command == IComposerClient::Command::PRESENT_DISPLAY) {
657 error = cmdErr.error;
658 } else {
659 ALOGW("command 0x%x generated error %d",
660 command, cmdErr.error);
661 }
662 }
663 }
664
665 mWriter.reset();
666
Chia-I Wuaab99f52016-10-05 12:59:58 +0800667 return error;
668}
669
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800670CommandReader::~CommandReader()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800671{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800672 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800673}
674
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800675Error CommandReader::parse()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800676{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800677 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800678
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800679 IComposerClient::Command command;
680 uint16_t length = 0;
681
682 while (!isEmpty()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800683 if (!beginCommand(&command, &length)) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800684 break;
685 }
686
687 bool parsed = false;
688 switch (command) {
689 case IComposerClient::Command::SELECT_DISPLAY:
690 parsed = parseSelectDisplay(length);
691 break;
692 case IComposerClient::Command::SET_ERROR:
693 parsed = parseSetError(length);
694 break;
695 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
696 parsed = parseSetChangedCompositionTypes(length);
697 break;
698 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
699 parsed = parseSetDisplayRequests(length);
700 break;
701 case IComposerClient::Command::SET_PRESENT_FENCE:
702 parsed = parseSetPresentFence(length);
703 break;
704 case IComposerClient::Command::SET_RELEASE_FENCES:
705 parsed = parseSetReleaseFences(length);
706 break;
707 default:
708 parsed = false;
709 break;
710 }
711
712 endCommand();
713
714 if (!parsed) {
715 ALOGE("failed to parse command 0x%x length %" PRIu16,
716 command, length);
717 break;
718 }
719 }
720
721 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800722}
723
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800724bool CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800725{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800726 if (length != CommandWriter::kSelectDisplayLength) {
727 return false;
728 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800729
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800730 mCurrentReturnData = &mReturnData[read64()];
731
732 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800733}
734
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800735bool CommandReader::parseSetError(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800736{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800737 if (length != CommandWriter::kSetErrorLength) {
738 return false;
739 }
740
741 auto location = read();
742 auto error = static_cast<Error>(readSigned());
743
744 mErrors.emplace_back(CommandError{location, error});
745
746 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800747}
748
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800749bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800750{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800751 // (layer id, composition type) pairs
752 if (length % 3 != 0 || !mCurrentReturnData) {
753 return false;
754 }
755
756 uint32_t count = length / 3;
757 mCurrentReturnData->changedLayers.reserve(count);
758 mCurrentReturnData->compositionTypes.reserve(count);
759 while (count > 0) {
760 auto layer = read64();
761 auto type = static_cast<IComposerClient::Composition>(readSigned());
762
763 mCurrentReturnData->changedLayers.push_back(layer);
764 mCurrentReturnData->compositionTypes.push_back(type);
765
766 count--;
767 }
768
769 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800770}
771
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800772bool CommandReader::parseSetDisplayRequests(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800773{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800774 // display requests followed by (layer id, layer requests) pairs
775 if (length % 3 != 1 || !mCurrentReturnData) {
776 return false;
777 }
778
779 mCurrentReturnData->displayRequests = read();
780
781 uint32_t count = (length - 1) / 3;
782 mCurrentReturnData->requestedLayers.reserve(count);
783 mCurrentReturnData->requestMasks.reserve(count);
784 while (count > 0) {
785 auto layer = read64();
786 auto layerRequestMask = read();
787
788 mCurrentReturnData->requestedLayers.push_back(layer);
789 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
790
791 count--;
792 }
793
794 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800795}
796
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800797bool CommandReader::parseSetPresentFence(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800798{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800799 if (length != CommandWriter::kSetPresentFenceLength ||
800 !mCurrentReturnData) {
801 return false;
802 }
803
804 if (mCurrentReturnData->presentFence >= 0) {
805 close(mCurrentReturnData->presentFence);
806 }
807 mCurrentReturnData->presentFence = readFence();
808
809 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800810}
811
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800812bool CommandReader::parseSetReleaseFences(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800813{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800814 // (layer id, release fence index) pairs
815 if (length % 3 != 0 || !mCurrentReturnData) {
816 return false;
817 }
818
819 uint32_t count = length / 3;
820 mCurrentReturnData->releasedLayers.reserve(count);
821 mCurrentReturnData->releaseFences.reserve(count);
822 while (count > 0) {
823 auto layer = read64();
824 auto fence = readFence();
825
826 mCurrentReturnData->releasedLayers.push_back(layer);
827 mCurrentReturnData->releaseFences.push_back(fence);
828
829 count--;
830 }
831
832 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800833}
834
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800835void CommandReader::resetData()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800836{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800837 mErrors.clear();
838
839 for (auto& data : mReturnData) {
840 if (data.second.presentFence >= 0) {
841 close(data.second.presentFence);
842 }
843 for (auto fence : data.second.releaseFences) {
844 if (fence >= 0) {
845 close(fence);
846 }
847 }
848 }
849
850 mReturnData.clear();
851 mCurrentReturnData = nullptr;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800852}
853
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800854std::vector<CommandReader::CommandError> CommandReader::takeErrors()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800855{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800856 return std::move(mErrors);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800857}
858
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800859bool CommandReader::hasChanges(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800860 uint32_t* outNumChangedCompositionTypes,
861 uint32_t* outNumLayerRequestMasks) const
Chia-I Wuaab99f52016-10-05 12:59:58 +0800862{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800863 auto found = mReturnData.find(display);
864 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800865 *outNumChangedCompositionTypes = 0;
866 *outNumLayerRequestMasks = 0;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800867 return false;
868 }
869
870 const ReturnData& data = found->second;
871
Chia-I Wu67e376d2016-12-19 11:36:22 +0800872 *outNumChangedCompositionTypes = data.compositionTypes.size();
873 *outNumLayerRequestMasks = data.requestMasks.size();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800874
875 return !(data.compositionTypes.empty() && data.requestMasks.empty());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800876}
877
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800878void CommandReader::takeChangedCompositionTypes(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800879 std::vector<Layer>* outLayers,
880 std::vector<IComposerClient::Composition>* outTypes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800881{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800882 auto found = mReturnData.find(display);
883 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800884 outLayers->clear();
885 outTypes->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800886 return;
887 }
888
889 ReturnData& data = found->second;
890
Chia-I Wu67e376d2016-12-19 11:36:22 +0800891 *outLayers = std::move(data.changedLayers);
892 *outTypes = std::move(data.compositionTypes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800893}
894
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800895void CommandReader::takeDisplayRequests(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800896 uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers,
897 std::vector<uint32_t>* outLayerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800898{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800899 auto found = mReturnData.find(display);
900 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800901 *outDisplayRequestMask = 0;
902 outLayers->clear();
903 outLayerRequestMasks->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800904 return;
905 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800906
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800907 ReturnData& data = found->second;
908
Chia-I Wu67e376d2016-12-19 11:36:22 +0800909 *outDisplayRequestMask = data.displayRequests;
910 *outLayers = std::move(data.requestedLayers);
911 *outLayerRequestMasks = std::move(data.requestMasks);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800912}
913
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800914void CommandReader::takeReleaseFences(Display display,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800915 std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800916{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800917 auto found = mReturnData.find(display);
918 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800919 outLayers->clear();
920 outReleaseFences->clear();
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800921 return;
922 }
923
924 ReturnData& data = found->second;
925
Chia-I Wu67e376d2016-12-19 11:36:22 +0800926 *outLayers = std::move(data.releasedLayers);
927 *outReleaseFences = std::move(data.releaseFences);
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800928}
929
Chia-I Wu67e376d2016-12-19 11:36:22 +0800930void CommandReader::takePresentFence(Display display, int* outPresentFence)
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800931{
932 auto found = mReturnData.find(display);
933 if (found == mReturnData.end()) {
Chia-I Wu67e376d2016-12-19 11:36:22 +0800934 *outPresentFence = -1;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800935 return;
936 }
937
938 ReturnData& data = found->second;
939
Chia-I Wu67e376d2016-12-19 11:36:22 +0800940 *outPresentFence = data.presentFence;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800941 data.presentFence = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800942}
943
944} // namespace Hwc2
945
946} // namespace android