blob: 63fd1e8ebea6ee1da444b098f2ce68be39723dac [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{
94 return (ret.getStatus().isOk()) ? static_cast<T>(ret) :
95 static_cast<T>(default_val);
96}
97
98Error unwrapRet(Return<Error>& ret)
99{
100 return unwrapRet(ret, kDefaultError);
101}
102
103template<typename T>
104void assignFromHidlVec(std::vector<T>& vec, const hidl_vec<T>& data)
105{
106 vec.clear();
107 vec.insert(vec.begin(), &data[0], &data[data.size()]);
108}
109
110} // anonymous namespace
111
112Composer::Composer()
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800113 : mWriter(kWriterInitialSize)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800114{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800115 mComposer = IComposer::getService("hwcomposer");
116 if (mComposer == nullptr) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800117 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
118 }
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800119
120 mComposer->createClient(
121 [&](const auto& tmpError, const auto& tmpClient)
122 {
123 if (tmpError == Error::NONE) {
124 mClient = tmpClient;
125 }
126 });
127 if (mClient == nullptr) {
128 LOG_ALWAYS_FATAL("failed to create composer client");
129 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800130}
131
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800132std::vector<IComposer::Capability> Composer::getCapabilities()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800133{
134 std::vector<IComposer::Capability> capabilities;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800135 mComposer->getCapabilities(
Chia-I Wuaab99f52016-10-05 12:59:58 +0800136 [&](const auto& tmpCapabilities) {
137 assignFromHidlVec(capabilities, tmpCapabilities);
138 });
139
140 return capabilities;
141}
142
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800143std::string Composer::dumpDebugInfo()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800144{
145 std::string info;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800146 mComposer->dumpDebugInfo([&](const auto& tmpInfo) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800147 info = tmpInfo.c_str();
148 });
149
150 return info;
151}
152
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800153void Composer::registerCallback(const sp<IComposerCallback>& callback)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800154{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800155 auto ret = mClient->registerCallback(callback);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800156 if (!ret.getStatus().isOk()) {
157 ALOGE("failed to register IComposerCallback");
158 }
159}
160
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800161uint32_t Composer::getMaxVirtualDisplayCount()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800162{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800163 auto ret = mClient->getMaxVirtualDisplayCount();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800164 return unwrapRet(ret, 0);
165}
166
167Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800168 PixelFormat& format, Display& display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800169{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800170 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800171 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800172 mClient->createVirtualDisplay(width, height, format, bufferSlotCount,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800173 [&](const auto& tmpError, const auto& tmpDisplay,
174 const auto& tmpFormat) {
175 error = tmpError;
176 if (error != Error::NONE) {
177 return;
178 }
179
180 display = tmpDisplay;
181 format = tmpFormat;
182 });
183
184 return error;
185}
186
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800187Error Composer::destroyVirtualDisplay(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800188{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800189 auto ret = mClient->destroyVirtualDisplay(display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800190 return unwrapRet(ret);
191}
192
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800193Error Composer::acceptDisplayChanges(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800194{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800195 mWriter.selectDisplay(display);
196 mWriter.acceptDisplayChanges();
197 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800198}
199
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800200Error Composer::createLayer(Display display, Layer& layer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800201{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800202 const uint32_t bufferSlotCount = 1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800203 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800204 mClient->createLayer(display, bufferSlotCount,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800205 [&](const auto& tmpError, const auto& tmpLayer) {
206 error = tmpError;
207 if (error != Error::NONE) {
208 return;
209 }
210
211 layer = tmpLayer;
212 });
213
214 return error;
215}
216
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800217Error Composer::destroyLayer(Display display, Layer layer)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800218{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800219 auto ret = mClient->destroyLayer(display, layer);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800220 return unwrapRet(ret);
221}
222
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800223Error Composer::getActiveConfig(Display display, Config& config)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800224{
225 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800226 mClient->getActiveConfig(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800227 [&](const auto& tmpError, const auto& tmpConfig) {
228 error = tmpError;
229 if (error != Error::NONE) {
230 return;
231 }
232
233 config = tmpConfig;
234 });
235
236 return error;
237}
238
239Error Composer::getChangedCompositionTypes(Display display,
240 std::vector<Layer>& layers,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800241 std::vector<IComposerClient::Composition>& types)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800242{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800243 mReader.takeChangedCompositionTypes(display, layers, types);
244 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800245}
246
247Error Composer::getColorModes(Display display,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800248 std::vector<ColorMode>& modes)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800249{
250 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800251 mClient->getColorModes(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800252 [&](const auto& tmpError, const auto& tmpModes) {
253 error = tmpError;
254 if (error != Error::NONE) {
255 return;
256 }
257
258 assignFromHidlVec(modes, tmpModes);
259 });
260
261 return error;
262}
263
264Error Composer::getDisplayAttribute(Display display, Config config,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800265 IComposerClient::Attribute attribute, int32_t& value)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800266{
267 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800268 mClient->getDisplayAttribute(display, config, attribute,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800269 [&](const auto& tmpError, const auto& tmpValue) {
270 error = tmpError;
271 if (error != Error::NONE) {
272 return;
273 }
274
275 value = tmpValue;
276 });
277
278 return error;
279}
280
281Error Composer::getDisplayConfigs(Display display,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800282 std::vector<Config>& configs)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800283{
284 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800285 mClient->getDisplayConfigs(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800286 [&](const auto& tmpError, const auto& tmpConfigs) {
287 error = tmpError;
288 if (error != Error::NONE) {
289 return;
290 }
291
292 assignFromHidlVec(configs, tmpConfigs);
293 });
294
295 return error;
296}
297
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800298Error Composer::getDisplayName(Display display, std::string& name)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800299{
300 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800301 mClient->getDisplayName(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800302 [&](const auto& tmpError, const auto& tmpName) {
303 error = tmpError;
304 if (error != Error::NONE) {
305 return;
306 }
307
308 name = tmpName.c_str();
309 });
310
311 return error;
312}
313
314Error Composer::getDisplayRequests(Display display,
315 uint32_t& displayRequestMask, std::vector<Layer>& layers,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800316 std::vector<uint32_t>& layerRequestMasks)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800317{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800318 mReader.takeDisplayRequests(display, displayRequestMask,
319 layers, layerRequestMasks);
320 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800321}
322
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800323Error Composer::getDisplayType(Display display, IComposerClient::DisplayType& type)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800324{
325 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800326 mClient->getDisplayType(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800327 [&](const auto& tmpError, const auto& tmpType) {
328 error = tmpError;
329 if (error != Error::NONE) {
330 return;
331 }
332
333 type = tmpType;
334 });
335
336 return error;
337}
338
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800339Error Composer::getDozeSupport(Display display, bool& support)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800340{
341 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800342 mClient->getDozeSupport(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800343 [&](const auto& tmpError, const auto& tmpSupport) {
344 error = tmpError;
345 if (error != Error::NONE) {
346 return;
347 }
348
349 support = tmpSupport;
350 });
351
352 return error;
353}
354
355Error Composer::getHdrCapabilities(Display display, std::vector<Hdr>& types,
356 float& maxLuminance, float& maxAverageLuminance,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800357 float& minLuminance)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800358{
359 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800360 mClient->getHdrCapabilities(display,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800361 [&](const auto& tmpError, const auto& tmpTypes,
362 const auto& tmpMaxLuminance,
363 const auto& tmpMaxAverageLuminance,
364 const auto& tmpMinLuminance) {
365 error = tmpError;
366 if (error != Error::NONE) {
367 return;
368 }
369
370 assignFromHidlVec(types, tmpTypes);
371 maxLuminance = tmpMaxLuminance;
372 maxAverageLuminance = tmpMaxAverageLuminance;
373 minLuminance = tmpMinLuminance;
374 });
375
376 return error;
377}
378
379Error Composer::getReleaseFences(Display display, std::vector<Layer>& layers,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800380 std::vector<int>& releaseFences)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800381{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800382 mReader.takeReleaseFences(display, layers, releaseFences);
383 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800384}
385
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800386Error Composer::presentDisplay(Display display, int& presentFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800387{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800388 mWriter.selectDisplay(display);
389 mWriter.presentDisplay();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800390
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800391 Error error = execute();
392 if (error != Error::NONE) {
393 return error;
394 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800395
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800396 mReader.takePresentFence(display, presentFence);
397
398 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800399}
400
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800401Error Composer::setActiveConfig(Display display, Config config)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800402{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800403 auto ret = mClient->setActiveConfig(display, config);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800404 return unwrapRet(ret);
405}
406
407Error Composer::setClientTarget(Display display, const native_handle_t* target,
408 int acquireFence, Dataspace dataspace,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800409 const std::vector<IComposerClient::Rect>& damage)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800410{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800411 mWriter.selectDisplay(display);
412 mWriter.setClientTarget(0, target, acquireFence, dataspace, damage);
413 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800414}
415
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800416Error Composer::setColorMode(Display display, ColorMode mode)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800417{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800418 auto ret = mClient->setColorMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800419 return unwrapRet(ret);
420}
421
422Error Composer::setColorTransform(Display display, const float* matrix,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800423 ColorTransform hint)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800424{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800425 mWriter.selectDisplay(display);
426 mWriter.setColorTransform(matrix, hint);
427 return Error::NONE;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800428}
429
430Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800431 int releaseFence)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800432{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800433 mWriter.selectDisplay(display);
434 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
435 return Error::NONE;
436}
Chia-I Wuaab99f52016-10-05 12:59:58 +0800437
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800438Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
439{
440 auto ret = mClient->setPowerMode(display, mode);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800441 return unwrapRet(ret);
442}
443
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800444Error Composer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800445{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800446 auto ret = mClient->setVsyncEnabled(display, enabled);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800447 return unwrapRet(ret);
448}
449
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800450Error Composer::setClientTargetSlotCount(Display display)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800451{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800452 const uint32_t bufferSlotCount = 1;
453 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800454 return unwrapRet(ret);
455}
456
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800457Error Composer::validateDisplay(Display display, uint32_t& numTypes,
458 uint32_t& numRequests)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800459{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800460 mWriter.selectDisplay(display);
461 mWriter.validateDisplay();
462
463 Error error = execute();
464 if (error != Error::NONE) {
465 return error;
466 }
467
468 mReader.hasChanges(display, numTypes, numRequests);
469
470 return Error::NONE;
471}
472
473Error Composer::setCursorPosition(Display display, Layer layer,
474 int32_t x, int32_t y)
475{
476 mWriter.selectDisplay(display);
477 mWriter.selectLayer(layer);
478 mWriter.setLayerCursorPosition(x, y);
479 return Error::NONE;
480}
481
482Error Composer::setLayerBuffer(Display display, Layer layer,
483 const native_handle_t* buffer, int acquireFence)
484{
485 mWriter.selectDisplay(display);
486 mWriter.selectLayer(layer);
487 mWriter.setLayerBuffer(0, buffer, acquireFence);
488 return Error::NONE;
489}
490
491Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
492 const std::vector<IComposerClient::Rect>& damage)
493{
494 mWriter.selectDisplay(display);
495 mWriter.selectLayer(layer);
496 mWriter.setLayerSurfaceDamage(damage);
497 return Error::NONE;
498}
499
500Error Composer::setLayerBlendMode(Display display, Layer layer,
501 IComposerClient::BlendMode mode)
502{
503 mWriter.selectDisplay(display);
504 mWriter.selectLayer(layer);
505 mWriter.setLayerBlendMode(mode);
506 return Error::NONE;
507}
508
509Error Composer::setLayerColor(Display display, Layer layer,
510 const IComposerClient::Color& color)
511{
512 mWriter.selectDisplay(display);
513 mWriter.selectLayer(layer);
514 mWriter.setLayerColor(color);
515 return Error::NONE;
516}
517
518Error Composer::setLayerCompositionType(Display display, Layer layer,
519 IComposerClient::Composition type)
520{
521 mWriter.selectDisplay(display);
522 mWriter.selectLayer(layer);
523 mWriter.setLayerCompositionType(type);
524 return Error::NONE;
525}
526
527Error Composer::setLayerDataspace(Display display, Layer layer,
528 Dataspace dataspace)
529{
530 mWriter.selectDisplay(display);
531 mWriter.selectLayer(layer);
532 mWriter.setLayerDataspace(dataspace);
533 return Error::NONE;
534}
535
536Error Composer::setLayerDisplayFrame(Display display, Layer layer,
537 const IComposerClient::Rect& frame)
538{
539 mWriter.selectDisplay(display);
540 mWriter.selectLayer(layer);
541 mWriter.setLayerDisplayFrame(frame);
542 return Error::NONE;
543}
544
545Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
546 float alpha)
547{
548 mWriter.selectDisplay(display);
549 mWriter.selectLayer(layer);
550 mWriter.setLayerPlaneAlpha(alpha);
551 return Error::NONE;
552}
553
554Error Composer::setLayerSidebandStream(Display display, Layer layer,
555 const native_handle_t* stream)
556{
557 mWriter.selectDisplay(display);
558 mWriter.selectLayer(layer);
559 mWriter.setLayerSidebandStream(stream);
560 return Error::NONE;
561}
562
563Error Composer::setLayerSourceCrop(Display display, Layer layer,
564 const IComposerClient::FRect& crop)
565{
566 mWriter.selectDisplay(display);
567 mWriter.selectLayer(layer);
568 mWriter.setLayerSourceCrop(crop);
569 return Error::NONE;
570}
571
572Error Composer::setLayerTransform(Display display, Layer layer,
573 Transform transform)
574{
575 mWriter.selectDisplay(display);
576 mWriter.selectLayer(layer);
577 mWriter.setLayerTransform(transform);
578 return Error::NONE;
579}
580
581Error Composer::setLayerVisibleRegion(Display display, Layer layer,
582 const std::vector<IComposerClient::Rect>& visible)
583{
584 mWriter.selectDisplay(display);
585 mWriter.selectLayer(layer);
586 mWriter.setLayerVisibleRegion(visible);
587 return Error::NONE;
588}
589
590Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z)
591{
592 mWriter.selectDisplay(display);
593 mWriter.selectLayer(layer);
594 mWriter.setLayerZOrder(z);
595 return Error::NONE;
596}
597
598Error Composer::execute()
599{
600 // prepare input command queue
601 bool queueChanged = false;
602 uint32_t commandLength = 0;
603 hidl_vec<hidl_handle> commandHandles;
604 if (!mWriter.writeQueue(queueChanged, commandLength, commandHandles)) {
605 mWriter.reset();
606 return Error::NO_RESOURCES;
607 }
608
609 // set up new input command queue if necessary
610 if (queueChanged) {
611 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
612 auto error = unwrapRet(ret);
613 if (error != Error::NONE) {
614 mWriter.reset();
615 return error;
616 }
617 }
618
Chia-I Wuaab99f52016-10-05 12:59:58 +0800619 Error error = kDefaultError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800620 mClient->executeCommands(commandLength, commandHandles,
621 [&](const auto& tmpError, const auto& tmpOutChanged,
622 const auto& tmpOutLength, const auto& tmpOutHandles)
623 {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800624 error = tmpError;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800625
626 // set up new output command queue if necessary
627 if (error == Error::NONE && tmpOutChanged) {
628 error = kDefaultError;
629 mClient->getOutputCommandQueue(
630 [&](const auto& tmpError,
631 const auto& tmpDescriptor)
632 {
633 error = tmpError;
634 if (error != Error::NONE) {
635 return;
636 }
637
638 mReader.setMQDescriptor(tmpDescriptor);
639 });
640 }
641
Chia-I Wuaab99f52016-10-05 12:59:58 +0800642 if (error != Error::NONE) {
643 return;
644 }
645
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800646 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
647 error = mReader.parse();
648 mReader.reset();
649 } else {
650 error = Error::NO_RESOURCES;
651 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800652 });
653
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800654 if (error == Error::NONE) {
655 std::vector<CommandReader::CommandError> commandErrors =
656 mReader.takeErrors();
657
658 for (const auto& cmdErr : commandErrors) {
659 auto command = mWriter.getCommand(cmdErr.location);
660
661 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
662 command == IComposerClient::Command::PRESENT_DISPLAY) {
663 error = cmdErr.error;
664 } else {
665 ALOGW("command 0x%x generated error %d",
666 command, cmdErr.error);
667 }
668 }
669 }
670
671 mWriter.reset();
672
Chia-I Wuaab99f52016-10-05 12:59:58 +0800673 return error;
674}
675
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800676CommandReader::~CommandReader()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800677{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800678 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800679}
680
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800681Error CommandReader::parse()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800682{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800683 resetData();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800684
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800685 IComposerClient::Command command;
686 uint16_t length = 0;
687
688 while (!isEmpty()) {
689 if (!beginCommand(command, length)) {
690 break;
691 }
692
693 bool parsed = false;
694 switch (command) {
695 case IComposerClient::Command::SELECT_DISPLAY:
696 parsed = parseSelectDisplay(length);
697 break;
698 case IComposerClient::Command::SET_ERROR:
699 parsed = parseSetError(length);
700 break;
701 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
702 parsed = parseSetChangedCompositionTypes(length);
703 break;
704 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
705 parsed = parseSetDisplayRequests(length);
706 break;
707 case IComposerClient::Command::SET_PRESENT_FENCE:
708 parsed = parseSetPresentFence(length);
709 break;
710 case IComposerClient::Command::SET_RELEASE_FENCES:
711 parsed = parseSetReleaseFences(length);
712 break;
713 default:
714 parsed = false;
715 break;
716 }
717
718 endCommand();
719
720 if (!parsed) {
721 ALOGE("failed to parse command 0x%x length %" PRIu16,
722 command, length);
723 break;
724 }
725 }
726
727 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800728}
729
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800730bool CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800731{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800732 if (length != CommandWriter::kSelectDisplayLength) {
733 return false;
734 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800735
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800736 mCurrentReturnData = &mReturnData[read64()];
737
738 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800739}
740
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800741bool CommandReader::parseSetError(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800742{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800743 if (length != CommandWriter::kSetErrorLength) {
744 return false;
745 }
746
747 auto location = read();
748 auto error = static_cast<Error>(readSigned());
749
750 mErrors.emplace_back(CommandError{location, error});
751
752 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800753}
754
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800755bool CommandReader::parseSetChangedCompositionTypes(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800756{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800757 // (layer id, composition type) pairs
758 if (length % 3 != 0 || !mCurrentReturnData) {
759 return false;
760 }
761
762 uint32_t count = length / 3;
763 mCurrentReturnData->changedLayers.reserve(count);
764 mCurrentReturnData->compositionTypes.reserve(count);
765 while (count > 0) {
766 auto layer = read64();
767 auto type = static_cast<IComposerClient::Composition>(readSigned());
768
769 mCurrentReturnData->changedLayers.push_back(layer);
770 mCurrentReturnData->compositionTypes.push_back(type);
771
772 count--;
773 }
774
775 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800776}
777
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800778bool CommandReader::parseSetDisplayRequests(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800779{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800780 // display requests followed by (layer id, layer requests) pairs
781 if (length % 3 != 1 || !mCurrentReturnData) {
782 return false;
783 }
784
785 mCurrentReturnData->displayRequests = read();
786
787 uint32_t count = (length - 1) / 3;
788 mCurrentReturnData->requestedLayers.reserve(count);
789 mCurrentReturnData->requestMasks.reserve(count);
790 while (count > 0) {
791 auto layer = read64();
792 auto layerRequestMask = read();
793
794 mCurrentReturnData->requestedLayers.push_back(layer);
795 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
796
797 count--;
798 }
799
800 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800801}
802
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800803bool CommandReader::parseSetPresentFence(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800804{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800805 if (length != CommandWriter::kSetPresentFenceLength ||
806 !mCurrentReturnData) {
807 return false;
808 }
809
810 if (mCurrentReturnData->presentFence >= 0) {
811 close(mCurrentReturnData->presentFence);
812 }
813 mCurrentReturnData->presentFence = readFence();
814
815 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800816}
817
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800818bool CommandReader::parseSetReleaseFences(uint16_t length)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800819{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800820 // (layer id, release fence index) pairs
821 if (length % 3 != 0 || !mCurrentReturnData) {
822 return false;
823 }
824
825 uint32_t count = length / 3;
826 mCurrentReturnData->releasedLayers.reserve(count);
827 mCurrentReturnData->releaseFences.reserve(count);
828 while (count > 0) {
829 auto layer = read64();
830 auto fence = readFence();
831
832 mCurrentReturnData->releasedLayers.push_back(layer);
833 mCurrentReturnData->releaseFences.push_back(fence);
834
835 count--;
836 }
837
838 return true;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800839}
840
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800841void CommandReader::resetData()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800842{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800843 mErrors.clear();
844
845 for (auto& data : mReturnData) {
846 if (data.second.presentFence >= 0) {
847 close(data.second.presentFence);
848 }
849 for (auto fence : data.second.releaseFences) {
850 if (fence >= 0) {
851 close(fence);
852 }
853 }
854 }
855
856 mReturnData.clear();
857 mCurrentReturnData = nullptr;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800858}
859
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800860std::vector<CommandReader::CommandError> CommandReader::takeErrors()
Chia-I Wuaab99f52016-10-05 12:59:58 +0800861{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800862 return std::move(mErrors);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800863}
864
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800865bool CommandReader::hasChanges(Display display,
866 uint32_t& numChangedCompositionTypes,
867 uint32_t& numLayerRequestMasks) const
Chia-I Wuaab99f52016-10-05 12:59:58 +0800868{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800869 auto found = mReturnData.find(display);
870 if (found == mReturnData.end()) {
871 numChangedCompositionTypes = 0;
872 numLayerRequestMasks = 0;
873 return false;
874 }
875
876 const ReturnData& data = found->second;
877
878 numChangedCompositionTypes = data.compositionTypes.size();
879 numLayerRequestMasks = data.requestMasks.size();
880
881 return !(data.compositionTypes.empty() && data.requestMasks.empty());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800882}
883
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800884void CommandReader::takeChangedCompositionTypes(Display display,
885 std::vector<Layer>& layers,
886 std::vector<IComposerClient::Composition>& types)
Chia-I Wuaab99f52016-10-05 12:59:58 +0800887{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800888 auto found = mReturnData.find(display);
889 if (found == mReturnData.end()) {
890 layers.clear();
891 types.clear();
892 return;
893 }
894
895 ReturnData& data = found->second;
896
897 layers = std::move(data.changedLayers);
898 types = std::move(data.compositionTypes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800899}
900
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800901void CommandReader::takeDisplayRequests(Display display,
902 uint32_t& displayRequestMask, std::vector<Layer>& layers,
903 std::vector<uint32_t>& layerRequestMasks)
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()) {
907 displayRequestMask = 0;
908 layers.clear();
909 layerRequestMasks.clear();
910 return;
911 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800912
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800913 ReturnData& data = found->second;
914
915 displayRequestMask = data.displayRequests;
916 layers = std::move(data.requestedLayers);
917 layerRequestMasks = std::move(data.requestMasks);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800918}
919
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800920void CommandReader::takeReleaseFences(Display display,
921 std::vector<Layer>& layers, std::vector<int>& releaseFences)
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()) {
925 layers.clear();
926 releaseFences.clear();
927 return;
928 }
929
930 ReturnData& data = found->second;
931
932 layers = std::move(data.releasedLayers);
933 releaseFences = std::move(data.releaseFences);
934}
935
936void CommandReader::takePresentFence(Display display, int& presentFence)
937{
938 auto found = mReturnData.find(display);
939 if (found == mReturnData.end()) {
940 presentFence = -1;
941 return;
942 }
943
944 ReturnData& data = found->second;
945
946 presentFence = data.presentFence;
947 data.presentFence = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800948}
949
950} // namespace Hwc2
951
952} // namespace android