blob: 7a2cb253e6e15b5b7222ca7087e574d5100e7b7c [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.
Chia-I Wubb61a722016-10-24 15:40:20 +0800102 bool openGralloc()
103 {
Chia-I Wue1768352016-12-19 12:56:54 +0800104 const hw_module_t* module = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +0800105 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
106 if (err) {
107 ALOGE("failed to get gralloc module");
108 return false;
109 }
110
111 uint8_t major = (module->module_api_version >> 8) & 0xff;
112 if (major > 1) {
113 ALOGE("unknown gralloc module major version %d", major);
114 return false;
115 }
116
117 if (major == 1) {
118 err = gralloc1_open(module, &mDevice);
119 if (err) {
120 ALOGE("failed to open gralloc1 device");
121 return false;
122 }
123
124 mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
125 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
126 mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
127 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
128 if (!mRetain || !mRelease) {
129 ALOGE("invalid gralloc1 device");
130 gralloc1_close(mDevice);
131 return false;
132 }
133 } else {
134 mModule = reinterpret_cast<const gralloc_module_t*>(module);
135 }
136
137 return true;
138 }
139
140 void closeGralloc()
141 {
142 if (mDevice) {
143 gralloc1_close(mDevice);
144 }
145 }
146
147 buffer_handle_t cloneBuffer(buffer_handle_t handle)
148 {
149 native_handle_t* clone = native_handle_clone(handle);
150 if (!clone) {
151 ALOGE("failed to clone buffer %p", handle);
152 return nullptr;
153 }
154
155 bool err;
156 if (mDevice) {
157 err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
158 } else {
159 err = (mModule->registerBuffer(mModule, clone) != 0);
160 }
161
162 if (err) {
163 ALOGE("failed to retain/register buffer %p", clone);
164 native_handle_close(clone);
165 native_handle_delete(clone);
166 return nullptr;
167 }
168
169 return clone;
170 }
171
172 void releaseBuffer(buffer_handle_t handle)
173 {
174 if (mDevice) {
175 mRelease(mDevice, handle);
176 } else {
177 mModule->unregisterBuffer(mModule, handle);
Chia-I Wubb61a722016-10-24 15:40:20 +0800178 }
Chia-I Wu939e4012016-12-12 21:51:33 +0800179 native_handle_close(handle);
180 native_handle_delete(const_cast<native_handle_t*>(handle));
Chia-I Wubb61a722016-10-24 15:40:20 +0800181 }
182
183 // gralloc1
184 gralloc1_device_t* mDevice;
185 GRALLOC1_PFN_RETAIN mRetain;
186 GRALLOC1_PFN_RELEASE mRelease;
187
188 // gralloc0
189 const gralloc_module_t* mModule;
Chia-I Wubb61a722016-10-24 15:40:20 +0800190};
191
192HandleImporter sHandleImporter;
193
194} // anonymous namespace
195
196BufferClone::BufferClone()
197 : mHandle(nullptr)
198{
199}
200
201BufferClone::BufferClone(BufferClone&& other)
202{
203 mHandle = other.mHandle;
204 other.mHandle = nullptr;
205}
206
207BufferClone& BufferClone::operator=(buffer_handle_t handle)
208{
209 clear();
210 mHandle = handle;
211 return *this;
212}
213
214BufferClone::~BufferClone()
215{
216 clear();
217}
218
219void BufferClone::clear()
220{
221 if (mHandle) {
222 sHandleImporter.freeBuffer(mHandle);
223 }
224}
225
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500226ComposerClient::ComposerClient(ComposerBase& hal)
227 : mHal(hal), mWriter(kWriterInitialSize)
Chia-I Wubb61a722016-10-24 15:40:20 +0800228{
Chia-I Wubb61a722016-10-24 15:40:20 +0800229}
230
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500231ComposerClient::~ComposerClient()
Chia-I Wubb61a722016-10-24 15:40:20 +0800232{
233 mHal.enableCallback(false);
234 mHal.removeClient();
235
236 // no need to grab the mutex as any in-flight hwbinder call should keep
237 // the client alive
238 for (const auto& dpy : mDisplayData) {
239 if (!dpy.second.Layers.empty()) {
240 ALOGW("client destroyed with valid layers");
241 }
242 for (const auto& ly : dpy.second.Layers) {
243 mHal.destroyLayer(dpy.first, ly.first);
244 }
245
246 if (dpy.second.IsVirtual) {
247 ALOGW("client destroyed with valid virtual display");
248 mHal.destroyVirtualDisplay(dpy.first);
249 }
250 }
251
252 mDisplayData.clear();
253
254 sHandleImporter.cleanup();
255}
256
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500257void ComposerClient::initialize()
258{
259 mReader = createCommandReader();
260 if (!sHandleImporter.initialize()) {
261 LOG_ALWAYS_FATAL("failed to initialize handle importer");
262 }
263}
264
265void ComposerClient::onHotplug(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800266 IComposerCallback::Connection connected)
267{
268 {
269 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
270
271 if (connected == IComposerCallback::Connection::CONNECTED) {
272 mDisplayData.emplace(display, DisplayData(false));
273 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
274 mDisplayData.erase(display);
275 }
276 }
277
278 mCallback->onHotplug(display, connected);
279}
280
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500281void ComposerClient::onRefresh(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800282{
283 mCallback->onRefresh(display);
284}
285
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500286void ComposerClient::onVsync(Display display, int64_t timestamp)
Chia-I Wubb61a722016-10-24 15:40:20 +0800287{
288 mCallback->onVsync(display, timestamp);
289}
290
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500291Return<void> ComposerClient::registerCallback(
292 const sp<IComposerCallback>& callback)
Chia-I Wubb61a722016-10-24 15:40:20 +0800293{
294 // no locking as we require this function to be called only once
295 mCallback = callback;
296 mHal.enableCallback(callback != nullptr);
297
298 return Void();
299}
300
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500301Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
Chia-I Wubb61a722016-10-24 15:40:20 +0800302{
303 return mHal.getMaxVirtualDisplayCount();
304}
305
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500306Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
307 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
Chia-I Wubb61a722016-10-24 15:40:20 +0800308 createVirtualDisplay_cb hidl_cb)
309{
Chia-I Wue1768352016-12-19 12:56:54 +0800310 Display display = 0;
311 Error err = mHal.createVirtualDisplay(width, height,
312 &formatHint, &display);
Chia-I Wubb61a722016-10-24 15:40:20 +0800313 if (err == Error::NONE) {
314 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
315
316 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
317 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
318 }
319
320 hidl_cb(err, display, formatHint);
321 return Void();
322}
323
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500324Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800325{
326 Error err = mHal.destroyVirtualDisplay(display);
327 if (err == Error::NONE) {
328 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
329
330 mDisplayData.erase(display);
331 }
332
333 return err;
334}
335
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500336Return<void> ComposerClient::createLayer(Display display,
337 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800338{
Chia-I Wue1768352016-12-19 12:56:54 +0800339 Layer layer = 0;
340 Error err = mHal.createLayer(display, &layer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800341 if (err == Error::NONE) {
342 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
343
344 auto dpy = mDisplayData.find(display);
345 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
346 ly->second.Buffers.resize(bufferSlotCount);
347 }
348
349 hidl_cb(err, layer);
350 return Void();
351}
352
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500353Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
Chia-I Wubb61a722016-10-24 15:40:20 +0800354{
355 Error err = mHal.destroyLayer(display, layer);
356 if (err == Error::NONE) {
357 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
358
359 auto dpy = mDisplayData.find(display);
360 dpy->second.Layers.erase(layer);
361 }
362
363 return err;
364}
365
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500366Return<void> ComposerClient::getActiveConfig(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800367 getActiveConfig_cb hidl_cb)
368{
Chia-I Wue1768352016-12-19 12:56:54 +0800369 Config config = 0;
370 Error err = mHal.getActiveConfig(display, &config);
Chia-I Wubb61a722016-10-24 15:40:20 +0800371
372 hidl_cb(err, config);
373 return Void();
374}
375
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500376Return<Error> ComposerClient::getClientTargetSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800377 uint32_t width, uint32_t height,
378 PixelFormat format, Dataspace dataspace)
379{
380 Error err = mHal.getClientTargetSupport(display,
381 width, height, format, dataspace);
382 return err;
383}
384
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500385Return<void> ComposerClient::getColorModes(Display display,
386 getColorModes_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800387{
388 hidl_vec<ColorMode> modes;
Chia-I Wue1768352016-12-19 12:56:54 +0800389 Error err = mHal.getColorModes(display, &modes);
Chia-I Wubb61a722016-10-24 15:40:20 +0800390
391 hidl_cb(err, modes);
392 return Void();
393}
394
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500395Return<void> ComposerClient::getDisplayAttribute(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800396 Config config, Attribute attribute,
397 getDisplayAttribute_cb hidl_cb)
398{
Chia-I Wue1768352016-12-19 12:56:54 +0800399 int32_t value = 0;
400 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
Chia-I Wubb61a722016-10-24 15:40:20 +0800401
402 hidl_cb(err, value);
403 return Void();
404}
405
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500406Return<void> ComposerClient::getDisplayConfigs(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800407 getDisplayConfigs_cb hidl_cb)
408{
409 hidl_vec<Config> configs;
Chia-I Wue1768352016-12-19 12:56:54 +0800410 Error err = mHal.getDisplayConfigs(display, &configs);
Chia-I Wubb61a722016-10-24 15:40:20 +0800411
412 hidl_cb(err, configs);
413 return Void();
414}
415
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500416Return<void> ComposerClient::getDisplayName(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800417 getDisplayName_cb hidl_cb)
418{
419 hidl_string name;
Chia-I Wue1768352016-12-19 12:56:54 +0800420 Error err = mHal.getDisplayName(display, &name);
Chia-I Wubb61a722016-10-24 15:40:20 +0800421
422 hidl_cb(err, name);
423 return Void();
424}
425
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500426Return<void> ComposerClient::getDisplayType(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800427 getDisplayType_cb hidl_cb)
428{
Chia-I Wue1768352016-12-19 12:56:54 +0800429 DisplayType type = DisplayType::INVALID;
430 Error err = mHal.getDisplayType(display, &type);
Chia-I Wubb61a722016-10-24 15:40:20 +0800431
432 hidl_cb(err, type);
433 return Void();
434}
435
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500436Return<void> ComposerClient::getDozeSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800437 getDozeSupport_cb hidl_cb)
438{
Chia-I Wue1768352016-12-19 12:56:54 +0800439 bool support = false;
440 Error err = mHal.getDozeSupport(display, &support);
Chia-I Wubb61a722016-10-24 15:40:20 +0800441
442 hidl_cb(err, support);
443 return Void();
444}
445
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500446Return<void> ComposerClient::getHdrCapabilities(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800447 getHdrCapabilities_cb hidl_cb)
448{
449 hidl_vec<Hdr> types;
450 float max_lumi = 0.0f;
451 float max_avg_lumi = 0.0f;
452 float min_lumi = 0.0f;
Chia-I Wue1768352016-12-19 12:56:54 +0800453 Error err = mHal.getHdrCapabilities(display, &types,
454 &max_lumi, &max_avg_lumi, &min_lumi);
Chia-I Wubb61a722016-10-24 15:40:20 +0800455
456 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
457 return Void();
458}
459
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500460Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800461 uint32_t clientTargetSlotCount)
462{
463 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
464
465 auto dpy = mDisplayData.find(display);
466 if (dpy == mDisplayData.end()) {
467 return Error::BAD_DISPLAY;
468 }
469
470 dpy->second.ClientTargets.resize(clientTargetSlotCount);
471
472 return Error::NONE;
473}
474
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500475Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
Chia-I Wubb61a722016-10-24 15:40:20 +0800476{
477 Error err = mHal.setActiveConfig(display, config);
478 return err;
479}
480
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500481Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800482{
483 Error err = mHal.setColorMode(display, mode);
484 return err;
485}
486
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500487Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800488{
489 Error err = mHal.setPowerMode(display, mode);
490 return err;
491}
492
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500493Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
Chia-I Wubb61a722016-10-24 15:40:20 +0800494{
495 Error err = mHal.setVsyncEnabled(display, enabled);
496 return err;
497}
498
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500499Return<Error> ComposerClient::setInputCommandQueue(
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800500 const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800501{
502 std::lock_guard<std::mutex> lock(mCommandMutex);
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500503 return mReader->setMQDescriptor(descriptor) ?
Chia-I Wubb61a722016-10-24 15:40:20 +0800504 Error::NONE : Error::NO_RESOURCES;
505}
506
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500507Return<void> ComposerClient::getOutputCommandQueue(
Chia-I Wubb61a722016-10-24 15:40:20 +0800508 getOutputCommandQueue_cb hidl_cb)
509{
510 // no locking as we require this function to be called inside
511 // executeCommands_cb
512
513 auto outDescriptor = mWriter.getMQDescriptor();
514 if (outDescriptor) {
515 hidl_cb(Error::NONE, *outDescriptor);
516 } else {
Hridya Valsaraju790db102017-01-10 08:58:23 -0800517 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
Chia-I Wubb61a722016-10-24 15:40:20 +0800518 }
519
520 return Void();
521}
522
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500523Return<void> ComposerClient::executeCommands(uint32_t inLength,
Chia-I Wubb61a722016-10-24 15:40:20 +0800524 const hidl_vec<hidl_handle>& inHandles,
525 executeCommands_cb hidl_cb)
526{
527 std::lock_guard<std::mutex> lock(mCommandMutex);
528
529 bool outChanged = false;
530 uint32_t outLength = 0;
531 hidl_vec<hidl_handle> outHandles;
532
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500533 if (!mReader->readQueue(inLength, inHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800534 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
535 return Void();
536 }
537
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500538 Error err = mReader->parse();
Chia-I Wubb61a722016-10-24 15:40:20 +0800539 if (err == Error::NONE &&
Chia-I Wue1768352016-12-19 12:56:54 +0800540 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800541 err = Error::NO_RESOURCES;
542 }
543
544 hidl_cb(err, outChanged, outLength, outHandles);
545
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500546 mReader->reset();
Chia-I Wubb61a722016-10-24 15:40:20 +0800547 mWriter.reset();
548
549 return Void();
550}
551
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500552std::unique_ptr<ComposerClient::CommandReader>
553ComposerClient::createCommandReader()
554{
555 return std::unique_ptr<ComposerClient::CommandReader>(
556 new CommandReader(*this));
557}
558
559ComposerClient::CommandReader::CommandReader(ComposerClient& client)
Chia-I Wubb61a722016-10-24 15:40:20 +0800560 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
561{
562}
563
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500564ComposerClient::CommandReader::~CommandReader()
565{
566}
567
568Error ComposerClient::CommandReader::parse()
Chia-I Wubb61a722016-10-24 15:40:20 +0800569{
570 IComposerClient::Command command;
Chia-I Wue1768352016-12-19 12:56:54 +0800571 uint16_t length = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800572
573 while (!isEmpty()) {
Chia-I Wue1768352016-12-19 12:56:54 +0800574 if (!beginCommand(&command, &length)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800575 break;
576 }
577
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500578 bool parsed = parseCommand(command, length);
Chia-I Wubb61a722016-10-24 15:40:20 +0800579 endCommand();
580
581 if (!parsed) {
582 ALOGE("failed to parse command 0x%x, length %" PRIu16,
583 command, length);
584 break;
585 }
586 }
587
588 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
589}
590
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500591bool ComposerClient::CommandReader::parseCommand(
592 IComposerClient::Command command, uint16_t length) {
593 switch (command) {
594 case IComposerClient::Command::SELECT_DISPLAY:
595 return parseSelectDisplay(length);
596 case IComposerClient::Command::SELECT_LAYER:
597 return parseSelectLayer(length);
598 case IComposerClient::Command::SET_COLOR_TRANSFORM:
599 return parseSetColorTransform(length);
600 case IComposerClient::Command::SET_CLIENT_TARGET:
601 return parseSetClientTarget(length);
602 case IComposerClient::Command::SET_OUTPUT_BUFFER:
603 return parseSetOutputBuffer(length);
604 case IComposerClient::Command::VALIDATE_DISPLAY:
605 return parseValidateDisplay(length);
606 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
607 return parseAcceptDisplayChanges(length);
608 case IComposerClient::Command::PRESENT_DISPLAY:
609 return parsePresentDisplay(length);
610 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
611 return parseSetLayerCursorPosition(length);
612 case IComposerClient::Command::SET_LAYER_BUFFER:
613 return parseSetLayerBuffer(length);
614 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
615 return parseSetLayerSurfaceDamage(length);
616 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
617 return parseSetLayerBlendMode(length);
618 case IComposerClient::Command::SET_LAYER_COLOR:
619 return parseSetLayerColor(length);
620 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
621 return parseSetLayerCompositionType(length);
622 case IComposerClient::Command::SET_LAYER_DATASPACE:
623 return parseSetLayerDataspace(length);
624 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
625 return parseSetLayerDisplayFrame(length);
626 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
627 return parseSetLayerPlaneAlpha(length);
628 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
629 return parseSetLayerSidebandStream(length);
630 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
631 return parseSetLayerSourceCrop(length);
632 case IComposerClient::Command::SET_LAYER_TRANSFORM:
633 return parseSetLayerTransform(length);
634 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
635 return parseSetLayerVisibleRegion(length);
636 case IComposerClient::Command::SET_LAYER_Z_ORDER:
637 return parseSetLayerZOrder(length);
638 default:
639 return false;
640 }
641}
642
643bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800644{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500645 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800646 return false;
647 }
648
649 mDisplay = read64();
650 mWriter.selectDisplay(mDisplay);
651
652 return true;
653}
654
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500655bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800656{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500657 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800658 return false;
659 }
660
661 mLayer = read64();
662
663 return true;
664}
665
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500666bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800667{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500668 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800669 return false;
670 }
671
672 float matrix[16];
673 for (int i = 0; i < 16; i++) {
674 matrix[i] = readFloat();
675 }
676 auto transform = readSigned();
677
678 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
679 if (err != Error::NONE) {
680 mWriter.setError(getCommandLoc(), err);
681 }
682
683 return true;
684}
685
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500686bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800687{
688 // 4 parameters followed by N rectangles
689 if ((length - 4) % 4 != 0) {
690 return false;
691 }
692
Chia-I Wue1768352016-12-19 12:56:54 +0800693 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800694 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800695 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800696 auto fence = readFence();
697 auto dataspace = readSigned();
698 auto damage = readRegion((length - 4) / 4);
699
700 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
701 slot, useCache, clientTarget);
702 if (err == Error::NONE) {
703 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
704 dataspace, damage);
705 }
706 if (err != Error::NONE) {
707 close(fence);
708 mWriter.setError(getCommandLoc(), err);
709 }
710
711 return true;
712}
713
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500714bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800715{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500716 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800717 return false;
718 }
719
Chia-I Wue1768352016-12-19 12:56:54 +0800720 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800721 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800722 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800723 auto fence = readFence();
724
725 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
726 slot, useCache, outputBuffer);
727 if (err == Error::NONE) {
728 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
729 }
730 if (err != Error::NONE) {
731 close(fence);
732 mWriter.setError(getCommandLoc(), err);
733 }
734
735 return true;
736}
737
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500738bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800739{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500740 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800741 return false;
742 }
743
744 std::vector<Layer> changedLayers;
745 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800746 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800747 std::vector<Layer> requestedLayers;
748 std::vector<uint32_t> requestMasks;
749
Chia-I Wue1768352016-12-19 12:56:54 +0800750 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
751 &compositionTypes, &displayRequestMask,
752 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800753 if (err == Error::NONE) {
754 mWriter.setChangedCompositionTypes(changedLayers,
755 compositionTypes);
756 mWriter.setDisplayRequests(displayRequestMask,
757 requestedLayers, requestMasks);
758 } else {
759 mWriter.setError(getCommandLoc(), err);
760 }
761
762 return true;
763}
764
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500765bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800766{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500767 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800768 return false;
769 }
770
771 auto err = mHal.acceptDisplayChanges(mDisplay);
772 if (err != Error::NONE) {
773 mWriter.setError(getCommandLoc(), err);
774 }
775
776 return true;
777}
778
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500779bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800780{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500781 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800782 return false;
783 }
784
Chia-I Wue1768352016-12-19 12:56:54 +0800785 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800786 std::vector<Layer> layers;
787 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800788 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800789 if (err == Error::NONE) {
790 mWriter.setPresentFence(presentFence);
791 mWriter.setReleaseFences(layers, fences);
792 } else {
793 mWriter.setError(getCommandLoc(), err);
794 }
795
796 return true;
797}
798
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500799bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800800{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500801 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800802 return false;
803 }
804
805 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
806 readSigned(), readSigned());
807 if (err != Error::NONE) {
808 mWriter.setError(getCommandLoc(), err);
809 }
810
811 return true;
812}
813
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500814bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800815{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500816 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800817 return false;
818 }
819
Chia-I Wue1768352016-12-19 12:56:54 +0800820 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800821 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800822 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800823 auto fence = readFence();
824
825 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
826 slot, useCache, buffer);
827 if (err == Error::NONE) {
828 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
829 }
830 if (err != Error::NONE) {
831 close(fence);
832 mWriter.setError(getCommandLoc(), err);
833 }
834
835 return true;
836}
837
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500838bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800839{
840 // N rectangles
841 if (length % 4 != 0) {
842 return false;
843 }
844
845 auto damage = readRegion(length / 4);
846 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
847 if (err != Error::NONE) {
848 mWriter.setError(getCommandLoc(), err);
849 }
850
851 return true;
852}
853
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500854bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800855{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500856 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800857 return false;
858 }
859
860 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
861 if (err != Error::NONE) {
862 mWriter.setError(getCommandLoc(), err);
863 }
864
865 return true;
866}
867
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500868bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800869{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500870 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800871 return false;
872 }
873
874 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
875 if (err != Error::NONE) {
876 mWriter.setError(getCommandLoc(), err);
877 }
878
879 return true;
880}
881
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500882bool ComposerClient::CommandReader::parseSetLayerCompositionType(
883 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800884{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500885 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800886 return false;
887 }
888
889 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
890 if (err != Error::NONE) {
891 mWriter.setError(getCommandLoc(), err);
892 }
893
894 return true;
895}
896
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500897bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800898{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500899 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800900 return false;
901 }
902
903 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
904 if (err != Error::NONE) {
905 mWriter.setError(getCommandLoc(), err);
906 }
907
908 return true;
909}
910
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500911bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800912{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500913 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800914 return false;
915 }
916
917 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
918 if (err != Error::NONE) {
919 mWriter.setError(getCommandLoc(), err);
920 }
921
922 return true;
923}
924
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500925bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800926{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500927 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800928 return false;
929 }
930
Dan Stoza0df10c42016-12-19 15:22:47 -0800931 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800932 if (err != Error::NONE) {
933 mWriter.setError(getCommandLoc(), err);
934 }
935
936 return true;
937}
938
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500939bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800940{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500941 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800942 return false;
943 }
944
945 auto stream = readHandle();
946
947 auto err = lookupLayerSidebandStream(stream);
948 if (err == Error::NONE) {
949 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
950 }
951 if (err != Error::NONE) {
952 mWriter.setError(getCommandLoc(), err);
953 }
954
955 return true;
956}
957
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500958bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800959{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500960 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800961 return false;
962 }
963
964 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
965 if (err != Error::NONE) {
966 mWriter.setError(getCommandLoc(), err);
967 }
968
969 return true;
970}
971
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500972bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800973{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500974 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800975 return false;
976 }
977
978 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
979 if (err != Error::NONE) {
980 mWriter.setError(getCommandLoc(), err);
981 }
982
983 return true;
984}
985
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500986bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800987{
988 // N rectangles
989 if (length % 4 != 0) {
990 return false;
991 }
992
993 auto region = readRegion(length / 4);
994 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
995 if (err != Error::NONE) {
996 mWriter.setError(getCommandLoc(), err);
997 }
998
999 return true;
1000}
1001
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001002bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001003{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001004 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001005 return false;
1006 }
1007
1008 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1009 if (err != Error::NONE) {
1010 mWriter.setError(getCommandLoc(), err);
1011 }
1012
1013 return true;
1014}
1015
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001016hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001017{
1018 return hwc_rect_t{
1019 readSigned(),
1020 readSigned(),
1021 readSigned(),
1022 readSigned(),
1023 };
1024}
1025
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001026std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001027{
1028 std::vector<hwc_rect_t> region;
1029 region.reserve(count);
1030 while (count > 0) {
1031 region.emplace_back(readRect());
1032 count--;
1033 }
1034
1035 return region;
1036}
1037
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001038hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001039{
1040 return hwc_frect_t{
1041 readFloat(),
1042 readFloat(),
1043 readFloat(),
1044 readFloat(),
1045 };
1046}
1047
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001048Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1049 uint32_t slot, bool useCache, buffer_handle_t& handle)
Chia-I Wubb61a722016-10-24 15:40:20 +08001050{
1051 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1052
1053 auto dpy = mClient.mDisplayData.find(mDisplay);
1054 if (dpy == mClient.mDisplayData.end()) {
1055 return Error::BAD_DISPLAY;
1056 }
1057
1058 BufferClone* clone = nullptr;
1059 switch (cache) {
1060 case BufferCache::CLIENT_TARGETS:
1061 if (slot < dpy->second.ClientTargets.size()) {
1062 clone = &dpy->second.ClientTargets[slot];
1063 }
1064 break;
1065 case BufferCache::OUTPUT_BUFFERS:
1066 if (slot < dpy->second.OutputBuffers.size()) {
1067 clone = &dpy->second.OutputBuffers[slot];
1068 }
1069 break;
1070 case BufferCache::LAYER_BUFFERS:
1071 {
1072 auto ly = dpy->second.Layers.find(mLayer);
1073 if (ly == dpy->second.Layers.end()) {
1074 return Error::BAD_LAYER;
1075 }
1076 if (slot < ly->second.Buffers.size()) {
1077 clone = &ly->second.Buffers[slot];
1078 }
1079 }
1080 break;
1081 case BufferCache::LAYER_SIDEBAND_STREAMS:
1082 {
1083 auto ly = dpy->second.Layers.find(mLayer);
1084 if (ly == dpy->second.Layers.end()) {
1085 return Error::BAD_LAYER;
1086 }
1087 if (slot == 0) {
1088 clone = &ly->second.SidebandStream;
1089 }
1090 }
1091 break;
1092 default:
1093 break;
1094 }
1095
1096 if (!clone) {
1097 ALOGW("invalid buffer slot");
1098 return Error::BAD_PARAMETER;
1099 }
1100
1101 // use or update cache
1102 if (useCache) {
1103 handle = *clone;
1104 } else {
1105 if (!sHandleImporter.importBuffer(handle)) {
1106 return Error::NO_RESOURCES;
1107 }
1108
1109 *clone = handle;
1110 }
1111
1112 return Error::NONE;
1113}
1114
1115} // namespace implementation
1116} // namespace V2_1
1117} // namespace composer
1118} // namespace graphics
1119} // namespace hardware
1120} // namespace android