blob: 49415ee3a63cda2e8e692746b7990ad4a1e3d763 [file] [log] [blame]
Chia-I Wubb61a722016-10-24 15:40:20 +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#define LOG_TAG "HwcPassthrough"
18
19#include <hardware/gralloc.h>
20#include <hardware/gralloc1.h>
21#include <log/log.h>
22
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -050023#include "ComposerClient.h"
Chia-I Wubb61a722016-10-24 15:40:20 +080024#include "Hwc.h"
Chia-I Wubb61a722016-10-24 15:40:20 +080025#include "IComposerCommandBuffer.h"
26
27namespace android {
28namespace hardware {
29namespace graphics {
30namespace composer {
31namespace V2_1 {
32namespace implementation {
33
34namespace {
35
36class HandleImporter {
37public:
38 HandleImporter() : mInitialized(false) {}
39
40 bool initialize()
41 {
42 // allow only one client
43 if (mInitialized) {
44 return false;
45 }
46
47 if (!openGralloc()) {
48 return false;
49 }
50
51 mInitialized = true;
52 return true;
53 }
54
55 void cleanup()
56 {
57 if (!mInitialized) {
58 return;
59 }
60
61 closeGralloc();
62 mInitialized = false;
63 }
64
65 // In IComposer, any buffer_handle_t is owned by the caller and we need to
66 // make a clone for hwcomposer2. We also need to translate empty handle
67 // to nullptr. This function does that, in-place.
68 bool importBuffer(buffer_handle_t& handle)
69 {
70 if (!handle) {
71 return true;
72 }
73
74 if (!handle->numFds && !handle->numInts) {
75 handle = nullptr;
76 return true;
77 }
78
79 buffer_handle_t clone = cloneBuffer(handle);
80 if (!clone) {
81 return false;
82 }
83
84 handle = clone;
85 return true;
86 }
87
88 void freeBuffer(buffer_handle_t handle)
89 {
90 if (!handle) {
91 return;
92 }
93
94 releaseBuffer(handle);
95 }
96
97private:
98 bool mInitialized;
99
100 // Some existing gralloc drivers do not support retaining more than once,
101 // when we are in passthrough mode.
102#ifdef BINDERIZED
103 bool openGralloc()
104 {
Chia-I Wue1768352016-12-19 12:56:54 +0800105 const hw_module_t* module = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +0800106 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
107 if (err) {
108 ALOGE("failed to get gralloc module");
109 return false;
110 }
111
112 uint8_t major = (module->module_api_version >> 8) & 0xff;
113 if (major > 1) {
114 ALOGE("unknown gralloc module major version %d", major);
115 return false;
116 }
117
118 if (major == 1) {
119 err = gralloc1_open(module, &mDevice);
120 if (err) {
121 ALOGE("failed to open gralloc1 device");
122 return false;
123 }
124
125 mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
126 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
127 mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
128 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
129 if (!mRetain || !mRelease) {
130 ALOGE("invalid gralloc1 device");
131 gralloc1_close(mDevice);
132 return false;
133 }
134 } else {
135 mModule = reinterpret_cast<const gralloc_module_t*>(module);
136 }
137
138 return true;
139 }
140
141 void closeGralloc()
142 {
143 if (mDevice) {
144 gralloc1_close(mDevice);
145 }
146 }
147
148 buffer_handle_t cloneBuffer(buffer_handle_t handle)
149 {
150 native_handle_t* clone = native_handle_clone(handle);
151 if (!clone) {
152 ALOGE("failed to clone buffer %p", handle);
153 return nullptr;
154 }
155
156 bool err;
157 if (mDevice) {
158 err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
159 } else {
160 err = (mModule->registerBuffer(mModule, clone) != 0);
161 }
162
163 if (err) {
164 ALOGE("failed to retain/register buffer %p", clone);
165 native_handle_close(clone);
166 native_handle_delete(clone);
167 return nullptr;
168 }
169
170 return clone;
171 }
172
173 void releaseBuffer(buffer_handle_t handle)
174 {
175 if (mDevice) {
176 mRelease(mDevice, handle);
177 } else {
178 mModule->unregisterBuffer(mModule, handle);
Chia-I Wubb61a722016-10-24 15:40:20 +0800179 }
Chia-I Wu939e4012016-12-12 21:51:33 +0800180 native_handle_close(handle);
181 native_handle_delete(const_cast<native_handle_t*>(handle));
Chia-I Wubb61a722016-10-24 15:40:20 +0800182 }
183
184 // gralloc1
185 gralloc1_device_t* mDevice;
186 GRALLOC1_PFN_RETAIN mRetain;
187 GRALLOC1_PFN_RELEASE mRelease;
188
189 // gralloc0
190 const gralloc_module_t* mModule;
191#else
192 bool openGralloc() { return true; }
193 void closeGralloc() {}
194 buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
195 void releaseBuffer(buffer_handle_t) {}
196#endif
197};
198
199HandleImporter sHandleImporter;
200
201} // anonymous namespace
202
203BufferClone::BufferClone()
204 : mHandle(nullptr)
205{
206}
207
208BufferClone::BufferClone(BufferClone&& other)
209{
210 mHandle = other.mHandle;
211 other.mHandle = nullptr;
212}
213
214BufferClone& BufferClone::operator=(buffer_handle_t handle)
215{
216 clear();
217 mHandle = handle;
218 return *this;
219}
220
221BufferClone::~BufferClone()
222{
223 clear();
224}
225
226void BufferClone::clear()
227{
228 if (mHandle) {
229 sHandleImporter.freeBuffer(mHandle);
230 }
231}
232
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500233ComposerClient::ComposerClient(ComposerBase& hal)
234 : mHal(hal), mWriter(kWriterInitialSize)
Chia-I Wubb61a722016-10-24 15:40:20 +0800235{
Chia-I Wubb61a722016-10-24 15:40:20 +0800236}
237
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500238ComposerClient::~ComposerClient()
Chia-I Wubb61a722016-10-24 15:40:20 +0800239{
240 mHal.enableCallback(false);
241 mHal.removeClient();
242
243 // no need to grab the mutex as any in-flight hwbinder call should keep
244 // the client alive
245 for (const auto& dpy : mDisplayData) {
246 if (!dpy.second.Layers.empty()) {
247 ALOGW("client destroyed with valid layers");
248 }
249 for (const auto& ly : dpy.second.Layers) {
250 mHal.destroyLayer(dpy.first, ly.first);
251 }
252
253 if (dpy.second.IsVirtual) {
254 ALOGW("client destroyed with valid virtual display");
255 mHal.destroyVirtualDisplay(dpy.first);
256 }
257 }
258
259 mDisplayData.clear();
260
261 sHandleImporter.cleanup();
262}
263
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500264void ComposerClient::initialize()
265{
266 mReader = createCommandReader();
267 if (!sHandleImporter.initialize()) {
268 LOG_ALWAYS_FATAL("failed to initialize handle importer");
269 }
270}
271
272void ComposerClient::onHotplug(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800273 IComposerCallback::Connection connected)
274{
275 {
276 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
277
278 if (connected == IComposerCallback::Connection::CONNECTED) {
279 mDisplayData.emplace(display, DisplayData(false));
280 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
281 mDisplayData.erase(display);
282 }
283 }
284
285 mCallback->onHotplug(display, connected);
286}
287
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500288void ComposerClient::onRefresh(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800289{
290 mCallback->onRefresh(display);
291}
292
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500293void ComposerClient::onVsync(Display display, int64_t timestamp)
Chia-I Wubb61a722016-10-24 15:40:20 +0800294{
295 mCallback->onVsync(display, timestamp);
296}
297
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500298Return<void> ComposerClient::registerCallback(
299 const sp<IComposerCallback>& callback)
Chia-I Wubb61a722016-10-24 15:40:20 +0800300{
301 // no locking as we require this function to be called only once
302 mCallback = callback;
303 mHal.enableCallback(callback != nullptr);
304
305 return Void();
306}
307
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500308Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
Chia-I Wubb61a722016-10-24 15:40:20 +0800309{
310 return mHal.getMaxVirtualDisplayCount();
311}
312
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500313Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
314 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
Chia-I Wubb61a722016-10-24 15:40:20 +0800315 createVirtualDisplay_cb hidl_cb)
316{
Chia-I Wue1768352016-12-19 12:56:54 +0800317 Display display = 0;
318 Error err = mHal.createVirtualDisplay(width, height,
319 &formatHint, &display);
Chia-I Wubb61a722016-10-24 15:40:20 +0800320 if (err == Error::NONE) {
321 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
322
323 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
324 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
325 }
326
327 hidl_cb(err, display, formatHint);
328 return Void();
329}
330
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500331Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800332{
333 Error err = mHal.destroyVirtualDisplay(display);
334 if (err == Error::NONE) {
335 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
336
337 mDisplayData.erase(display);
338 }
339
340 return err;
341}
342
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500343Return<void> ComposerClient::createLayer(Display display,
344 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800345{
Chia-I Wue1768352016-12-19 12:56:54 +0800346 Layer layer = 0;
347 Error err = mHal.createLayer(display, &layer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800348 if (err == Error::NONE) {
349 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
350
351 auto dpy = mDisplayData.find(display);
352 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
353 ly->second.Buffers.resize(bufferSlotCount);
354 }
355
356 hidl_cb(err, layer);
357 return Void();
358}
359
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500360Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
Chia-I Wubb61a722016-10-24 15:40:20 +0800361{
362 Error err = mHal.destroyLayer(display, layer);
363 if (err == Error::NONE) {
364 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
365
366 auto dpy = mDisplayData.find(display);
367 dpy->second.Layers.erase(layer);
368 }
369
370 return err;
371}
372
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500373Return<void> ComposerClient::getActiveConfig(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800374 getActiveConfig_cb hidl_cb)
375{
Chia-I Wue1768352016-12-19 12:56:54 +0800376 Config config = 0;
377 Error err = mHal.getActiveConfig(display, &config);
Chia-I Wubb61a722016-10-24 15:40:20 +0800378
379 hidl_cb(err, config);
380 return Void();
381}
382
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500383Return<Error> ComposerClient::getClientTargetSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800384 uint32_t width, uint32_t height,
385 PixelFormat format, Dataspace dataspace)
386{
387 Error err = mHal.getClientTargetSupport(display,
388 width, height, format, dataspace);
389 return err;
390}
391
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500392Return<void> ComposerClient::getColorModes(Display display,
393 getColorModes_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800394{
395 hidl_vec<ColorMode> modes;
Chia-I Wue1768352016-12-19 12:56:54 +0800396 Error err = mHal.getColorModes(display, &modes);
Chia-I Wubb61a722016-10-24 15:40:20 +0800397
398 hidl_cb(err, modes);
399 return Void();
400}
401
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500402Return<void> ComposerClient::getDisplayAttribute(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800403 Config config, Attribute attribute,
404 getDisplayAttribute_cb hidl_cb)
405{
Chia-I Wue1768352016-12-19 12:56:54 +0800406 int32_t value = 0;
407 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
Chia-I Wubb61a722016-10-24 15:40:20 +0800408
409 hidl_cb(err, value);
410 return Void();
411}
412
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500413Return<void> ComposerClient::getDisplayConfigs(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800414 getDisplayConfigs_cb hidl_cb)
415{
416 hidl_vec<Config> configs;
Chia-I Wue1768352016-12-19 12:56:54 +0800417 Error err = mHal.getDisplayConfigs(display, &configs);
Chia-I Wubb61a722016-10-24 15:40:20 +0800418
419 hidl_cb(err, configs);
420 return Void();
421}
422
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500423Return<void> ComposerClient::getDisplayName(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800424 getDisplayName_cb hidl_cb)
425{
426 hidl_string name;
Chia-I Wue1768352016-12-19 12:56:54 +0800427 Error err = mHal.getDisplayName(display, &name);
Chia-I Wubb61a722016-10-24 15:40:20 +0800428
429 hidl_cb(err, name);
430 return Void();
431}
432
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500433Return<void> ComposerClient::getDisplayType(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800434 getDisplayType_cb hidl_cb)
435{
Chia-I Wue1768352016-12-19 12:56:54 +0800436 DisplayType type = DisplayType::INVALID;
437 Error err = mHal.getDisplayType(display, &type);
Chia-I Wubb61a722016-10-24 15:40:20 +0800438
439 hidl_cb(err, type);
440 return Void();
441}
442
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500443Return<void> ComposerClient::getDozeSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800444 getDozeSupport_cb hidl_cb)
445{
Chia-I Wue1768352016-12-19 12:56:54 +0800446 bool support = false;
447 Error err = mHal.getDozeSupport(display, &support);
Chia-I Wubb61a722016-10-24 15:40:20 +0800448
449 hidl_cb(err, support);
450 return Void();
451}
452
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500453Return<void> ComposerClient::getHdrCapabilities(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800454 getHdrCapabilities_cb hidl_cb)
455{
456 hidl_vec<Hdr> types;
457 float max_lumi = 0.0f;
458 float max_avg_lumi = 0.0f;
459 float min_lumi = 0.0f;
Chia-I Wue1768352016-12-19 12:56:54 +0800460 Error err = mHal.getHdrCapabilities(display, &types,
461 &max_lumi, &max_avg_lumi, &min_lumi);
Chia-I Wubb61a722016-10-24 15:40:20 +0800462
463 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
464 return Void();
465}
466
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500467Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800468 uint32_t clientTargetSlotCount)
469{
470 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
471
472 auto dpy = mDisplayData.find(display);
473 if (dpy == mDisplayData.end()) {
474 return Error::BAD_DISPLAY;
475 }
476
477 dpy->second.ClientTargets.resize(clientTargetSlotCount);
478
479 return Error::NONE;
480}
481
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500482Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
Chia-I Wubb61a722016-10-24 15:40:20 +0800483{
484 Error err = mHal.setActiveConfig(display, config);
485 return err;
486}
487
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500488Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800489{
490 Error err = mHal.setColorMode(display, mode);
491 return err;
492}
493
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500494Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800495{
496 Error err = mHal.setPowerMode(display, mode);
497 return err;
498}
499
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500500Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
Chia-I Wubb61a722016-10-24 15:40:20 +0800501{
502 Error err = mHal.setVsyncEnabled(display, enabled);
503 return err;
504}
505
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500506Return<Error> ComposerClient::setInputCommandQueue(
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800507 const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800508{
509 std::lock_guard<std::mutex> lock(mCommandMutex);
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500510 return mReader->setMQDescriptor(descriptor) ?
Chia-I Wubb61a722016-10-24 15:40:20 +0800511 Error::NONE : Error::NO_RESOURCES;
512}
513
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500514Return<void> ComposerClient::getOutputCommandQueue(
Chia-I Wubb61a722016-10-24 15:40:20 +0800515 getOutputCommandQueue_cb hidl_cb)
516{
517 // no locking as we require this function to be called inside
518 // executeCommands_cb
519
520 auto outDescriptor = mWriter.getMQDescriptor();
521 if (outDescriptor) {
522 hidl_cb(Error::NONE, *outDescriptor);
523 } else {
Hridya Valsaraju790db102017-01-10 08:58:23 -0800524 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
Chia-I Wubb61a722016-10-24 15:40:20 +0800525 }
526
527 return Void();
528}
529
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500530Return<void> ComposerClient::executeCommands(uint32_t inLength,
Chia-I Wubb61a722016-10-24 15:40:20 +0800531 const hidl_vec<hidl_handle>& inHandles,
532 executeCommands_cb hidl_cb)
533{
534 std::lock_guard<std::mutex> lock(mCommandMutex);
535
536 bool outChanged = false;
537 uint32_t outLength = 0;
538 hidl_vec<hidl_handle> outHandles;
539
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500540 if (!mReader->readQueue(inLength, inHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800541 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
542 return Void();
543 }
544
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500545 Error err = mReader->parse();
Chia-I Wubb61a722016-10-24 15:40:20 +0800546 if (err == Error::NONE &&
Chia-I Wue1768352016-12-19 12:56:54 +0800547 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800548 err = Error::NO_RESOURCES;
549 }
550
551 hidl_cb(err, outChanged, outLength, outHandles);
552
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500553 mReader->reset();
Chia-I Wubb61a722016-10-24 15:40:20 +0800554 mWriter.reset();
555
556 return Void();
557}
558
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500559std::unique_ptr<ComposerClient::CommandReader>
560ComposerClient::createCommandReader()
561{
562 return std::unique_ptr<ComposerClient::CommandReader>(
563 new CommandReader(*this));
564}
565
566ComposerClient::CommandReader::CommandReader(ComposerClient& client)
Chia-I Wubb61a722016-10-24 15:40:20 +0800567 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
568{
569}
570
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500571ComposerClient::CommandReader::~CommandReader()
572{
573}
574
575Error ComposerClient::CommandReader::parse()
Chia-I Wubb61a722016-10-24 15:40:20 +0800576{
577 IComposerClient::Command command;
Chia-I Wue1768352016-12-19 12:56:54 +0800578 uint16_t length = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800579
580 while (!isEmpty()) {
Chia-I Wue1768352016-12-19 12:56:54 +0800581 if (!beginCommand(&command, &length)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800582 break;
583 }
584
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500585 bool parsed = parseCommand(command, length);
Chia-I Wubb61a722016-10-24 15:40:20 +0800586 endCommand();
587
588 if (!parsed) {
589 ALOGE("failed to parse command 0x%x, length %" PRIu16,
590 command, length);
591 break;
592 }
593 }
594
595 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
596}
597
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500598bool ComposerClient::CommandReader::parseCommand(
599 IComposerClient::Command command, uint16_t length) {
600 switch (command) {
601 case IComposerClient::Command::SELECT_DISPLAY:
602 return parseSelectDisplay(length);
603 case IComposerClient::Command::SELECT_LAYER:
604 return parseSelectLayer(length);
605 case IComposerClient::Command::SET_COLOR_TRANSFORM:
606 return parseSetColorTransform(length);
607 case IComposerClient::Command::SET_CLIENT_TARGET:
608 return parseSetClientTarget(length);
609 case IComposerClient::Command::SET_OUTPUT_BUFFER:
610 return parseSetOutputBuffer(length);
611 case IComposerClient::Command::VALIDATE_DISPLAY:
612 return parseValidateDisplay(length);
613 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
614 return parseAcceptDisplayChanges(length);
615 case IComposerClient::Command::PRESENT_DISPLAY:
616 return parsePresentDisplay(length);
617 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
618 return parseSetLayerCursorPosition(length);
619 case IComposerClient::Command::SET_LAYER_BUFFER:
620 return parseSetLayerBuffer(length);
621 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
622 return parseSetLayerSurfaceDamage(length);
623 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
624 return parseSetLayerBlendMode(length);
625 case IComposerClient::Command::SET_LAYER_COLOR:
626 return parseSetLayerColor(length);
627 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
628 return parseSetLayerCompositionType(length);
629 case IComposerClient::Command::SET_LAYER_DATASPACE:
630 return parseSetLayerDataspace(length);
631 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
632 return parseSetLayerDisplayFrame(length);
633 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
634 return parseSetLayerPlaneAlpha(length);
635 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
636 return parseSetLayerSidebandStream(length);
637 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
638 return parseSetLayerSourceCrop(length);
639 case IComposerClient::Command::SET_LAYER_TRANSFORM:
640 return parseSetLayerTransform(length);
641 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
642 return parseSetLayerVisibleRegion(length);
643 case IComposerClient::Command::SET_LAYER_Z_ORDER:
644 return parseSetLayerZOrder(length);
645 default:
646 return false;
647 }
648}
649
650bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800651{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500652 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800653 return false;
654 }
655
656 mDisplay = read64();
657 mWriter.selectDisplay(mDisplay);
658
659 return true;
660}
661
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500662bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800663{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500664 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800665 return false;
666 }
667
668 mLayer = read64();
669
670 return true;
671}
672
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500673bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800674{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500675 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800676 return false;
677 }
678
679 float matrix[16];
680 for (int i = 0; i < 16; i++) {
681 matrix[i] = readFloat();
682 }
683 auto transform = readSigned();
684
685 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
686 if (err != Error::NONE) {
687 mWriter.setError(getCommandLoc(), err);
688 }
689
690 return true;
691}
692
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500693bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800694{
695 // 4 parameters followed by N rectangles
696 if ((length - 4) % 4 != 0) {
697 return false;
698 }
699
Chia-I Wue1768352016-12-19 12:56:54 +0800700 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800701 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800702 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800703 auto fence = readFence();
704 auto dataspace = readSigned();
705 auto damage = readRegion((length - 4) / 4);
706
707 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
708 slot, useCache, clientTarget);
709 if (err == Error::NONE) {
710 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
711 dataspace, damage);
712 }
713 if (err != Error::NONE) {
714 close(fence);
715 mWriter.setError(getCommandLoc(), err);
716 }
717
718 return true;
719}
720
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500721bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800722{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500723 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800724 return false;
725 }
726
Chia-I Wue1768352016-12-19 12:56:54 +0800727 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800728 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800729 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800730 auto fence = readFence();
731
732 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
733 slot, useCache, outputBuffer);
734 if (err == Error::NONE) {
735 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
736 }
737 if (err != Error::NONE) {
738 close(fence);
739 mWriter.setError(getCommandLoc(), err);
740 }
741
742 return true;
743}
744
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500745bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800746{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500747 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800748 return false;
749 }
750
751 std::vector<Layer> changedLayers;
752 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800753 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800754 std::vector<Layer> requestedLayers;
755 std::vector<uint32_t> requestMasks;
756
Chia-I Wue1768352016-12-19 12:56:54 +0800757 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
758 &compositionTypes, &displayRequestMask,
759 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800760 if (err == Error::NONE) {
761 mWriter.setChangedCompositionTypes(changedLayers,
762 compositionTypes);
763 mWriter.setDisplayRequests(displayRequestMask,
764 requestedLayers, requestMasks);
765 } else {
766 mWriter.setError(getCommandLoc(), err);
767 }
768
769 return true;
770}
771
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500772bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800773{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500774 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800775 return false;
776 }
777
778 auto err = mHal.acceptDisplayChanges(mDisplay);
779 if (err != Error::NONE) {
780 mWriter.setError(getCommandLoc(), err);
781 }
782
783 return true;
784}
785
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500786bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800787{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500788 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800789 return false;
790 }
791
Chia-I Wue1768352016-12-19 12:56:54 +0800792 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800793 std::vector<Layer> layers;
794 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800795 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800796 if (err == Error::NONE) {
797 mWriter.setPresentFence(presentFence);
798 mWriter.setReleaseFences(layers, fences);
799 } else {
800 mWriter.setError(getCommandLoc(), err);
801 }
802
803 return true;
804}
805
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500806bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800807{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500808 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800809 return false;
810 }
811
812 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
813 readSigned(), readSigned());
814 if (err != Error::NONE) {
815 mWriter.setError(getCommandLoc(), err);
816 }
817
818 return true;
819}
820
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500821bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800822{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500823 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800824 return false;
825 }
826
Chia-I Wue1768352016-12-19 12:56:54 +0800827 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800828 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800829 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800830 auto fence = readFence();
831
832 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
833 slot, useCache, buffer);
834 if (err == Error::NONE) {
835 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
836 }
837 if (err != Error::NONE) {
838 close(fence);
839 mWriter.setError(getCommandLoc(), err);
840 }
841
842 return true;
843}
844
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500845bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800846{
847 // N rectangles
848 if (length % 4 != 0) {
849 return false;
850 }
851
852 auto damage = readRegion(length / 4);
853 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
854 if (err != Error::NONE) {
855 mWriter.setError(getCommandLoc(), err);
856 }
857
858 return true;
859}
860
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500861bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800862{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500863 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800864 return false;
865 }
866
867 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
868 if (err != Error::NONE) {
869 mWriter.setError(getCommandLoc(), err);
870 }
871
872 return true;
873}
874
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500875bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800876{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500877 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800878 return false;
879 }
880
881 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
882 if (err != Error::NONE) {
883 mWriter.setError(getCommandLoc(), err);
884 }
885
886 return true;
887}
888
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500889bool ComposerClient::CommandReader::parseSetLayerCompositionType(
890 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800891{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500892 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800893 return false;
894 }
895
896 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
897 if (err != Error::NONE) {
898 mWriter.setError(getCommandLoc(), err);
899 }
900
901 return true;
902}
903
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500904bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800905{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500906 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800907 return false;
908 }
909
910 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
911 if (err != Error::NONE) {
912 mWriter.setError(getCommandLoc(), err);
913 }
914
915 return true;
916}
917
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500918bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800919{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500920 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800921 return false;
922 }
923
924 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
925 if (err != Error::NONE) {
926 mWriter.setError(getCommandLoc(), err);
927 }
928
929 return true;
930}
931
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500932bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800933{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500934 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800935 return false;
936 }
937
Dan Stoza0df10c42016-12-19 15:22:47 -0800938 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800939 if (err != Error::NONE) {
940 mWriter.setError(getCommandLoc(), err);
941 }
942
943 return true;
944}
945
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500946bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800947{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500948 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800949 return false;
950 }
951
952 auto stream = readHandle();
953
954 auto err = lookupLayerSidebandStream(stream);
955 if (err == Error::NONE) {
956 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
957 }
958 if (err != Error::NONE) {
959 mWriter.setError(getCommandLoc(), err);
960 }
961
962 return true;
963}
964
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500965bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800966{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500967 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800968 return false;
969 }
970
971 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
972 if (err != Error::NONE) {
973 mWriter.setError(getCommandLoc(), err);
974 }
975
976 return true;
977}
978
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500979bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800980{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500981 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800982 return false;
983 }
984
985 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
986 if (err != Error::NONE) {
987 mWriter.setError(getCommandLoc(), err);
988 }
989
990 return true;
991}
992
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500993bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800994{
995 // N rectangles
996 if (length % 4 != 0) {
997 return false;
998 }
999
1000 auto region = readRegion(length / 4);
1001 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1002 if (err != Error::NONE) {
1003 mWriter.setError(getCommandLoc(), err);
1004 }
1005
1006 return true;
1007}
1008
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001009bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001010{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001011 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001012 return false;
1013 }
1014
1015 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1016 if (err != Error::NONE) {
1017 mWriter.setError(getCommandLoc(), err);
1018 }
1019
1020 return true;
1021}
1022
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001023hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001024{
1025 return hwc_rect_t{
1026 readSigned(),
1027 readSigned(),
1028 readSigned(),
1029 readSigned(),
1030 };
1031}
1032
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001033std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001034{
1035 std::vector<hwc_rect_t> region;
1036 region.reserve(count);
1037 while (count > 0) {
1038 region.emplace_back(readRect());
1039 count--;
1040 }
1041
1042 return region;
1043}
1044
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001045hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001046{
1047 return hwc_frect_t{
1048 readFloat(),
1049 readFloat(),
1050 readFloat(),
1051 readFloat(),
1052 };
1053}
1054
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001055Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1056 uint32_t slot, bool useCache, buffer_handle_t& handle)
Chia-I Wubb61a722016-10-24 15:40:20 +08001057{
1058 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1059
1060 auto dpy = mClient.mDisplayData.find(mDisplay);
1061 if (dpy == mClient.mDisplayData.end()) {
1062 return Error::BAD_DISPLAY;
1063 }
1064
1065 BufferClone* clone = nullptr;
1066 switch (cache) {
1067 case BufferCache::CLIENT_TARGETS:
1068 if (slot < dpy->second.ClientTargets.size()) {
1069 clone = &dpy->second.ClientTargets[slot];
1070 }
1071 break;
1072 case BufferCache::OUTPUT_BUFFERS:
1073 if (slot < dpy->second.OutputBuffers.size()) {
1074 clone = &dpy->second.OutputBuffers[slot];
1075 }
1076 break;
1077 case BufferCache::LAYER_BUFFERS:
1078 {
1079 auto ly = dpy->second.Layers.find(mLayer);
1080 if (ly == dpy->second.Layers.end()) {
1081 return Error::BAD_LAYER;
1082 }
1083 if (slot < ly->second.Buffers.size()) {
1084 clone = &ly->second.Buffers[slot];
1085 }
1086 }
1087 break;
1088 case BufferCache::LAYER_SIDEBAND_STREAMS:
1089 {
1090 auto ly = dpy->second.Layers.find(mLayer);
1091 if (ly == dpy->second.Layers.end()) {
1092 return Error::BAD_LAYER;
1093 }
1094 if (slot == 0) {
1095 clone = &ly->second.SidebandStream;
1096 }
1097 }
1098 break;
1099 default:
1100 break;
1101 }
1102
1103 if (!clone) {
1104 ALOGW("invalid buffer slot");
1105 return Error::BAD_PARAMETER;
1106 }
1107
1108 // use or update cache
1109 if (useCache) {
1110 handle = *clone;
1111 } else {
1112 if (!sHandleImporter.importBuffer(handle)) {
1113 return Error::NO_RESOURCES;
1114 }
1115
1116 *clone = handle;
1117 }
1118
1119 return Error::NONE;
1120}
1121
1122} // namespace implementation
1123} // namespace V2_1
1124} // namespace composer
1125} // namespace graphics
1126} // namespace hardware
1127} // namespace android