1 /*
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 <android/hardware/graphics/mapper/2.0/IMapper.h>
20 #include <log/log.h>
21
22 #include "ComposerClient.h"
23 #include "ComposerBase.h"
24 #include "IComposerCommandBuffer.h"
25
26 namespace android {
27 namespace hardware {
28 namespace graphics {
29 namespace composer {
30 namespace V2_1 {
31 namespace implementation {
32
33 namespace {
34
35 using MapperError = android::hardware::graphics::mapper::V2_0::Error;
36 using android::hardware::graphics::mapper::V2_0::IMapper;
37
38 class HandleImporter {
39 public:
initialize()40 bool initialize()
41 {
42 // allow only one client
43 if (mInitialized) {
44 return false;
45 }
46
47 mMapper = IMapper::getService();
48
49 mInitialized = true;
50 return true;
51 }
52
cleanup()53 void cleanup()
54 {
55 mMapper.clear();
56 mInitialized = false;
57 }
58
59 // In IComposer, any buffer_handle_t is owned by the caller and we need to
60 // make a clone for hwcomposer2. We also need to translate empty handle
61 // to nullptr. This function does that, in-place.
importBuffer(buffer_handle_t & handle)62 bool importBuffer(buffer_handle_t& handle)
63 {
64 if (!handle) {
65 return true;
66 }
67
68 if (!handle->numFds && !handle->numInts) {
69 handle = nullptr;
70 return true;
71 }
72
73 MapperError error;
74 buffer_handle_t importedHandle;
75 mMapper->importBuffer(
76 hidl_handle(handle),
77 [&](const auto& tmpError, const auto& tmpBufferHandle) {
78 error = tmpError;
79 importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
80 });
81 if (error != MapperError::NONE) {
82 return false;
83 }
84
85 handle = importedHandle;
86
87 return true;
88 }
89
freeBuffer(buffer_handle_t handle)90 void freeBuffer(buffer_handle_t handle)
91 {
92 if (!handle) {
93 return;
94 }
95
96 mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
97 }
98
99 private:
100 bool mInitialized = false;
101 sp<IMapper> mMapper;
102 };
103
104 HandleImporter sHandleImporter;
105
106 } // anonymous namespace
107
BufferCacheEntry()108 BufferCacheEntry::BufferCacheEntry()
109 : mHandle(nullptr)
110 {
111 }
112
BufferCacheEntry(BufferCacheEntry && other)113 BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other)
114 {
115 mHandle = other.mHandle;
116 other.mHandle = nullptr;
117 }
118
operator =(buffer_handle_t handle)119 BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle)
120 {
121 clear();
122 mHandle = handle;
123 return *this;
124 }
125
~BufferCacheEntry()126 BufferCacheEntry::~BufferCacheEntry()
127 {
128 clear();
129 }
130
clear()131 void BufferCacheEntry::clear()
132 {
133 if (mHandle) {
134 sHandleImporter.freeBuffer(mHandle);
135 }
136 }
137
ComposerClient(ComposerBase & hal)138 ComposerClient::ComposerClient(ComposerBase& hal)
139 : mHal(hal), mWriter(kWriterInitialSize)
140 {
141 }
142
~ComposerClient()143 ComposerClient::~ComposerClient()
144 {
145 // We want to call hwc2_close here (and move hwc2_open to the
146 // constructor), with the assumption that hwc2_close would
147 //
148 // - clean up all resources owned by the client
149 // - make sure all displays are blank (since there is no layer)
150 //
151 // But since SF used to crash at this point, different hwcomposer2
152 // implementations behave differently on hwc2_close. Our only portable
153 // choice really is to abort(). But that is not an option anymore
154 // because we might also have VTS or VR as clients that can come and go.
155 //
156 // Below we manually clean all resources (layers and virtual
157 // displays), and perform a presentDisplay afterwards.
158 ALOGW("destroying composer client");
159
160 mHal.enableCallback(false);
161
162 // no need to grab the mutex as any in-flight hwbinder call would have
163 // kept the client alive
164 for (const auto& dpy : mDisplayData) {
165 ALOGW("destroying client resources for display %" PRIu64, dpy.first);
166
167 for (const auto& ly : dpy.second.Layers) {
168 mHal.destroyLayer(dpy.first, ly.first);
169 }
170
171 if (dpy.second.IsVirtual) {
172 mHal.destroyVirtualDisplay(dpy.first);
173 } else {
174 ALOGW("performing a final presentDisplay");
175
176 std::vector<Layer> changedLayers;
177 std::vector<IComposerClient::Composition> compositionTypes;
178 uint32_t displayRequestMask = 0;
179 std::vector<Layer> requestedLayers;
180 std::vector<uint32_t> requestMasks;
181 mHal.validateDisplay(dpy.first, &changedLayers, &compositionTypes,
182 &displayRequestMask, &requestedLayers, &requestMasks);
183
184 mHal.acceptDisplayChanges(dpy.first);
185
186 int32_t presentFence = -1;
187 std::vector<Layer> releasedLayers;
188 std::vector<int32_t> releaseFences;
189 mHal.presentDisplay(dpy.first, &presentFence, &releasedLayers, &releaseFences);
190 if (presentFence >= 0) {
191 close(presentFence);
192 }
193 for (auto fence : releaseFences) {
194 if (fence >= 0) {
195 close(fence);
196 }
197 }
198 }
199 }
200
201 mDisplayData.clear();
202
203 sHandleImporter.cleanup();
204
205 mHal.removeClient();
206
207 ALOGW("removed composer client");
208 }
209
initialize()210 void ComposerClient::initialize()
211 {
212 mReader = createCommandReader();
213 if (!sHandleImporter.initialize()) {
214 LOG_ALWAYS_FATAL("failed to initialize handle importer");
215 }
216 }
217
onHotplug(Display display,IComposerCallback::Connection connected)218 void ComposerClient::onHotplug(Display display,
219 IComposerCallback::Connection connected)
220 {
221 {
222 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
223
224 if (connected == IComposerCallback::Connection::CONNECTED) {
225 mDisplayData.emplace(display, DisplayData(false));
226 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
227 mDisplayData.erase(display);
228 }
229 }
230
231 auto ret = mCallback->onHotplug(display, connected);
232 ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
233 ret.description().c_str());
234 }
235
onRefresh(Display display)236 void ComposerClient::onRefresh(Display display)
237 {
238 auto ret = mCallback->onRefresh(display);
239 ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s",
240 ret.description().c_str());
241 }
242
onVsync(Display display,int64_t timestamp)243 void ComposerClient::onVsync(Display display, int64_t timestamp)
244 {
245 auto ret = mCallback->onVsync(display, timestamp);
246 ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s",
247 ret.description().c_str());
248 }
249
registerCallback(const sp<IComposerCallback> & callback)250 Return<void> ComposerClient::registerCallback(
251 const sp<IComposerCallback>& callback)
252 {
253 // no locking as we require this function to be called only once
254 mCallback = callback;
255 mHal.enableCallback(callback != nullptr);
256
257 return Void();
258 }
259
getMaxVirtualDisplayCount()260 Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
261 {
262 return mHal.getMaxVirtualDisplayCount();
263 }
264
createVirtualDisplay(uint32_t width,uint32_t height,PixelFormat formatHint,uint32_t outputBufferSlotCount,createVirtualDisplay_cb hidl_cb)265 Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
266 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
267 createVirtualDisplay_cb hidl_cb)
268 {
269 Display display = 0;
270 Error err = mHal.createVirtualDisplay(width, height,
271 &formatHint, &display);
272 if (err == Error::NONE) {
273 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
274
275 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
276 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
277 }
278
279 hidl_cb(err, display, formatHint);
280 return Void();
281 }
282
destroyVirtualDisplay(Display display)283 Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
284 {
285 Error err = mHal.destroyVirtualDisplay(display);
286 if (err == Error::NONE) {
287 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
288
289 mDisplayData.erase(display);
290 }
291
292 return err;
293 }
294
createLayer(Display display,uint32_t bufferSlotCount,createLayer_cb hidl_cb)295 Return<void> ComposerClient::createLayer(Display display,
296 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
297 {
298 Layer layer = 0;
299 Error err = mHal.createLayer(display, &layer);
300 if (err == Error::NONE) {
301 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
302
303 auto dpy = mDisplayData.find(display);
304 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
305 ly->second.Buffers.resize(bufferSlotCount);
306 }
307
308 hidl_cb(err, layer);
309 return Void();
310 }
311
destroyLayer(Display display,Layer layer)312 Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
313 {
314 Error err = mHal.destroyLayer(display, layer);
315 if (err == Error::NONE) {
316 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
317
318 auto dpy = mDisplayData.find(display);
319 dpy->second.Layers.erase(layer);
320 }
321
322 return err;
323 }
324
getActiveConfig(Display display,getActiveConfig_cb hidl_cb)325 Return<void> ComposerClient::getActiveConfig(Display display,
326 getActiveConfig_cb hidl_cb)
327 {
328 Config config = 0;
329 Error err = mHal.getActiveConfig(display, &config);
330
331 hidl_cb(err, config);
332 return Void();
333 }
334
getClientTargetSupport(Display display,uint32_t width,uint32_t height,PixelFormat format,Dataspace dataspace)335 Return<Error> ComposerClient::getClientTargetSupport(Display display,
336 uint32_t width, uint32_t height,
337 PixelFormat format, Dataspace dataspace)
338 {
339 Error err = mHal.getClientTargetSupport(display,
340 width, height, format, dataspace);
341 return err;
342 }
343
getColorModes(Display display,getColorModes_cb hidl_cb)344 Return<void> ComposerClient::getColorModes(Display display,
345 getColorModes_cb hidl_cb)
346 {
347 hidl_vec<ColorMode> modes;
348 Error err = mHal.getColorModes(display, &modes);
349
350 hidl_cb(err, modes);
351 return Void();
352 }
353
getDisplayAttribute(Display display,Config config,Attribute attribute,getDisplayAttribute_cb hidl_cb)354 Return<void> ComposerClient::getDisplayAttribute(Display display,
355 Config config, Attribute attribute,
356 getDisplayAttribute_cb hidl_cb)
357 {
358 int32_t value = 0;
359 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
360
361 hidl_cb(err, value);
362 return Void();
363 }
364
getDisplayConfigs(Display display,getDisplayConfigs_cb hidl_cb)365 Return<void> ComposerClient::getDisplayConfigs(Display display,
366 getDisplayConfigs_cb hidl_cb)
367 {
368 hidl_vec<Config> configs;
369 Error err = mHal.getDisplayConfigs(display, &configs);
370
371 hidl_cb(err, configs);
372 return Void();
373 }
374
getDisplayName(Display display,getDisplayName_cb hidl_cb)375 Return<void> ComposerClient::getDisplayName(Display display,
376 getDisplayName_cb hidl_cb)
377 {
378 hidl_string name;
379 Error err = mHal.getDisplayName(display, &name);
380
381 hidl_cb(err, name);
382 return Void();
383 }
384
getDisplayType(Display display,getDisplayType_cb hidl_cb)385 Return<void> ComposerClient::getDisplayType(Display display,
386 getDisplayType_cb hidl_cb)
387 {
388 DisplayType type = DisplayType::INVALID;
389 Error err = mHal.getDisplayType(display, &type);
390
391 hidl_cb(err, type);
392 return Void();
393 }
394
getDozeSupport(Display display,getDozeSupport_cb hidl_cb)395 Return<void> ComposerClient::getDozeSupport(Display display,
396 getDozeSupport_cb hidl_cb)
397 {
398 bool support = false;
399 Error err = mHal.getDozeSupport(display, &support);
400
401 hidl_cb(err, support);
402 return Void();
403 }
404
getHdrCapabilities(Display display,getHdrCapabilities_cb hidl_cb)405 Return<void> ComposerClient::getHdrCapabilities(Display display,
406 getHdrCapabilities_cb hidl_cb)
407 {
408 hidl_vec<Hdr> types;
409 float max_lumi = 0.0f;
410 float max_avg_lumi = 0.0f;
411 float min_lumi = 0.0f;
412 Error err = mHal.getHdrCapabilities(display, &types,
413 &max_lumi, &max_avg_lumi, &min_lumi);
414
415 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
416 return Void();
417 }
418
setClientTargetSlotCount(Display display,uint32_t clientTargetSlotCount)419 Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
420 uint32_t clientTargetSlotCount)
421 {
422 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
423
424 auto dpy = mDisplayData.find(display);
425 if (dpy == mDisplayData.end()) {
426 return Error::BAD_DISPLAY;
427 }
428
429 dpy->second.ClientTargets.resize(clientTargetSlotCount);
430
431 return Error::NONE;
432 }
433
setActiveConfig(Display display,Config config)434 Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
435 {
436 Error err = mHal.setActiveConfig(display, config);
437 return err;
438 }
439
setColorMode(Display display,ColorMode mode)440 Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
441 {
442 Error err = mHal.setColorMode(display, mode);
443 return err;
444 }
445
setPowerMode(Display display,PowerMode mode)446 Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
447 {
448 Error err = mHal.setPowerMode(display, mode);
449 return err;
450 }
451
setVsyncEnabled(Display display,Vsync enabled)452 Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
453 {
454 Error err = mHal.setVsyncEnabled(display, enabled);
455 return err;
456 }
457
setInputCommandQueue(const MQDescriptorSync<uint32_t> & descriptor)458 Return<Error> ComposerClient::setInputCommandQueue(
459 const MQDescriptorSync<uint32_t>& descriptor)
460 {
461 std::lock_guard<std::mutex> lock(mCommandMutex);
462 return mReader->setMQDescriptor(descriptor) ?
463 Error::NONE : Error::NO_RESOURCES;
464 }
465
getOutputCommandQueue(getOutputCommandQueue_cb hidl_cb)466 Return<void> ComposerClient::getOutputCommandQueue(
467 getOutputCommandQueue_cb hidl_cb)
468 {
469 // no locking as we require this function to be called inside
470 // executeCommands_cb
471
472 auto outDescriptor = mWriter.getMQDescriptor();
473 if (outDescriptor) {
474 hidl_cb(Error::NONE, *outDescriptor);
475 } else {
476 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
477 }
478
479 return Void();
480 }
481
executeCommands(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,executeCommands_cb hidl_cb)482 Return<void> ComposerClient::executeCommands(uint32_t inLength,
483 const hidl_vec<hidl_handle>& inHandles,
484 executeCommands_cb hidl_cb)
485 {
486 std::lock_guard<std::mutex> lock(mCommandMutex);
487
488 bool outChanged = false;
489 uint32_t outLength = 0;
490 hidl_vec<hidl_handle> outHandles;
491
492 if (!mReader->readQueue(inLength, inHandles)) {
493 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
494 return Void();
495 }
496
497 Error err = mReader->parse();
498 if (err == Error::NONE &&
499 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
500 err = Error::NO_RESOURCES;
501 }
502
503 hidl_cb(err, outChanged, outLength, outHandles);
504
505 mReader->reset();
506 mWriter.reset();
507
508 return Void();
509 }
510
511 std::unique_ptr<ComposerClient::CommandReader>
createCommandReader()512 ComposerClient::createCommandReader()
513 {
514 return std::unique_ptr<ComposerClient::CommandReader>(
515 new CommandReader(*this));
516 }
517
CommandReader(ComposerClient & client)518 ComposerClient::CommandReader::CommandReader(ComposerClient& client)
519 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
520 {
521 }
522
~CommandReader()523 ComposerClient::CommandReader::~CommandReader()
524 {
525 }
526
parse()527 Error ComposerClient::CommandReader::parse()
528 {
529 IComposerClient::Command command;
530 uint16_t length = 0;
531
532 while (!isEmpty()) {
533 if (!beginCommand(&command, &length)) {
534 break;
535 }
536
537 bool parsed = parseCommand(command, length);
538 endCommand();
539
540 if (!parsed) {
541 ALOGE("failed to parse command 0x%x, length %" PRIu16,
542 command, length);
543 break;
544 }
545 }
546
547 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
548 }
549
parseCommand(IComposerClient::Command command,uint16_t length)550 bool ComposerClient::CommandReader::parseCommand(
551 IComposerClient::Command command, uint16_t length) {
552 switch (command) {
553 case IComposerClient::Command::SELECT_DISPLAY:
554 return parseSelectDisplay(length);
555 case IComposerClient::Command::SELECT_LAYER:
556 return parseSelectLayer(length);
557 case IComposerClient::Command::SET_COLOR_TRANSFORM:
558 return parseSetColorTransform(length);
559 case IComposerClient::Command::SET_CLIENT_TARGET:
560 return parseSetClientTarget(length);
561 case IComposerClient::Command::SET_OUTPUT_BUFFER:
562 return parseSetOutputBuffer(length);
563 case IComposerClient::Command::VALIDATE_DISPLAY:
564 return parseValidateDisplay(length);
565 case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
566 return parsePresentOrValidateDisplay(length);
567 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
568 return parseAcceptDisplayChanges(length);
569 case IComposerClient::Command::PRESENT_DISPLAY:
570 return parsePresentDisplay(length);
571 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
572 return parseSetLayerCursorPosition(length);
573 case IComposerClient::Command::SET_LAYER_BUFFER:
574 return parseSetLayerBuffer(length);
575 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
576 return parseSetLayerSurfaceDamage(length);
577 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
578 return parseSetLayerBlendMode(length);
579 case IComposerClient::Command::SET_LAYER_COLOR:
580 return parseSetLayerColor(length);
581 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
582 return parseSetLayerCompositionType(length);
583 case IComposerClient::Command::SET_LAYER_DATASPACE:
584 return parseSetLayerDataspace(length);
585 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
586 return parseSetLayerDisplayFrame(length);
587 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
588 return parseSetLayerPlaneAlpha(length);
589 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
590 return parseSetLayerSidebandStream(length);
591 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
592 return parseSetLayerSourceCrop(length);
593 case IComposerClient::Command::SET_LAYER_TRANSFORM:
594 return parseSetLayerTransform(length);
595 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
596 return parseSetLayerVisibleRegion(length);
597 case IComposerClient::Command::SET_LAYER_Z_ORDER:
598 return parseSetLayerZOrder(length);
599 default:
600 return false;
601 }
602 }
603
parseSelectDisplay(uint16_t length)604 bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
605 {
606 if (length != CommandWriterBase::kSelectDisplayLength) {
607 return false;
608 }
609
610 mDisplay = read64();
611 mWriter.selectDisplay(mDisplay);
612
613 return true;
614 }
615
parseSelectLayer(uint16_t length)616 bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
617 {
618 if (length != CommandWriterBase::kSelectLayerLength) {
619 return false;
620 }
621
622 mLayer = read64();
623
624 return true;
625 }
626
parseSetColorTransform(uint16_t length)627 bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
628 {
629 if (length != CommandWriterBase::kSetColorTransformLength) {
630 return false;
631 }
632
633 float matrix[16];
634 for (int i = 0; i < 16; i++) {
635 matrix[i] = readFloat();
636 }
637 auto transform = readSigned();
638
639 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
640 if (err != Error::NONE) {
641 mWriter.setError(getCommandLoc(), err);
642 }
643
644 return true;
645 }
646
parseSetClientTarget(uint16_t length)647 bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
648 {
649 // 4 parameters followed by N rectangles
650 if ((length - 4) % 4 != 0) {
651 return false;
652 }
653
654 bool useCache = false;
655 auto slot = read();
656 auto clientTarget = readHandle(&useCache);
657 auto fence = readFence();
658 auto dataspace = readSigned();
659 auto damage = readRegion((length - 4) / 4);
660 bool closeFence = true;
661
662 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
663 slot, useCache, clientTarget, &clientTarget);
664 if (err == Error::NONE) {
665 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
666 dataspace, damage);
667 auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
668 useCache, clientTarget);
669 if (err == Error::NONE) {
670 closeFence = false;
671 err = updateBufErr;
672 }
673 }
674 if (closeFence) {
675 close(fence);
676 }
677 if (err != Error::NONE) {
678 mWriter.setError(getCommandLoc(), err);
679 }
680
681 return true;
682 }
683
parseSetOutputBuffer(uint16_t length)684 bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
685 {
686 if (length != CommandWriterBase::kSetOutputBufferLength) {
687 return false;
688 }
689
690 bool useCache = false;
691 auto slot = read();
692 auto outputBuffer = readHandle(&useCache);
693 auto fence = readFence();
694 bool closeFence = true;
695
696 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
697 slot, useCache, outputBuffer, &outputBuffer);
698 if (err == Error::NONE) {
699 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
700 auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS,
701 slot, useCache, outputBuffer);
702 if (err == Error::NONE) {
703 closeFence = false;
704 err = updateBufErr;
705 }
706 }
707 if (closeFence) {
708 close(fence);
709 }
710 if (err != Error::NONE) {
711 mWriter.setError(getCommandLoc(), err);
712 }
713
714 return true;
715 }
716
parseValidateDisplay(uint16_t length)717 bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
718 {
719 if (length != CommandWriterBase::kValidateDisplayLength) {
720 return false;
721 }
722
723 std::vector<Layer> changedLayers;
724 std::vector<IComposerClient::Composition> compositionTypes;
725 uint32_t displayRequestMask = 0x0;
726 std::vector<Layer> requestedLayers;
727 std::vector<uint32_t> requestMasks;
728
729 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
730 &compositionTypes, &displayRequestMask,
731 &requestedLayers, &requestMasks);
732 if (err == Error::NONE) {
733 mWriter.setChangedCompositionTypes(changedLayers,
734 compositionTypes);
735 mWriter.setDisplayRequests(displayRequestMask,
736 requestedLayers, requestMasks);
737 } else {
738 mWriter.setError(getCommandLoc(), err);
739 }
740
741 return true;
742 }
743
parsePresentOrValidateDisplay(uint16_t length)744 bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
745 {
746 if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
747 return false;
748 }
749
750 // First try to Present as is.
751 int presentFence = -1;
752 std::vector<Layer> layers;
753 std::vector<int> fences;
754 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
755 if (err == Error::NONE) {
756 mWriter.setPresentOrValidateResult(1);
757 mWriter.setPresentFence(presentFence);
758 mWriter.setReleaseFences(layers, fences);
759 return true;
760 }
761
762 // Present has failed. We need to fallback to validate
763 std::vector<Layer> changedLayers;
764 std::vector<IComposerClient::Composition> compositionTypes;
765 uint32_t displayRequestMask = 0x0;
766 std::vector<Layer> requestedLayers;
767 std::vector<uint32_t> requestMasks;
768
769 err = mHal.validateDisplay(mDisplay, &changedLayers,
770 &compositionTypes, &displayRequestMask,
771 &requestedLayers, &requestMasks);
772 if (err == Error::NONE) {
773 mWriter.setPresentOrValidateResult(0);
774 mWriter.setChangedCompositionTypes(changedLayers,
775 compositionTypes);
776 mWriter.setDisplayRequests(displayRequestMask,
777 requestedLayers, requestMasks);
778 } else {
779 mWriter.setError(getCommandLoc(), err);
780 }
781
782 return true;
783 }
784
parseAcceptDisplayChanges(uint16_t length)785 bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
786 {
787 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
788 return false;
789 }
790
791 auto err = mHal.acceptDisplayChanges(mDisplay);
792 if (err != Error::NONE) {
793 mWriter.setError(getCommandLoc(), err);
794 }
795
796 return true;
797 }
798
parsePresentDisplay(uint16_t length)799 bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
800 {
801 if (length != CommandWriterBase::kPresentDisplayLength) {
802 return false;
803 }
804
805 int presentFence = -1;
806 std::vector<Layer> layers;
807 std::vector<int> fences;
808 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
809 if (err == Error::NONE) {
810 mWriter.setPresentFence(presentFence);
811 mWriter.setReleaseFences(layers, fences);
812 } else {
813 mWriter.setError(getCommandLoc(), err);
814 }
815
816 return true;
817 }
818
parseSetLayerCursorPosition(uint16_t length)819 bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
820 {
821 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
822 return false;
823 }
824
825 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
826 readSigned(), readSigned());
827 if (err != Error::NONE) {
828 mWriter.setError(getCommandLoc(), err);
829 }
830
831 return true;
832 }
833
parseSetLayerBuffer(uint16_t length)834 bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
835 {
836 if (length != CommandWriterBase::kSetLayerBufferLength) {
837 return false;
838 }
839
840 bool useCache = false;
841 auto slot = read();
842 auto buffer = readHandle(&useCache);
843 auto fence = readFence();
844 bool closeFence = true;
845
846 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
847 slot, useCache, buffer, &buffer);
848 if (err == Error::NONE) {
849 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
850 auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot,
851 useCache, buffer);
852 if (err == Error::NONE) {
853 closeFence = false;
854 err = updateBufErr;
855 }
856 }
857 if (closeFence) {
858 close(fence);
859 }
860 if (err != Error::NONE) {
861 mWriter.setError(getCommandLoc(), err);
862 }
863
864 return true;
865 }
866
parseSetLayerSurfaceDamage(uint16_t length)867 bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
868 {
869 // N rectangles
870 if (length % 4 != 0) {
871 return false;
872 }
873
874 auto damage = readRegion(length / 4);
875 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
876 if (err != Error::NONE) {
877 mWriter.setError(getCommandLoc(), err);
878 }
879
880 return true;
881 }
882
parseSetLayerBlendMode(uint16_t length)883 bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
884 {
885 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
886 return false;
887 }
888
889 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
890 if (err != Error::NONE) {
891 mWriter.setError(getCommandLoc(), err);
892 }
893
894 return true;
895 }
896
parseSetLayerColor(uint16_t length)897 bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
898 {
899 if (length != CommandWriterBase::kSetLayerColorLength) {
900 return false;
901 }
902
903 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
904 if (err != Error::NONE) {
905 mWriter.setError(getCommandLoc(), err);
906 }
907
908 return true;
909 }
910
parseSetLayerCompositionType(uint16_t length)911 bool ComposerClient::CommandReader::parseSetLayerCompositionType(
912 uint16_t length)
913 {
914 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
915 return false;
916 }
917
918 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
919 if (err != Error::NONE) {
920 mWriter.setError(getCommandLoc(), err);
921 }
922
923 return true;
924 }
925
parseSetLayerDataspace(uint16_t length)926 bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
927 {
928 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
929 return false;
930 }
931
932 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
933 if (err != Error::NONE) {
934 mWriter.setError(getCommandLoc(), err);
935 }
936
937 return true;
938 }
939
parseSetLayerDisplayFrame(uint16_t length)940 bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
941 {
942 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
943 return false;
944 }
945
946 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
947 if (err != Error::NONE) {
948 mWriter.setError(getCommandLoc(), err);
949 }
950
951 return true;
952 }
953
parseSetLayerPlaneAlpha(uint16_t length)954 bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
955 {
956 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
957 return false;
958 }
959
960 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
961 if (err != Error::NONE) {
962 mWriter.setError(getCommandLoc(), err);
963 }
964
965 return true;
966 }
967
parseSetLayerSidebandStream(uint16_t length)968 bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
969 {
970 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
971 return false;
972 }
973
974 auto stream = readHandle();
975
976 auto err = lookupLayerSidebandStream(stream, &stream);
977 if (err == Error::NONE) {
978 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
979 auto updateErr = updateLayerSidebandStream(stream);
980 if (err == Error::NONE) {
981 err = updateErr;
982 }
983 }
984 if (err != Error::NONE) {
985 mWriter.setError(getCommandLoc(), err);
986 }
987
988 return true;
989 }
990
parseSetLayerSourceCrop(uint16_t length)991 bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
992 {
993 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
994 return false;
995 }
996
997 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
998 if (err != Error::NONE) {
999 mWriter.setError(getCommandLoc(), err);
1000 }
1001
1002 return true;
1003 }
1004
parseSetLayerTransform(uint16_t length)1005 bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
1006 {
1007 if (length != CommandWriterBase::kSetLayerTransformLength) {
1008 return false;
1009 }
1010
1011 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
1012 if (err != Error::NONE) {
1013 mWriter.setError(getCommandLoc(), err);
1014 }
1015
1016 return true;
1017 }
1018
parseSetLayerVisibleRegion(uint16_t length)1019 bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
1020 {
1021 // N rectangles
1022 if (length % 4 != 0) {
1023 return false;
1024 }
1025
1026 auto region = readRegion(length / 4);
1027 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1028 if (err != Error::NONE) {
1029 mWriter.setError(getCommandLoc(), err);
1030 }
1031
1032 return true;
1033 }
1034
parseSetLayerZOrder(uint16_t length)1035 bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
1036 {
1037 if (length != CommandWriterBase::kSetLayerZOrderLength) {
1038 return false;
1039 }
1040
1041 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1042 if (err != Error::NONE) {
1043 mWriter.setError(getCommandLoc(), err);
1044 }
1045
1046 return true;
1047 }
1048
readRect()1049 hwc_rect_t ComposerClient::CommandReader::readRect()
1050 {
1051 return hwc_rect_t{
1052 readSigned(),
1053 readSigned(),
1054 readSigned(),
1055 readSigned(),
1056 };
1057 }
1058
readRegion(size_t count)1059 std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
1060 {
1061 std::vector<hwc_rect_t> region;
1062 region.reserve(count);
1063 while (count > 0) {
1064 region.emplace_back(readRect());
1065 count--;
1066 }
1067
1068 return region;
1069 }
1070
readFRect()1071 hwc_frect_t ComposerClient::CommandReader::readFRect()
1072 {
1073 return hwc_frect_t{
1074 readFloat(),
1075 readFloat(),
1076 readFloat(),
1077 readFloat(),
1078 };
1079 }
1080
lookupBufferCacheEntryLocked(BufferCache cache,uint32_t slot,BufferCacheEntry ** outEntry)1081 Error ComposerClient::CommandReader::lookupBufferCacheEntryLocked(
1082 BufferCache cache, uint32_t slot, BufferCacheEntry** outEntry)
1083 {
1084 auto dpy = mClient.mDisplayData.find(mDisplay);
1085 if (dpy == mClient.mDisplayData.end()) {
1086 return Error::BAD_DISPLAY;
1087 }
1088
1089 BufferCacheEntry* entry = nullptr;
1090 switch (cache) {
1091 case BufferCache::CLIENT_TARGETS:
1092 if (slot < dpy->second.ClientTargets.size()) {
1093 entry = &dpy->second.ClientTargets[slot];
1094 }
1095 break;
1096 case BufferCache::OUTPUT_BUFFERS:
1097 if (slot < dpy->second.OutputBuffers.size()) {
1098 entry = &dpy->second.OutputBuffers[slot];
1099 }
1100 break;
1101 case BufferCache::LAYER_BUFFERS:
1102 {
1103 auto ly = dpy->second.Layers.find(mLayer);
1104 if (ly == dpy->second.Layers.end()) {
1105 return Error::BAD_LAYER;
1106 }
1107 if (slot < ly->second.Buffers.size()) {
1108 entry = &ly->second.Buffers[slot];
1109 }
1110 }
1111 break;
1112 case BufferCache::LAYER_SIDEBAND_STREAMS:
1113 {
1114 auto ly = dpy->second.Layers.find(mLayer);
1115 if (ly == dpy->second.Layers.end()) {
1116 return Error::BAD_LAYER;
1117 }
1118 if (slot == 0) {
1119 entry = &ly->second.SidebandStream;
1120 }
1121 }
1122 break;
1123 default:
1124 break;
1125 }
1126
1127 if (!entry) {
1128 ALOGW("invalid buffer slot %" PRIu32, slot);
1129 return Error::BAD_PARAMETER;
1130 }
1131
1132 *outEntry = entry;
1133
1134 return Error::NONE;
1135 }
1136
lookupBuffer(BufferCache cache,uint32_t slot,bool useCache,buffer_handle_t handle,buffer_handle_t * outHandle)1137 Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1138 uint32_t slot, bool useCache, buffer_handle_t handle,
1139 buffer_handle_t* outHandle)
1140 {
1141 if (useCache) {
1142 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1143
1144 BufferCacheEntry* entry;
1145 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1146 if (error != Error::NONE) {
1147 return error;
1148 }
1149
1150 // input handle is ignored
1151 *outHandle = entry->getHandle();
1152 } else {
1153 if (!sHandleImporter.importBuffer(handle)) {
1154 return Error::NO_RESOURCES;
1155 }
1156
1157 *outHandle = handle;
1158 }
1159
1160 return Error::NONE;
1161 }
1162
updateBuffer(BufferCache cache,uint32_t slot,bool useCache,buffer_handle_t handle)1163 Error ComposerClient::CommandReader::updateBuffer(BufferCache cache,
1164 uint32_t slot, bool useCache, buffer_handle_t handle)
1165 {
1166 // handle was looked up from cache
1167 if (useCache) {
1168 return Error::NONE;
1169 }
1170
1171 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1172
1173 BufferCacheEntry* entry = nullptr;
1174 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1175 if (error != Error::NONE) {
1176 return error;
1177 }
1178
1179 *entry = handle;
1180 return Error::NONE;
1181 }
1182
1183 } // namespace implementation
1184 } // namespace V2_1
1185 } // namespace composer
1186 } // namespace graphics
1187 } // namespace hardware
1188 } // namespace android
1189