blob: edd161a8d789e9ee28e28f2644e058d05dca6f78 [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
23#include "Hwc.h"
24#include "HwcClient.h"
25#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
233HwcClient::HwcClient(HwcHal& hal)
234 : mHal(hal), mReader(*this), mWriter(kWriterInitialSize)
235{
236 if (!sHandleImporter.initialize()) {
237 LOG_ALWAYS_FATAL("failed to initialize handle importer");
238 }
239}
240
241HwcClient::~HwcClient()
242{
243 mHal.enableCallback(false);
244 mHal.removeClient();
245
246 // no need to grab the mutex as any in-flight hwbinder call should keep
247 // the client alive
248 for (const auto& dpy : mDisplayData) {
249 if (!dpy.second.Layers.empty()) {
250 ALOGW("client destroyed with valid layers");
251 }
252 for (const auto& ly : dpy.second.Layers) {
253 mHal.destroyLayer(dpy.first, ly.first);
254 }
255
256 if (dpy.second.IsVirtual) {
257 ALOGW("client destroyed with valid virtual display");
258 mHal.destroyVirtualDisplay(dpy.first);
259 }
260 }
261
262 mDisplayData.clear();
263
264 sHandleImporter.cleanup();
265}
266
267void HwcClient::onHotplug(Display display,
268 IComposerCallback::Connection connected)
269{
270 {
271 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
272
273 if (connected == IComposerCallback::Connection::CONNECTED) {
274 mDisplayData.emplace(display, DisplayData(false));
275 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
276 mDisplayData.erase(display);
277 }
278 }
279
280 mCallback->onHotplug(display, connected);
281}
282
283void HwcClient::onRefresh(Display display)
284{
285 mCallback->onRefresh(display);
286}
287
288void HwcClient::onVsync(Display display, int64_t timestamp)
289{
290 mCallback->onVsync(display, timestamp);
291}
292
293Return<void> HwcClient::registerCallback(const sp<IComposerCallback>& callback)
294{
295 // no locking as we require this function to be called only once
296 mCallback = callback;
297 mHal.enableCallback(callback != nullptr);
298
299 return Void();
300}
301
302Return<uint32_t> HwcClient::getMaxVirtualDisplayCount()
303{
304 return mHal.getMaxVirtualDisplayCount();
305}
306
307Return<void> HwcClient::createVirtualDisplay(uint32_t width, uint32_t height,
308 PixelFormat formatHint, uint32_t outputBufferSlotCount,
309 createVirtualDisplay_cb hidl_cb)
310{
Chia-I Wue1768352016-12-19 12:56:54 +0800311 Display display = 0;
312 Error err = mHal.createVirtualDisplay(width, height,
313 &formatHint, &display);
Chia-I Wubb61a722016-10-24 15:40:20 +0800314 if (err == Error::NONE) {
315 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
316
317 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
318 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
319 }
320
321 hidl_cb(err, display, formatHint);
322 return Void();
323}
324
325Return<Error> HwcClient::destroyVirtualDisplay(Display display)
326{
327 Error err = mHal.destroyVirtualDisplay(display);
328 if (err == Error::NONE) {
329 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
330
331 mDisplayData.erase(display);
332 }
333
334 return err;
335}
336
337Return<void> HwcClient::createLayer(Display display, uint32_t bufferSlotCount,
338 createLayer_cb hidl_cb)
339{
Chia-I Wue1768352016-12-19 12:56:54 +0800340 Layer layer = 0;
341 Error err = mHal.createLayer(display, &layer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800342 if (err == Error::NONE) {
343 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
344
345 auto dpy = mDisplayData.find(display);
346 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
347 ly->second.Buffers.resize(bufferSlotCount);
348 }
349
350 hidl_cb(err, layer);
351 return Void();
352}
353
354Return<Error> HwcClient::destroyLayer(Display display, Layer layer)
355{
356 Error err = mHal.destroyLayer(display, layer);
357 if (err == Error::NONE) {
358 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
359
360 auto dpy = mDisplayData.find(display);
361 dpy->second.Layers.erase(layer);
362 }
363
364 return err;
365}
366
367Return<void> HwcClient::getActiveConfig(Display display,
368 getActiveConfig_cb hidl_cb)
369{
Chia-I Wue1768352016-12-19 12:56:54 +0800370 Config config = 0;
371 Error err = mHal.getActiveConfig(display, &config);
Chia-I Wubb61a722016-10-24 15:40:20 +0800372
373 hidl_cb(err, config);
374 return Void();
375}
376
377Return<Error> HwcClient::getClientTargetSupport(Display display,
378 uint32_t width, uint32_t height,
379 PixelFormat format, Dataspace dataspace)
380{
381 Error err = mHal.getClientTargetSupport(display,
382 width, height, format, dataspace);
383 return err;
384}
385
386Return<void> HwcClient::getColorModes(Display display, getColorModes_cb hidl_cb)
387{
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
395Return<void> HwcClient::getDisplayAttribute(Display display,
396 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
406Return<void> HwcClient::getDisplayConfigs(Display display,
407 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
416Return<void> HwcClient::getDisplayName(Display display,
417 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
426Return<void> HwcClient::getDisplayType(Display display,
427 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
436Return<void> HwcClient::getDozeSupport(Display display,
437 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
446Return<void> HwcClient::getHdrCapabilities(Display display,
447 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
460Return<Error> HwcClient::setClientTargetSlotCount(Display display,
461 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
475Return<Error> HwcClient::setActiveConfig(Display display, Config config)
476{
477 Error err = mHal.setActiveConfig(display, config);
478 return err;
479}
480
481Return<Error> HwcClient::setColorMode(Display display, ColorMode mode)
482{
483 Error err = mHal.setColorMode(display, mode);
484 return err;
485}
486
487Return<Error> HwcClient::setPowerMode(Display display, PowerMode mode)
488{
489 Error err = mHal.setPowerMode(display, mode);
490 return err;
491}
492
493Return<Error> HwcClient::setVsyncEnabled(Display display, Vsync enabled)
494{
495 Error err = mHal.setVsyncEnabled(display, enabled);
496 return err;
497}
498
499Return<Error> HwcClient::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);
503 return mReader.setMQDescriptor(descriptor) ?
504 Error::NONE : Error::NO_RESOURCES;
505}
506
507Return<void> HwcClient::getOutputCommandQueue(
508 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
523Return<void> HwcClient::executeCommands(uint32_t inLength,
524 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
533 if (!mReader.readQueue(inLength, inHandles)) {
534 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
535 return Void();
536 }
537
538 Error err = mReader.parse();
539 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
546 mReader.reset();
547 mWriter.reset();
548
549 return Void();
550}
551
552HwcClient::CommandReader::CommandReader(HwcClient& client)
553 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
554{
555}
556
557Error HwcClient::CommandReader::parse()
558{
559 IComposerClient::Command command;
Chia-I Wue1768352016-12-19 12:56:54 +0800560 uint16_t length = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800561
562 while (!isEmpty()) {
Chia-I Wue1768352016-12-19 12:56:54 +0800563 if (!beginCommand(&command, &length)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800564 break;
565 }
566
567 bool parsed = false;
568 switch (command) {
569 case IComposerClient::Command::SELECT_DISPLAY:
570 parsed = parseSelectDisplay(length);
571 break;
572 case IComposerClient::Command::SELECT_LAYER:
573 parsed = parseSelectLayer(length);
574 break;
575 case IComposerClient::Command::SET_COLOR_TRANSFORM:
576 parsed = parseSetColorTransform(length);
577 break;
578 case IComposerClient::Command::SET_CLIENT_TARGET:
579 parsed = parseSetClientTarget(length);
580 break;
581 case IComposerClient::Command::SET_OUTPUT_BUFFER:
582 parsed = parseSetOutputBuffer(length);
583 break;
584 case IComposerClient::Command::VALIDATE_DISPLAY:
585 parsed = parseValidateDisplay(length);
586 break;
587 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
588 parsed = parseAcceptDisplayChanges(length);
589 break;
590 case IComposerClient::Command::PRESENT_DISPLAY:
591 parsed = parsePresentDisplay(length);
592 break;
593 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
594 parsed = parseSetLayerCursorPosition(length);
595 break;
596 case IComposerClient::Command::SET_LAYER_BUFFER:
597 parsed = parseSetLayerBuffer(length);
598 break;
599 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
600 parsed = parseSetLayerSurfaceDamage(length);
601 break;
602 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
603 parsed = parseSetLayerBlendMode(length);
604 break;
605 case IComposerClient::Command::SET_LAYER_COLOR:
606 parsed = parseSetLayerColor(length);
607 break;
608 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
609 parsed = parseSetLayerCompositionType(length);
610 break;
611 case IComposerClient::Command::SET_LAYER_DATASPACE:
612 parsed = parseSetLayerDataspace(length);
613 break;
614 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
615 parsed = parseSetLayerDisplayFrame(length);
616 break;
617 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
618 parsed = parseSetLayerPlaneAlpha(length);
619 break;
620 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
621 parsed = parseSetLayerSidebandStream(length);
622 break;
623 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
624 parsed = parseSetLayerSourceCrop(length);
625 break;
626 case IComposerClient::Command::SET_LAYER_TRANSFORM:
627 parsed = parseSetLayerTransform(length);
628 break;
629 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
630 parsed = parseSetLayerVisibleRegion(length);
631 break;
632 case IComposerClient::Command::SET_LAYER_Z_ORDER:
633 parsed = parseSetLayerZOrder(length);
634 break;
635 default:
636 parsed = false;
637 break;
638 }
639
640 endCommand();
641
642 if (!parsed) {
643 ALOGE("failed to parse command 0x%x, length %" PRIu16,
644 command, length);
645 break;
646 }
647 }
648
649 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
650}
651
652bool HwcClient::CommandReader::parseSelectDisplay(uint16_t length)
653{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500654 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800655 return false;
656 }
657
658 mDisplay = read64();
659 mWriter.selectDisplay(mDisplay);
660
661 return true;
662}
663
664bool HwcClient::CommandReader::parseSelectLayer(uint16_t length)
665{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500666 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800667 return false;
668 }
669
670 mLayer = read64();
671
672 return true;
673}
674
675bool HwcClient::CommandReader::parseSetColorTransform(uint16_t length)
676{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500677 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800678 return false;
679 }
680
681 float matrix[16];
682 for (int i = 0; i < 16; i++) {
683 matrix[i] = readFloat();
684 }
685 auto transform = readSigned();
686
687 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
688 if (err != Error::NONE) {
689 mWriter.setError(getCommandLoc(), err);
690 }
691
692 return true;
693}
694
695bool HwcClient::CommandReader::parseSetClientTarget(uint16_t length)
696{
697 // 4 parameters followed by N rectangles
698 if ((length - 4) % 4 != 0) {
699 return false;
700 }
701
Chia-I Wue1768352016-12-19 12:56:54 +0800702 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800703 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800704 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800705 auto fence = readFence();
706 auto dataspace = readSigned();
707 auto damage = readRegion((length - 4) / 4);
708
709 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
710 slot, useCache, clientTarget);
711 if (err == Error::NONE) {
712 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
713 dataspace, damage);
714 }
715 if (err != Error::NONE) {
716 close(fence);
717 mWriter.setError(getCommandLoc(), err);
718 }
719
720 return true;
721}
722
723bool HwcClient::CommandReader::parseSetOutputBuffer(uint16_t length)
724{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500725 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800726 return false;
727 }
728
Chia-I Wue1768352016-12-19 12:56:54 +0800729 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800730 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800731 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800732 auto fence = readFence();
733
734 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
735 slot, useCache, outputBuffer);
736 if (err == Error::NONE) {
737 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
738 }
739 if (err != Error::NONE) {
740 close(fence);
741 mWriter.setError(getCommandLoc(), err);
742 }
743
744 return true;
745}
746
747bool HwcClient::CommandReader::parseValidateDisplay(uint16_t length)
748{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500749 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800750 return false;
751 }
752
753 std::vector<Layer> changedLayers;
754 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800755 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800756 std::vector<Layer> requestedLayers;
757 std::vector<uint32_t> requestMasks;
758
Chia-I Wue1768352016-12-19 12:56:54 +0800759 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
760 &compositionTypes, &displayRequestMask,
761 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800762 if (err == Error::NONE) {
763 mWriter.setChangedCompositionTypes(changedLayers,
764 compositionTypes);
765 mWriter.setDisplayRequests(displayRequestMask,
766 requestedLayers, requestMasks);
767 } else {
768 mWriter.setError(getCommandLoc(), err);
769 }
770
771 return true;
772}
773
774bool HwcClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
775{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500776 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800777 return false;
778 }
779
780 auto err = mHal.acceptDisplayChanges(mDisplay);
781 if (err != Error::NONE) {
782 mWriter.setError(getCommandLoc(), err);
783 }
784
785 return true;
786}
787
788bool HwcClient::CommandReader::parsePresentDisplay(uint16_t length)
789{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500790 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800791 return false;
792 }
793
Chia-I Wue1768352016-12-19 12:56:54 +0800794 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800795 std::vector<Layer> layers;
796 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800797 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800798 if (err == Error::NONE) {
799 mWriter.setPresentFence(presentFence);
800 mWriter.setReleaseFences(layers, fences);
801 } else {
802 mWriter.setError(getCommandLoc(), err);
803 }
804
805 return true;
806}
807
808bool HwcClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
809{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500810 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800811 return false;
812 }
813
814 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
815 readSigned(), readSigned());
816 if (err != Error::NONE) {
817 mWriter.setError(getCommandLoc(), err);
818 }
819
820 return true;
821}
822
823bool HwcClient::CommandReader::parseSetLayerBuffer(uint16_t length)
824{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500825 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800826 return false;
827 }
828
Chia-I Wue1768352016-12-19 12:56:54 +0800829 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800830 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800831 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800832 auto fence = readFence();
833
834 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
835 slot, useCache, buffer);
836 if (err == Error::NONE) {
837 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
838 }
839 if (err != Error::NONE) {
840 close(fence);
841 mWriter.setError(getCommandLoc(), err);
842 }
843
844 return true;
845}
846
847bool HwcClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
848{
849 // N rectangles
850 if (length % 4 != 0) {
851 return false;
852 }
853
854 auto damage = readRegion(length / 4);
855 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
856 if (err != Error::NONE) {
857 mWriter.setError(getCommandLoc(), err);
858 }
859
860 return true;
861}
862
863bool HwcClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
864{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500865 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800866 return false;
867 }
868
869 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
870 if (err != Error::NONE) {
871 mWriter.setError(getCommandLoc(), err);
872 }
873
874 return true;
875}
876
877bool HwcClient::CommandReader::parseSetLayerColor(uint16_t length)
878{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500879 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800880 return false;
881 }
882
883 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
884 if (err != Error::NONE) {
885 mWriter.setError(getCommandLoc(), err);
886 }
887
888 return true;
889}
890
891bool HwcClient::CommandReader::parseSetLayerCompositionType(uint16_t length)
892{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500893 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800894 return false;
895 }
896
897 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
898 if (err != Error::NONE) {
899 mWriter.setError(getCommandLoc(), err);
900 }
901
902 return true;
903}
904
905bool HwcClient::CommandReader::parseSetLayerDataspace(uint16_t length)
906{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500907 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800908 return false;
909 }
910
911 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
912 if (err != Error::NONE) {
913 mWriter.setError(getCommandLoc(), err);
914 }
915
916 return true;
917}
918
919bool HwcClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
920{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500921 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800922 return false;
923 }
924
925 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
926 if (err != Error::NONE) {
927 mWriter.setError(getCommandLoc(), err);
928 }
929
930 return true;
931}
932
933bool HwcClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
934{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500935 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800936 return false;
937 }
938
Dan Stoza0df10c42016-12-19 15:22:47 -0800939 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800940 if (err != Error::NONE) {
941 mWriter.setError(getCommandLoc(), err);
942 }
943
944 return true;
945}
946
947bool HwcClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
948{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500949 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800950 return false;
951 }
952
953 auto stream = readHandle();
954
955 auto err = lookupLayerSidebandStream(stream);
956 if (err == Error::NONE) {
957 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
958 }
959 if (err != Error::NONE) {
960 mWriter.setError(getCommandLoc(), err);
961 }
962
963 return true;
964}
965
966bool HwcClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
967{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500968 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800969 return false;
970 }
971
972 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
973 if (err != Error::NONE) {
974 mWriter.setError(getCommandLoc(), err);
975 }
976
977 return true;
978}
979
980bool HwcClient::CommandReader::parseSetLayerTransform(uint16_t length)
981{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500982 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800983 return false;
984 }
985
986 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
987 if (err != Error::NONE) {
988 mWriter.setError(getCommandLoc(), err);
989 }
990
991 return true;
992}
993
994bool HwcClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
995{
996 // N rectangles
997 if (length % 4 != 0) {
998 return false;
999 }
1000
1001 auto region = readRegion(length / 4);
1002 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1003 if (err != Error::NONE) {
1004 mWriter.setError(getCommandLoc(), err);
1005 }
1006
1007 return true;
1008}
1009
1010bool HwcClient::CommandReader::parseSetLayerZOrder(uint16_t length)
1011{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001012 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001013 return false;
1014 }
1015
1016 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1017 if (err != Error::NONE) {
1018 mWriter.setError(getCommandLoc(), err);
1019 }
1020
1021 return true;
1022}
1023
1024hwc_rect_t HwcClient::CommandReader::readRect()
1025{
1026 return hwc_rect_t{
1027 readSigned(),
1028 readSigned(),
1029 readSigned(),
1030 readSigned(),
1031 };
1032}
1033
1034std::vector<hwc_rect_t> HwcClient::CommandReader::readRegion(size_t count)
1035{
1036 std::vector<hwc_rect_t> region;
1037 region.reserve(count);
1038 while (count > 0) {
1039 region.emplace_back(readRect());
1040 count--;
1041 }
1042
1043 return region;
1044}
1045
1046hwc_frect_t HwcClient::CommandReader::readFRect()
1047{
1048 return hwc_frect_t{
1049 readFloat(),
1050 readFloat(),
1051 readFloat(),
1052 readFloat(),
1053 };
1054}
1055
1056Error HwcClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
1057 bool useCache, buffer_handle_t& handle)
1058{
1059 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1060
1061 auto dpy = mClient.mDisplayData.find(mDisplay);
1062 if (dpy == mClient.mDisplayData.end()) {
1063 return Error::BAD_DISPLAY;
1064 }
1065
1066 BufferClone* clone = nullptr;
1067 switch (cache) {
1068 case BufferCache::CLIENT_TARGETS:
1069 if (slot < dpy->second.ClientTargets.size()) {
1070 clone = &dpy->second.ClientTargets[slot];
1071 }
1072 break;
1073 case BufferCache::OUTPUT_BUFFERS:
1074 if (slot < dpy->second.OutputBuffers.size()) {
1075 clone = &dpy->second.OutputBuffers[slot];
1076 }
1077 break;
1078 case BufferCache::LAYER_BUFFERS:
1079 {
1080 auto ly = dpy->second.Layers.find(mLayer);
1081 if (ly == dpy->second.Layers.end()) {
1082 return Error::BAD_LAYER;
1083 }
1084 if (slot < ly->second.Buffers.size()) {
1085 clone = &ly->second.Buffers[slot];
1086 }
1087 }
1088 break;
1089 case BufferCache::LAYER_SIDEBAND_STREAMS:
1090 {
1091 auto ly = dpy->second.Layers.find(mLayer);
1092 if (ly == dpy->second.Layers.end()) {
1093 return Error::BAD_LAYER;
1094 }
1095 if (slot == 0) {
1096 clone = &ly->second.SidebandStream;
1097 }
1098 }
1099 break;
1100 default:
1101 break;
1102 }
1103
1104 if (!clone) {
1105 ALOGW("invalid buffer slot");
1106 return Error::BAD_PARAMETER;
1107 }
1108
1109 // use or update cache
1110 if (useCache) {
1111 handle = *clone;
1112 } else {
1113 if (!sHandleImporter.importBuffer(handle)) {
1114 return Error::NO_RESOURCES;
1115 }
1116
1117 *clone = handle;
1118 }
1119
1120 return Error::NONE;
1121}
1122
1123} // namespace implementation
1124} // namespace V2_1
1125} // namespace composer
1126} // namespace graphics
1127} // namespace hardware
1128} // namespace android