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