1 /*
2 * Copyright 2022 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 #include "HostFrameComposer.h"
18
19 #include <EGL/egl.h>
20 #include <EGL/eglext.h>
21 #include <android-base/parseint.h>
22 #include <android-base/properties.h>
23 #include <android-base/strings.h>
24 #include <android-base/unique_fd.h>
25 #include <hardware/hwcomposer2.h>
26 #include <poll.h>
27 #include <sync/sync.h>
28 #include <ui/GraphicBuffer.h>
29
30 #include <optional>
31 #include <tuple>
32
33 #include "../egl/goldfish_sync.h"
34 #include "Display.h"
35 #include "HostUtils.h"
36 #include "virtgpu_drm.h"
37
38 namespace aidl::android::hardware::graphics::composer3::impl {
39 namespace {
40
AsHwcRect(const common::Rect & rect)41 hwc_rect AsHwcRect(const common::Rect& rect) {
42 hwc_rect out;
43 out.left = rect.left;
44 out.top = rect.top;
45 out.right = rect.right;
46 out.bottom = rect.bottom;
47 return out;
48 }
49
AsHwcFrect(const common::FRect & rect)50 hwc_frect AsHwcFrect(const common::FRect& rect) {
51 hwc_frect out;
52 out.left = rect.left;
53 out.top = rect.top;
54 out.right = rect.right;
55 out.bottom = rect.bottom;
56 return out;
57 }
58
AsHwcColor(const Color & color)59 hwc_color AsHwcColor(const Color& color) {
60 hwc_color out;
61 out.r = static_cast<uint8_t>(color.r * 255.0f);
62 out.g = static_cast<uint8_t>(color.g * 255.0f);
63 out.b = static_cast<uint8_t>(color.b * 255.0f);
64 out.a = static_cast<uint8_t>(color.a * 255.0f);
65 return out;
66 }
67
AsHwcTransform(const common::Transform & transform)68 hwc_transform_t AsHwcTransform(const common::Transform& transform) {
69 switch (transform) {
70 case common::Transform::NONE:
71 return static_cast<hwc_transform_t>(0);
72 case common::Transform::FLIP_H:
73 return HWC_TRANSFORM_FLIP_H;
74 case common::Transform::FLIP_V:
75 return HWC_TRANSFORM_FLIP_V;
76 case common::Transform::ROT_90:
77 return HWC_TRANSFORM_ROT_90;
78 case common::Transform::ROT_180:
79 return HWC_TRANSFORM_ROT_180;
80 case common::Transform::ROT_270:
81 return HWC_TRANSFORM_ROT_270;
82 }
83 }
84
isMinigbmFromProperty()85 static bool isMinigbmFromProperty() {
86 static constexpr const auto kGrallocProp = "ro.hardware.gralloc";
87
88 const auto grallocProp = ::android::base::GetProperty(kGrallocProp, "");
89 DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, grallocProp.c_str());
90
91 if (grallocProp == "minigbm") {
92 DEBUG_LOG("%s: Using minigbm, in minigbm mode.\n", __FUNCTION__);
93 return true;
94 } else {
95 DEBUG_LOG("%s: Is not using minigbm, in goldfish mode.\n", __FUNCTION__);
96 return false;
97 }
98 }
99
100 typedef struct compose_layer {
101 uint32_t cbHandle;
102 hwc2_composition_t composeMode;
103 hwc_rect_t displayFrame;
104 hwc_frect_t crop;
105 int32_t blendMode;
106 float alpha;
107 hwc_color_t color;
108 hwc_transform_t transform;
109 } ComposeLayer;
110
111 typedef struct compose_device {
112 uint32_t version;
113 uint32_t targetHandle;
114 uint32_t numLayers;
115 struct compose_layer layer[0];
116 } ComposeDevice;
117
118 typedef struct compose_device_v2 {
119 uint32_t version;
120 uint32_t displayId;
121 uint32_t targetHandle;
122 uint32_t numLayers;
123 struct compose_layer layer[0];
124 } ComposeDevice_v2;
125
126 class ComposeMsg {
127 public:
ComposeMsg(uint32_t layerCnt=0)128 ComposeMsg(uint32_t layerCnt = 0)
129 : mData(sizeof(ComposeDevice) + layerCnt * sizeof(ComposeLayer)) {
130 mComposeDevice = reinterpret_cast<ComposeDevice*>(mData.data());
131 mLayerCnt = layerCnt;
132 }
133
get()134 ComposeDevice* get() { return mComposeDevice; }
135
getLayerCnt()136 uint32_t getLayerCnt() { return mLayerCnt; }
137
138 private:
139 std::vector<uint8_t> mData;
140 uint32_t mLayerCnt;
141 ComposeDevice* mComposeDevice;
142 };
143
144 class ComposeMsg_v2 {
145 public:
ComposeMsg_v2(uint32_t layerCnt=0)146 ComposeMsg_v2(uint32_t layerCnt = 0)
147 : mData(sizeof(ComposeDevice_v2) + layerCnt * sizeof(ComposeLayer)) {
148 mComposeDevice = reinterpret_cast<ComposeDevice_v2*>(mData.data());
149 mLayerCnt = layerCnt;
150 }
151
get()152 ComposeDevice_v2* get() { return mComposeDevice; }
153
getLayerCnt()154 uint32_t getLayerCnt() { return mLayerCnt; }
155
156 private:
157 std::vector<uint8_t> mData;
158 uint32_t mLayerCnt;
159 ComposeDevice_v2* mComposeDevice;
160 };
161
162 } // namespace
163
init()164 HWC3::Error HostFrameComposer::init() {
165 mIsMinigbm = isMinigbmFromProperty();
166
167 if (mIsMinigbm) {
168 mDrmClient.emplace();
169
170 HWC3::Error error = mDrmClient->init();
171 if (error != HWC3::Error::None) {
172 ALOGE("%s: failed to initialize DrmClient", __FUNCTION__);
173 return error;
174 }
175 } else {
176 mSyncDeviceFd = goldfish_sync_open();
177 }
178
179 return HWC3::Error::None;
180 }
181
registerOnHotplugCallback(const HotplugCallback & cb)182 HWC3::Error HostFrameComposer::registerOnHotplugCallback(const HotplugCallback& cb) {
183 if (mDrmClient) {
184 mDrmClient->registerOnHotplugCallback(cb);
185 }
186 return HWC3::Error::None;
187 }
188
unregisterOnHotplugCallback()189 HWC3::Error HostFrameComposer::unregisterOnHotplugCallback() {
190 if (mDrmClient) {
191 mDrmClient->unregisterOnHotplugCallback();
192 }
193 return HWC3::Error::None;
194 }
195
createHostComposerDisplayInfo(Display * display,uint32_t hostDisplayId)196 HWC3::Error HostFrameComposer::createHostComposerDisplayInfo(Display* display,
197 uint32_t hostDisplayId) {
198 HWC3::Error error = HWC3::Error::None;
199
200 int64_t displayId = display->getId();
201 int32_t displayConfigId;
202 int32_t displayWidth;
203 int32_t displayHeight;
204
205 error = display->getActiveConfig(&displayConfigId);
206 if (error != HWC3::Error::None) {
207 ALOGE("%s: display:%" PRIu64 " has no active config", __FUNCTION__, displayId);
208 return error;
209 }
210
211 error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, &displayWidth);
212 if (error != HWC3::Error::None) {
213 ALOGE("%s: display:%" PRIu64 " failed to get width", __FUNCTION__, displayId);
214 return error;
215 }
216
217 error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::HEIGHT, &displayHeight);
218 if (error != HWC3::Error::None) {
219 ALOGE("%s: display:%" PRIu64 " failed to get height", __FUNCTION__, displayId);
220 return error;
221 }
222
223 HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId];
224
225 displayInfo.hostDisplayId = hostDisplayId;
226 displayInfo.swapchain = DrmSwapchain::create(
227 static_cast<uint32_t>(displayWidth), static_cast<uint32_t>(displayHeight),
228 ::android::GraphicBuffer::USAGE_HW_COMPOSER | ::android::GraphicBuffer::USAGE_HW_RENDER,
229 mDrmClient ? &mDrmClient.value() : nullptr);
230 if (!displayInfo.swapchain) {
231 ALOGE("%s: display:%" PRIu64 " failed to allocate swapchain", __FUNCTION__, displayId);
232 return HWC3::Error::NoResources;
233 }
234 return HWC3::Error::None;
235 }
236
onDisplayCreate(Display * display)237 HWC3::Error HostFrameComposer::onDisplayCreate(Display* display) {
238 HWC3::Error error = HWC3::Error::None;
239
240 const uint32_t displayId = static_cast<uint32_t>(display->getId());
241 int32_t displayConfigId;
242 int32_t displayWidth;
243 int32_t displayHeight;
244 int32_t displayDpiX;
245
246 error = display->getActiveConfig(&displayConfigId);
247 if (error != HWC3::Error::None) {
248 ALOGE("%s: display:%" PRIu32 " has no active config", __FUNCTION__, displayId);
249 return error;
250 }
251
252 error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::WIDTH, &displayWidth);
253 if (error != HWC3::Error::None) {
254 ALOGE("%s: display:%" PRIu32 " failed to get width", __FUNCTION__, displayId);
255 return error;
256 }
257
258 error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::HEIGHT, &displayHeight);
259 if (error != HWC3::Error::None) {
260 ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId);
261 return error;
262 }
263
264 error = display->getDisplayAttribute(displayConfigId, DisplayAttribute::DPI_X, &displayDpiX);
265 if (error != HWC3::Error::None) {
266 ALOGE("%s: display:%" PRIu32 " failed to get height", __FUNCTION__, displayId);
267 return error;
268 }
269
270 uint32_t hostDisplayId = 0;
271
272 DEFINE_AND_VALIDATE_HOST_CONNECTION
273 if (displayId == 0) {
274 // Primary display:
275 hostCon->lock();
276 if (rcEnc->rcCreateDisplayById(rcEnc, displayId)) {
277 ALOGE("%s host failed to create display %" PRIu32, __func__, displayId);
278 hostCon->unlock();
279 return HWC3::Error::NoResources;
280 }
281 if (rcEnc->rcSetDisplayPoseDpi(
282 rcEnc, displayId, -1, -1, static_cast<uint32_t>(displayWidth),
283 static_cast<uint32_t>(displayHeight), static_cast<uint32_t>(displayDpiX / 1000))) {
284 ALOGE("%s host failed to set display %" PRIu32, __func__, displayId);
285 hostCon->unlock();
286 return HWC3::Error::NoResources;
287 }
288 hostCon->unlock();
289 } else {
290 // Secondary display:
291 static constexpr const uint32_t kHostDisplayIdStart = 6;
292
293 uint32_t expectedHostDisplayId = kHostDisplayIdStart + displayId - 1;
294 uint32_t actualHostDisplayId = 0;
295
296 hostCon->lock();
297 rcEnc->rcDestroyDisplay(rcEnc, expectedHostDisplayId);
298 rcEnc->rcCreateDisplay(rcEnc, &actualHostDisplayId);
299 rcEnc->rcSetDisplayPose(rcEnc, actualHostDisplayId, -1, -1,
300 static_cast<uint32_t>(displayWidth),
301 static_cast<uint32_t>(displayHeight));
302 hostCon->unlock();
303
304 if (actualHostDisplayId != expectedHostDisplayId) {
305 ALOGE(
306 "Something wrong with host displayId allocation, expected %d "
307 "but received %d",
308 expectedHostDisplayId, actualHostDisplayId);
309 }
310
311 hostDisplayId = actualHostDisplayId;
312 }
313
314 error = createHostComposerDisplayInfo(display, hostDisplayId);
315 if (error != HWC3::Error::None) {
316 ALOGE("%s failed to initialize host info for display:%" PRIu32, __FUNCTION__, displayId);
317 return error;
318 }
319
320 std::optional<std::vector<uint8_t>> edid;
321 if (mDrmClient) {
322 edid = mDrmClient->getEdid(displayId);
323 if (edid) {
324 display->setEdid(*edid);
325 }
326 }
327
328 return HWC3::Error::None;
329 }
330
onDisplayDestroy(Display * display)331 HWC3::Error HostFrameComposer::onDisplayDestroy(Display* display) {
332 int64_t displayId = display->getId();
333
334 auto it = mDisplayInfos.find(displayId);
335 if (it == mDisplayInfos.end()) {
336 ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId);
337 return HWC3::Error::BadDisplay;
338 }
339
340 HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId];
341
342 if (displayId != 0) {
343 DEFINE_AND_VALIDATE_HOST_CONNECTION
344 hostCon->lock();
345 rcEnc->rcDestroyDisplay(rcEnc, displayInfo.hostDisplayId);
346 hostCon->unlock();
347 }
348
349 mDisplayInfos.erase(it);
350
351 return HWC3::Error::None;
352 }
353
onDisplayClientTargetSet(Display * display)354 HWC3::Error HostFrameComposer::onDisplayClientTargetSet(Display* display) {
355 int64_t displayId = display->getId();
356
357 auto it = mDisplayInfos.find(displayId);
358 if (it == mDisplayInfos.end()) {
359 ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId);
360 return HWC3::Error::BadDisplay;
361 }
362
363 HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId];
364
365 if (mIsMinigbm) {
366 FencedBuffer& clientTargetFencedBuffer = display->getClientTarget();
367
368 auto [drmBufferCreateError, drmBuffer] =
369 mDrmClient->create(clientTargetFencedBuffer.getBuffer());
370 if (drmBufferCreateError != HWC3::Error::None) {
371 ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer", __FUNCTION__,
372 displayId);
373 return HWC3::Error::NoResources;
374 }
375 displayInfo.clientTargetDrmBuffer = std::move(drmBuffer);
376 }
377
378 return HWC3::Error::None;
379 }
380
validateDisplay(Display * display,DisplayChanges * outChanges)381 HWC3::Error HostFrameComposer::validateDisplay(Display* display, DisplayChanges* outChanges) {
382 const auto& displayId = display->getId();
383
384 DEFINE_AND_VALIDATE_HOST_CONNECTION
385 hostCon->lock();
386 bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
387 bool hostCompositionV2 = rcEnc->hasHostCompositionV2();
388 hostCon->unlock();
389
390 const std::vector<Layer*> layers = display->getOrderedLayers();
391 for (const auto& layer : layers) {
392 switch (layer->getCompositionType()) {
393 case Composition::INVALID:
394 // Log error for unused layers, layer leak?
395 ALOGE("%s layer:%" PRIu64 " CompositionType not set", __FUNCTION__, layer->getId());
396 break;
397 case Composition::DISPLAY_DECORATION:
398 return HWC3::Error::Unsupported;
399 default:
400 break;
401 }
402 }
403
404 // If one layer requires a fall back to the client composition type, all
405 // layers will fall back to the client composition type.
406 bool fallBackToClient =
407 (!hostCompositionV1 && !hostCompositionV2);
408 std::unordered_map<Layer*, Composition> changes;
409
410 if (!fallBackToClient) {
411 for (const auto& layer : layers) {
412 const auto& layerCompositionType = layer->getCompositionType();
413 const auto layerCompositionTypeString = toString(layerCompositionType);
414
415 std::optional<Composition> layerFallBackTo = std::nullopt;
416 switch (layerCompositionType) {
417 case Composition::CLIENT:
418 case Composition::SIDEBAND:
419 ALOGV("%s: layer %" PRIu32 " CompositionType %s, fallback to client",
420 __FUNCTION__, static_cast<uint32_t>(layer->getId()),
421 layerCompositionTypeString.c_str());
422 layerFallBackTo = Composition::CLIENT;
423 break;
424 case Composition::CURSOR:
425 ALOGV("%s: layer %" PRIu32 " CompositionType %s, fallback to device",
426 __FUNCTION__, static_cast<uint32_t>(layer->getId()),
427 layerCompositionTypeString.c_str());
428 layerFallBackTo = Composition::DEVICE;
429 break;
430 case Composition::INVALID:
431 case Composition::DEVICE:
432 case Composition::SOLID_COLOR:
433 layerFallBackTo = std::nullopt;
434 break;
435 default:
436 ALOGE("%s: layer %" PRIu32 " has an unknown composition type: %s", __FUNCTION__,
437 static_cast<uint32_t>(layer->getId()), layerCompositionTypeString.c_str());
438 }
439 if (layerFallBackTo == Composition::CLIENT) {
440 fallBackToClient = true;
441 }
442 if (layerFallBackTo.has_value()) {
443 changes.emplace(layer, layerFallBackTo.value());
444 }
445 }
446 }
447
448 if (fallBackToClient) {
449 changes.clear();
450 for (auto& layer : layers) {
451 if (layer->getCompositionType() == Composition::INVALID) {
452 continue;
453 }
454 if (layer->getCompositionType() != Composition::CLIENT) {
455 changes.emplace(layer, Composition::CLIENT);
456 }
457 }
458 }
459
460 outChanges->clearLayerCompositionChanges();
461 for (auto& [layer, newCompositionType] : changes) {
462 layer->logCompositionFallbackIfChanged(newCompositionType);
463 outChanges->addLayerCompositionChange(displayId, layer->getId(), newCompositionType);
464 }
465
466 return HWC3::Error::None;
467 }
468
presentDisplay(Display * display,::android::base::unique_fd * outDisplayFence,std::unordered_map<int64_t,::android::base::unique_fd> * outLayerFences)469 HWC3::Error HostFrameComposer::presentDisplay(
470 Display* display, ::android::base::unique_fd* outDisplayFence,
471 std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) {
472 const uint32_t displayId = static_cast<uint32_t>(display->getId());
473 auto displayInfoIt = mDisplayInfos.find(displayId);
474 if (displayInfoIt == mDisplayInfos.end()) {
475 ALOGE("%s: failed to find display buffers for display:%" PRIu32, __FUNCTION__, displayId);
476 return HWC3::Error::BadDisplay;
477 }
478
479 HostComposerDisplayInfo& displayInfo = displayInfoIt->second;
480
481 HostConnection* hostCon;
482 ExtendedRCEncoderContext* rcEnc;
483 HWC3::Error error = getAndValidateHostConnection(&hostCon, &rcEnc);
484 if (error != HWC3::Error::None) {
485 return error;
486 }
487 *outDisplayFence = ::android::base::unique_fd();
488 hostCon->lock();
489 bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
490 bool hostCompositionV2 = rcEnc->hasHostCompositionV2();
491 hostCon->unlock();
492
493 // Ff we supports v2, then discard v1
494 if (hostCompositionV2) {
495 hostCompositionV1 = false;
496 }
497
498 auto compositionResult = displayInfo.swapchain->getNextImage();
499 compositionResult->wait();
500
501 const std::vector<Layer*> layers = display->getOrderedLayers();
502 if (hostCompositionV2 || hostCompositionV1) {
503 uint32_t numLayer = 0;
504 for (auto layer : layers) {
505 if (layer->getCompositionType() == Composition::DEVICE ||
506 layer->getCompositionType() == Composition::SOLID_COLOR) {
507 numLayer++;
508 }
509 }
510
511 DEBUG_LOG("%s: presenting display:%" PRIu32 " with %d layers", __FUNCTION__, displayId,
512 static_cast<int>(layers.size()));
513
514 if (numLayer == 0) {
515 ALOGV("%s display has no layers to compose, flushing client target buffer.",
516 __FUNCTION__);
517
518 FencedBuffer& displayClientTarget = display->getClientTarget();
519 if (displayClientTarget.getBuffer() != nullptr) {
520 ::android::base::unique_fd fence = displayClientTarget.getFence();
521 if (mIsMinigbm) {
522 auto [_, flushCompleteFence] = mDrmClient->flushToDisplay(
523 displayId, displayInfo.clientTargetDrmBuffer, fence);
524
525 *outDisplayFence = std::move(flushCompleteFence);
526 } else {
527 post(hostCon, rcEnc, displayInfo.hostDisplayId, displayClientTarget.getBuffer());
528 *outDisplayFence = std::move(fence);
529 }
530 }
531 return HWC3::Error::None;
532 }
533
534 std::unique_ptr<ComposeMsg> composeMsg;
535 std::unique_ptr<ComposeMsg_v2> composeMsgV2;
536
537 if (hostCompositionV1) {
538 composeMsg.reset(new ComposeMsg(numLayer));
539 } else {
540 composeMsgV2.reset(new ComposeMsg_v2(numLayer));
541 }
542
543 // Handle the composition
544 ComposeDevice* p;
545 ComposeDevice_v2* p2;
546 ComposeLayer* l;
547
548 if (hostCompositionV1) {
549 p = composeMsg->get();
550 l = p->layer;
551 } else {
552 p2 = composeMsgV2->get();
553 l = p2->layer;
554 }
555
556 std::vector<int64_t> releaseLayerIds;
557 for (auto layer : layers) {
558 const auto& layerCompositionType = layer->getCompositionType();
559 const auto layerCompositionTypeString = toString(layerCompositionType);
560
561 // TODO: use local var composisitonType to store getCompositionType()
562 if (layerCompositionType != Composition::DEVICE &&
563 layerCompositionType != Composition::SOLID_COLOR) {
564 ALOGE("%s: Unsupported composition type %s layer %u", __FUNCTION__,
565 layerCompositionTypeString.c_str(), (uint32_t)layer->getId());
566 continue;
567 }
568 // send layer composition command to host
569 if (layerCompositionType == Composition::DEVICE) {
570 releaseLayerIds.emplace_back(layer->getId());
571
572 ::android::base::unique_fd fence = layer->getBuffer().getFence();
573 if (fence.ok()) {
574 int err = sync_wait(fence.get(), 3000);
575 if (err < 0 && errno == ETIME) {
576 ALOGE("%s waited on fence %d for 3000 ms", __FUNCTION__, fence.get());
577 }
578 } else {
579 ALOGV("%s: acquire fence not set for layer %u", __FUNCTION__,
580 (uint32_t)layer->getId());
581 }
582 const native_handle_t* cb = layer->getBuffer().getBuffer();
583 if (cb != nullptr) {
584 l->cbHandle = hostCon->grallocHelper()->getHostHandle(cb);
585 } else {
586 ALOGE("%s null buffer for layer %d", __FUNCTION__, (uint32_t)layer->getId());
587 }
588 } else {
589 // solidcolor has no buffer
590 l->cbHandle = 0;
591 }
592 l->composeMode = (hwc2_composition_t)layerCompositionType;
593 l->displayFrame = AsHwcRect(layer->getDisplayFrame());
594 l->crop = AsHwcFrect(layer->getSourceCrop());
595 l->blendMode = static_cast<int32_t>(layer->getBlendMode());
596 l->alpha = layer->getPlaneAlpha();
597 l->color = AsHwcColor(layer->getColor());
598 l->transform = AsHwcTransform(layer->getTransform());
599 ALOGV(
600 " cb %d blendmode %d alpha %f %d %d %d %d z %d"
601 " composeMode %d, transform %d",
602 l->cbHandle, l->blendMode, l->alpha, l->displayFrame.left, l->displayFrame.top,
603 l->displayFrame.right, l->displayFrame.bottom, layer->getZOrder(), l->composeMode,
604 l->transform);
605 l++;
606 }
607
608 if (hostCompositionV1) {
609 p->version = 1;
610 p->targetHandle =
611 hostCon->grallocHelper()->getHostHandle(compositionResult->getBuffer());
612 p->numLayers = numLayer;
613 } else {
614 p2->version = 2;
615 p2->displayId = displayInfo.hostDisplayId;
616 p2->targetHandle =
617 hostCon->grallocHelper()->getHostHandle(compositionResult->getBuffer());
618 p2->numLayers = numLayer;
619 }
620
621 void* buffer;
622 uint32_t bufferSize;
623 if (hostCompositionV1) {
624 buffer = (void*)p;
625 bufferSize = sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer);
626 } else {
627 bufferSize = sizeof(ComposeDevice_v2) + numLayer * sizeof(ComposeLayer);
628 buffer = (void*)p2;
629 }
630
631 ::android::base::unique_fd retire_fd;
632 hostCon->lock();
633 if (rcEnc->hasAsyncFrameCommands()) {
634 if (mIsMinigbm) {
635 rcEnc->rcComposeAsyncWithoutPost(rcEnc, bufferSize, buffer);
636 } else {
637 rcEnc->rcComposeAsync(rcEnc, bufferSize, buffer);
638 }
639 } else {
640 if (mIsMinigbm) {
641 rcEnc->rcComposeWithoutPost(rcEnc, bufferSize, buffer);
642 } else {
643 rcEnc->rcCompose(rcEnc, bufferSize, buffer);
644 }
645 }
646 hostCon->unlock();
647
648 // Send a retire fence and use it as the release fence for all layers,
649 // since media expects it
650 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID};
651
652 uint64_t sync_handle, thread_handle;
653
654 // We don't use rc command to sync if we are using virtio-gpu, which is
655 // proxied by minigbm.
656 bool useRcCommandToSync = !mIsMinigbm;
657
658 if (useRcCommandToSync) {
659 hostCon->lock();
660 rcEnc->rcCreateSyncKHR(rcEnc, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs,
661 2 * sizeof(EGLint), true /* destroy when signaled */,
662 &sync_handle, &thread_handle);
663 hostCon->unlock();
664 }
665
666 if (mIsMinigbm) {
667 auto [_, fence] =
668 mDrmClient->flushToDisplay(displayId, compositionResult->getDrmBuffer(), -1);
669 retire_fd = std::move(fence);
670 } else {
671 int fd;
672 goldfish_sync_queue_work(mSyncDeviceFd, sync_handle, thread_handle, &fd);
673 retire_fd = ::android::base::unique_fd(fd);
674 }
675
676 for (int64_t layerId : releaseLayerIds) {
677 (*outLayerFences)[layerId] = ::android::base::unique_fd(dup(retire_fd.get()));
678 }
679 *outDisplayFence = ::android::base::unique_fd(dup(retire_fd.get()));
680
681 if (useRcCommandToSync) {
682 hostCon->lock();
683 if (rcEnc->hasAsyncFrameCommands()) {
684 rcEnc->rcDestroySyncKHRAsync(rcEnc, sync_handle);
685 } else {
686 rcEnc->rcDestroySyncKHR(rcEnc, sync_handle);
687 }
688 hostCon->unlock();
689 }
690 } else {
691 // we set all layers Composition::CLIENT, so do nothing.
692 FencedBuffer& displayClientTarget = display->getClientTarget();
693 ::android::base::unique_fd displayClientTargetFence = displayClientTarget.getFence();
694 if (mIsMinigbm) {
695 auto [_, flushFence] = mDrmClient->flushToDisplay(
696 displayId, compositionResult->getDrmBuffer(), displayClientTargetFence);
697 *outDisplayFence = std::move(flushFence);
698 } else {
699 post(hostCon, rcEnc, displayInfo.hostDisplayId, displayClientTarget.getBuffer());
700 *outDisplayFence = std::move(displayClientTargetFence);
701 }
702 ALOGV("%s fallback to post, returns outRetireFence %d", __FUNCTION__,
703 outDisplayFence->get());
704 }
705 compositionResult->markAsInUse(outDisplayFence->ok()
706 ? ::android::base::unique_fd(dup(*outDisplayFence))
707 : ::android::base::unique_fd());
708 return HWC3::Error::None;
709 }
710
post(HostConnection * hostCon,ExtendedRCEncoderContext * rcEnc,uint32_t hostDisplayId,buffer_handle_t h)711 void HostFrameComposer::post(HostConnection* hostCon, ExtendedRCEncoderContext* rcEnc,
712 uint32_t hostDisplayId, buffer_handle_t h) {
713 assert(cb && "native_handle_t::from(h) failed");
714
715 hostCon->lock();
716 rcEnc->rcSetDisplayColorBuffer(
717 rcEnc, hostDisplayId,
718 hostCon->grallocHelper()->getHostHandle(h));
719 rcEnc->rcFBPost(rcEnc, hostCon->grallocHelper()->getHostHandle(h));
720 hostCon->flush();
721 hostCon->unlock();
722 }
723
onActiveConfigChange(Display * display)724 HWC3::Error HostFrameComposer::onActiveConfigChange(Display* display) {
725 const uint32_t displayId = static_cast<uint32_t>(display->getId());
726 DEBUG_LOG("%s: display:%" PRIu32, __FUNCTION__, displayId);
727 HWC3::Error error = createHostComposerDisplayInfo(display, displayId);
728 if (error != HWC3::Error::None) {
729 ALOGE("%s failed to update host info for display:%" PRIu32, __FUNCTION__, displayId);
730 return error;
731 }
732 return HWC3::Error::None;
733 }
734
735 } // namespace aidl::android::hardware::graphics::composer3::impl
736