blob: 5599959811cb306117b576c3a0a5c744fccfeeab [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 {
105 const hw_module_t* module;
106 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);
179 native_handle_close(handle);
180 native_handle_delete(const_cast<native_handle_t*>(handle));
181 }
182 }
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{
311 Display display;
312 Error err = mHal.createVirtualDisplay(width, height, formatHint, display);
313 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
324Return<Error> HwcClient::destroyVirtualDisplay(Display display)
325{
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
336Return<void> HwcClient::createLayer(Display display, uint32_t bufferSlotCount,
337 createLayer_cb hidl_cb)
338{
339 Layer layer;
340 Error err = mHal.createLayer(display, layer);
341 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
353Return<Error> HwcClient::destroyLayer(Display display, Layer layer)
354{
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
366Return<void> HwcClient::getActiveConfig(Display display,
367 getActiveConfig_cb hidl_cb)
368{
369 Config config;
370 Error err = mHal.getActiveConfig(display, config);
371
372 hidl_cb(err, config);
373 return Void();
374}
375
376Return<Error> HwcClient::getClientTargetSupport(Display display,
377 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
385Return<void> HwcClient::getColorModes(Display display, getColorModes_cb hidl_cb)
386{
387 hidl_vec<ColorMode> modes;
388 Error err = mHal.getColorModes(display, modes);
389
390 hidl_cb(err, modes);
391 return Void();
392}
393
394Return<void> HwcClient::getDisplayAttribute(Display display,
395 Config config, Attribute attribute,
396 getDisplayAttribute_cb hidl_cb)
397{
398 int32_t value;
399 Error err = mHal.getDisplayAttribute(display, config, attribute, value);
400
401 hidl_cb(err, value);
402 return Void();
403}
404
405Return<void> HwcClient::getDisplayConfigs(Display display,
406 getDisplayConfigs_cb hidl_cb)
407{
408 hidl_vec<Config> configs;
409 Error err = mHal.getDisplayConfigs(display, configs);
410
411 hidl_cb(err, configs);
412 return Void();
413}
414
415Return<void> HwcClient::getDisplayName(Display display,
416 getDisplayName_cb hidl_cb)
417{
418 hidl_string name;
419 Error err = mHal.getDisplayName(display, name);
420
421 hidl_cb(err, name);
422 return Void();
423}
424
425Return<void> HwcClient::getDisplayType(Display display,
426 getDisplayType_cb hidl_cb)
427{
428 DisplayType type;
429 Error err = mHal.getDisplayType(display, type);
430
431 hidl_cb(err, type);
432 return Void();
433}
434
435Return<void> HwcClient::getDozeSupport(Display display,
436 getDozeSupport_cb hidl_cb)
437{
438 bool support;
439 Error err = mHal.getDozeSupport(display, support);
440
441 hidl_cb(err, support);
442 return Void();
443}
444
445Return<void> HwcClient::getHdrCapabilities(Display display,
446 getHdrCapabilities_cb hidl_cb)
447{
448 hidl_vec<Hdr> types;
449 float max_lumi = 0.0f;
450 float max_avg_lumi = 0.0f;
451 float min_lumi = 0.0f;
452 Error err = mHal.getHdrCapabilities(display, types,
453 max_lumi, max_avg_lumi, min_lumi);
454
455 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
456 return Void();
457}
458
459Return<Error> HwcClient::setClientTargetSlotCount(Display display,
460 uint32_t clientTargetSlotCount)
461{
462 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
463
464 auto dpy = mDisplayData.find(display);
465 if (dpy == mDisplayData.end()) {
466 return Error::BAD_DISPLAY;
467 }
468
469 dpy->second.ClientTargets.resize(clientTargetSlotCount);
470
471 return Error::NONE;
472}
473
474Return<Error> HwcClient::setActiveConfig(Display display, Config config)
475{
476 Error err = mHal.setActiveConfig(display, config);
477 return err;
478}
479
480Return<Error> HwcClient::setColorMode(Display display, ColorMode mode)
481{
482 Error err = mHal.setColorMode(display, mode);
483 return err;
484}
485
486Return<Error> HwcClient::setPowerMode(Display display, PowerMode mode)
487{
488 Error err = mHal.setPowerMode(display, mode);
489 return err;
490}
491
492Return<Error> HwcClient::setVsyncEnabled(Display display, Vsync enabled)
493{
494 Error err = mHal.setVsyncEnabled(display, enabled);
495 return err;
496}
497
498Return<Error> HwcClient::setInputCommandQueue(
499 const MQDescriptorSync& descriptor)
500{
501 std::lock_guard<std::mutex> lock(mCommandMutex);
502 return mReader.setMQDescriptor(descriptor) ?
503 Error::NONE : Error::NO_RESOURCES;
504}
505
506Return<void> HwcClient::getOutputCommandQueue(
507 getOutputCommandQueue_cb hidl_cb)
508{
509 // no locking as we require this function to be called inside
510 // executeCommands_cb
511
512 auto outDescriptor = mWriter.getMQDescriptor();
513 if (outDescriptor) {
514 hidl_cb(Error::NONE, *outDescriptor);
515 } else {
516 hidl_cb(Error::NO_RESOURCES, MQDescriptorSync(0, nullptr, 0));
517 }
518
519 return Void();
520}
521
522Return<void> HwcClient::executeCommands(uint32_t inLength,
523 const hidl_vec<hidl_handle>& inHandles,
524 executeCommands_cb hidl_cb)
525{
526 std::lock_guard<std::mutex> lock(mCommandMutex);
527
528 bool outChanged = false;
529 uint32_t outLength = 0;
530 hidl_vec<hidl_handle> outHandles;
531
532 if (!mReader.readQueue(inLength, inHandles)) {
533 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
534 return Void();
535 }
536
537 Error err = mReader.parse();
538 if (err == Error::NONE &&
539 !mWriter.writeQueue(outChanged, outLength, outHandles)) {
540 err = Error::NO_RESOURCES;
541 }
542
543 hidl_cb(err, outChanged, outLength, outHandles);
544
545 mReader.reset();
546 mWriter.reset();
547
548 return Void();
549}
550
551HwcClient::CommandReader::CommandReader(HwcClient& client)
552 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
553{
554}
555
556Error HwcClient::CommandReader::parse()
557{
558 IComposerClient::Command command;
559 uint16_t length;
560
561 while (!isEmpty()) {
562 if (!beginCommand(command, length)) {
563 break;
564 }
565
566 bool parsed = false;
567 switch (command) {
568 case IComposerClient::Command::SELECT_DISPLAY:
569 parsed = parseSelectDisplay(length);
570 break;
571 case IComposerClient::Command::SELECT_LAYER:
572 parsed = parseSelectLayer(length);
573 break;
574 case IComposerClient::Command::SET_COLOR_TRANSFORM:
575 parsed = parseSetColorTransform(length);
576 break;
577 case IComposerClient::Command::SET_CLIENT_TARGET:
578 parsed = parseSetClientTarget(length);
579 break;
580 case IComposerClient::Command::SET_OUTPUT_BUFFER:
581 parsed = parseSetOutputBuffer(length);
582 break;
583 case IComposerClient::Command::VALIDATE_DISPLAY:
584 parsed = parseValidateDisplay(length);
585 break;
586 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
587 parsed = parseAcceptDisplayChanges(length);
588 break;
589 case IComposerClient::Command::PRESENT_DISPLAY:
590 parsed = parsePresentDisplay(length);
591 break;
592 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
593 parsed = parseSetLayerCursorPosition(length);
594 break;
595 case IComposerClient::Command::SET_LAYER_BUFFER:
596 parsed = parseSetLayerBuffer(length);
597 break;
598 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
599 parsed = parseSetLayerSurfaceDamage(length);
600 break;
601 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
602 parsed = parseSetLayerBlendMode(length);
603 break;
604 case IComposerClient::Command::SET_LAYER_COLOR:
605 parsed = parseSetLayerColor(length);
606 break;
607 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
608 parsed = parseSetLayerCompositionType(length);
609 break;
610 case IComposerClient::Command::SET_LAYER_DATASPACE:
611 parsed = parseSetLayerDataspace(length);
612 break;
613 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
614 parsed = parseSetLayerDisplayFrame(length);
615 break;
616 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
617 parsed = parseSetLayerPlaneAlpha(length);
618 break;
619 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
620 parsed = parseSetLayerSidebandStream(length);
621 break;
622 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
623 parsed = parseSetLayerSourceCrop(length);
624 break;
625 case IComposerClient::Command::SET_LAYER_TRANSFORM:
626 parsed = parseSetLayerTransform(length);
627 break;
628 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
629 parsed = parseSetLayerVisibleRegion(length);
630 break;
631 case IComposerClient::Command::SET_LAYER_Z_ORDER:
632 parsed = parseSetLayerZOrder(length);
633 break;
634 default:
635 parsed = false;
636 break;
637 }
638
639 endCommand();
640
641 if (!parsed) {
642 ALOGE("failed to parse command 0x%x, length %" PRIu16,
643 command, length);
644 break;
645 }
646 }
647
648 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
649}
650
651bool HwcClient::CommandReader::parseSelectDisplay(uint16_t length)
652{
653 if (length != CommandWriter::kSelectDisplayLength) {
654 return false;
655 }
656
657 mDisplay = read64();
658 mWriter.selectDisplay(mDisplay);
659
660 return true;
661}
662
663bool HwcClient::CommandReader::parseSelectLayer(uint16_t length)
664{
665 if (length != CommandWriter::kSelectLayerLength) {
666 return false;
667 }
668
669 mLayer = read64();
670
671 return true;
672}
673
674bool HwcClient::CommandReader::parseSetColorTransform(uint16_t length)
675{
676 if (length != CommandWriter::kSetColorTransformLength) {
677 return false;
678 }
679
680 float matrix[16];
681 for (int i = 0; i < 16; i++) {
682 matrix[i] = readFloat();
683 }
684 auto transform = readSigned();
685
686 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
687 if (err != Error::NONE) {
688 mWriter.setError(getCommandLoc(), err);
689 }
690
691 return true;
692}
693
694bool HwcClient::CommandReader::parseSetClientTarget(uint16_t length)
695{
696 // 4 parameters followed by N rectangles
697 if ((length - 4) % 4 != 0) {
698 return false;
699 }
700
701 bool useCache;
702 auto slot = read();
703 auto clientTarget = readHandle(useCache);
704 auto fence = readFence();
705 auto dataspace = readSigned();
706 auto damage = readRegion((length - 4) / 4);
707
708 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
709 slot, useCache, clientTarget);
710 if (err == Error::NONE) {
711 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
712 dataspace, damage);
713 }
714 if (err != Error::NONE) {
715 close(fence);
716 mWriter.setError(getCommandLoc(), err);
717 }
718
719 return true;
720}
721
722bool HwcClient::CommandReader::parseSetOutputBuffer(uint16_t length)
723{
724 if (length != CommandWriter::kSetOutputBufferLength) {
725 return false;
726 }
727
728 bool useCache;
729 auto slot = read();
730 auto outputBuffer = readHandle(useCache);
731 auto fence = readFence();
732
733 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
734 slot, useCache, outputBuffer);
735 if (err == Error::NONE) {
736 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
737 }
738 if (err != Error::NONE) {
739 close(fence);
740 mWriter.setError(getCommandLoc(), err);
741 }
742
743 return true;
744}
745
746bool HwcClient::CommandReader::parseValidateDisplay(uint16_t length)
747{
748 if (length != CommandWriter::kValidateDisplayLength) {
749 return false;
750 }
751
752 std::vector<Layer> changedLayers;
753 std::vector<IComposerClient::Composition> compositionTypes;
754 uint32_t displayRequestMask;
755 std::vector<Layer> requestedLayers;
756 std::vector<uint32_t> requestMasks;
757
758 auto err = mHal.validateDisplay(mDisplay, changedLayers, compositionTypes,
759 displayRequestMask, requestedLayers, requestMasks);
760 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
772bool HwcClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
773{
774 if (length != CommandWriter::kAcceptDisplayChangesLength) {
775 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
786bool HwcClient::CommandReader::parsePresentDisplay(uint16_t length)
787{
788 if (length != CommandWriter::kPresentDisplayLength) {
789 return false;
790 }
791
792 int presentFence;
793 std::vector<Layer> layers;
794 std::vector<int> fences;
795 auto err = mHal.presentDisplay(mDisplay, presentFence, layers, fences);
796 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
806bool HwcClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
807{
808 if (length != CommandWriter::kSetLayerCursorPositionLength) {
809 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
821bool HwcClient::CommandReader::parseSetLayerBuffer(uint16_t length)
822{
823 if (length != CommandWriter::kSetLayerBufferLength) {
824 return false;
825 }
826
827 bool useCache;
828 auto slot = read();
829 auto buffer = readHandle(useCache);
830 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
845bool HwcClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
846{
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
861bool HwcClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
862{
863 if (length != CommandWriter::kSetLayerBlendModeLength) {
864 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
875bool HwcClient::CommandReader::parseSetLayerColor(uint16_t length)
876{
877 if (length != CommandWriter::kSetLayerColorLength) {
878 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
889bool HwcClient::CommandReader::parseSetLayerCompositionType(uint16_t length)
890{
891 if (length != CommandWriter::kSetLayerCompositionTypeLength) {
892 return false;
893 }
894
895 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
896 if (err != Error::NONE) {
897 mWriter.setError(getCommandLoc(), err);
898 }
899
900 return true;
901}
902
903bool HwcClient::CommandReader::parseSetLayerDataspace(uint16_t length)
904{
905 if (length != CommandWriter::kSetLayerDataspaceLength) {
906 return false;
907 }
908
909 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
910 if (err != Error::NONE) {
911 mWriter.setError(getCommandLoc(), err);
912 }
913
914 return true;
915}
916
917bool HwcClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
918{
919 if (length != CommandWriter::kSetLayerDisplayFrameLength) {
920 return false;
921 }
922
923 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
924 if (err != Error::NONE) {
925 mWriter.setError(getCommandLoc(), err);
926 }
927
928 return true;
929}
930
931bool HwcClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
932{
933 if (length != CommandWriter::kSetLayerPlaneAlphaLength) {
934 return false;
935 }
936
Dan Stoza0df10c42016-12-19 15:22:47 -0800937 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800938 if (err != Error::NONE) {
939 mWriter.setError(getCommandLoc(), err);
940 }
941
942 return true;
943}
944
945bool HwcClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
946{
947 if (length != CommandWriter::kSetLayerSidebandStreamLength) {
948 return false;
949 }
950
951 auto stream = readHandle();
952
953 auto err = lookupLayerSidebandStream(stream);
954 if (err == Error::NONE) {
955 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
956 }
957 if (err != Error::NONE) {
958 mWriter.setError(getCommandLoc(), err);
959 }
960
961 return true;
962}
963
964bool HwcClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
965{
966 if (length != CommandWriter::kSetLayerSourceCropLength) {
967 return false;
968 }
969
970 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
971 if (err != Error::NONE) {
972 mWriter.setError(getCommandLoc(), err);
973 }
974
975 return true;
976}
977
978bool HwcClient::CommandReader::parseSetLayerTransform(uint16_t length)
979{
980 if (length != CommandWriter::kSetLayerTransformLength) {
981 return false;
982 }
983
984 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
985 if (err != Error::NONE) {
986 mWriter.setError(getCommandLoc(), err);
987 }
988
989 return true;
990}
991
992bool HwcClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
993{
994 // N rectangles
995 if (length % 4 != 0) {
996 return false;
997 }
998
999 auto region = readRegion(length / 4);
1000 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1001 if (err != Error::NONE) {
1002 mWriter.setError(getCommandLoc(), err);
1003 }
1004
1005 return true;
1006}
1007
1008bool HwcClient::CommandReader::parseSetLayerZOrder(uint16_t length)
1009{
1010 if (length != CommandWriter::kSetLayerZOrderLength) {
1011 return false;
1012 }
1013
1014 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1015 if (err != Error::NONE) {
1016 mWriter.setError(getCommandLoc(), err);
1017 }
1018
1019 return true;
1020}
1021
1022hwc_rect_t HwcClient::CommandReader::readRect()
1023{
1024 return hwc_rect_t{
1025 readSigned(),
1026 readSigned(),
1027 readSigned(),
1028 readSigned(),
1029 };
1030}
1031
1032std::vector<hwc_rect_t> HwcClient::CommandReader::readRegion(size_t count)
1033{
1034 std::vector<hwc_rect_t> region;
1035 region.reserve(count);
1036 while (count > 0) {
1037 region.emplace_back(readRect());
1038 count--;
1039 }
1040
1041 return region;
1042}
1043
1044hwc_frect_t HwcClient::CommandReader::readFRect()
1045{
1046 return hwc_frect_t{
1047 readFloat(),
1048 readFloat(),
1049 readFloat(),
1050 readFloat(),
1051 };
1052}
1053
1054Error HwcClient::CommandReader::lookupBuffer(BufferCache cache, uint32_t slot,
1055 bool useCache, buffer_handle_t& handle)
1056{
1057 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1058
1059 auto dpy = mClient.mDisplayData.find(mDisplay);
1060 if (dpy == mClient.mDisplayData.end()) {
1061 return Error::BAD_DISPLAY;
1062 }
1063
1064 BufferClone* clone = nullptr;
1065 switch (cache) {
1066 case BufferCache::CLIENT_TARGETS:
1067 if (slot < dpy->second.ClientTargets.size()) {
1068 clone = &dpy->second.ClientTargets[slot];
1069 }
1070 break;
1071 case BufferCache::OUTPUT_BUFFERS:
1072 if (slot < dpy->second.OutputBuffers.size()) {
1073 clone = &dpy->second.OutputBuffers[slot];
1074 }
1075 break;
1076 case BufferCache::LAYER_BUFFERS:
1077 {
1078 auto ly = dpy->second.Layers.find(mLayer);
1079 if (ly == dpy->second.Layers.end()) {
1080 return Error::BAD_LAYER;
1081 }
1082 if (slot < ly->second.Buffers.size()) {
1083 clone = &ly->second.Buffers[slot];
1084 }
1085 }
1086 break;
1087 case BufferCache::LAYER_SIDEBAND_STREAMS:
1088 {
1089 auto ly = dpy->second.Layers.find(mLayer);
1090 if (ly == dpy->second.Layers.end()) {
1091 return Error::BAD_LAYER;
1092 }
1093 if (slot == 0) {
1094 clone = &ly->second.SidebandStream;
1095 }
1096 }
1097 break;
1098 default:
1099 break;
1100 }
1101
1102 if (!clone) {
1103 ALOGW("invalid buffer slot");
1104 return Error::BAD_PARAMETER;
1105 }
1106
1107 // use or update cache
1108 if (useCache) {
1109 handle = *clone;
1110 } else {
1111 if (!sHandleImporter.importBuffer(handle)) {
1112 return Error::NO_RESOURCES;
1113 }
1114
1115 *clone = handle;
1116 }
1117
1118 return Error::NONE;
1119}
1120
1121} // namespace implementation
1122} // namespace V2_1
1123} // namespace composer
1124} // namespace graphics
1125} // namespace hardware
1126} // namespace android