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