• 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 "ClientComposer.h"
18 
19 #include "Device.h"
20 #include "Display.h"
21 #include "Drm.h"
22 #include "Layer.h"
23 
24 namespace android {
25 
ClientComposer(DrmPresenter * drmPresenter)26 ClientComposer::ClientComposer(DrmPresenter* drmPresenter)
27     : mDrmPresenter(drmPresenter) {}
28 
init()29 HWC2::Error ClientComposer::init() {
30   DEBUG_LOG("%s", __FUNCTION__);
31 
32   return HWC2::Error::None;
33 }
34 
onDisplayCreate(Display * display)35 HWC2::Error ClientComposer::onDisplayCreate(Display* display) {
36   const auto displayId = display->getId();
37   DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
38 
39   // Ensure created.
40   mDisplayInfos.emplace(displayId, DisplayInfo{});
41 
42   return HWC2::Error::None;
43 }
44 
onDisplayDestroy(Display * display)45 HWC2::Error ClientComposer::onDisplayDestroy(Display* display) {
46   const auto displayId = display->getId();
47   DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
48 
49   auto it = mDisplayInfos.find(displayId);
50   if (it == mDisplayInfos.end()) {
51     ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__,
52           displayId);
53     return HWC2::Error::BadDisplay;
54   }
55 
56   mDisplayInfos.erase(it);
57 
58   return HWC2::Error::None;
59 }
60 
onDisplayClientTargetSet(Display * display)61 HWC2::Error ClientComposer::onDisplayClientTargetSet(Display* display) {
62   const auto displayId = display->getId();
63   DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
64 
65   auto it = mDisplayInfos.find(displayId);
66   if (it == mDisplayInfos.end()) {
67     ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__,
68           displayId);
69     return HWC2::Error::BadDisplay;
70   }
71 
72   DisplayInfo& displayInfo = it->second;
73 
74   auto clientTargetNativeBuffer = display->getClientTarget().getBuffer();
75   auto clientTargetDrmBuffer =
76     std::make_unique<DrmBuffer>(clientTargetNativeBuffer, mDrmPresenter);
77   if (!clientTargetDrmBuffer) {
78     ALOGE("%s: display:%" PRIu64 " failed to create client target drm buffer",
79           __FUNCTION__, displayId);
80     return HWC2::Error::NoResources;
81   }
82 
83   displayInfo.clientTargetDrmBuffer = std::move(clientTargetDrmBuffer);
84 
85   return HWC2::Error::None;
86 }
87 
onActiveConfigChange(Display *)88 HWC2::Error ClientComposer::onActiveConfigChange(Display*) {
89   DEBUG_LOG("%s", __FUNCTION__);
90 
91   return HWC2::Error::None;
92 };
93 
validateDisplay(Display * display,std::unordered_map<hwc2_layer_t,HWC2::Composition> * changes)94 HWC2::Error ClientComposer::validateDisplay(
95     Display* display, std::unordered_map<hwc2_layer_t, HWC2::Composition>* changes) {
96   const auto displayId = display->getId();
97   DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
98   (void)displayId;
99 
100   const std::vector<Layer*>& layers = display->getOrderedLayers();
101 
102   for (Layer* layer : layers) {
103     const auto layerId = layer->getId();
104     const auto layerCompositionType = layer->getCompositionType();
105 
106     if (layerCompositionType != HWC2::Composition::Client) {
107       (*changes)[layerId] = HWC2::Composition::Client;
108     }
109   }
110 
111   return HWC2::Error::None;
112 }
113 
presentDisplay(Display * display)114 std::tuple<HWC2::Error, base::unique_fd> ClientComposer::presentDisplay(
115     Display* display) {
116   ATRACE_CALL();
117 
118   const auto displayId = display->getId();
119   DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId);
120 
121   auto displayInfoIt = mDisplayInfos.find(displayId);
122   if (displayInfoIt == mDisplayInfos.end()) {
123     ALOGE("%s: failed to find display buffers for display:%" PRIu64,
124           __FUNCTION__, displayId);
125     return std::make_tuple(HWC2::Error::BadDisplay, base::unique_fd());
126   }
127 
128   DisplayInfo& displayInfo = displayInfoIt->second;
129 
130   auto clientTargetFence = display->getClientTarget().getFence();
131 
132   auto [error, presentFence] =
133       displayInfo.clientTargetDrmBuffer->flushToDisplay(
134           static_cast<int>(displayId), clientTargetFence);
135   if (error != HWC2::Error::None) {
136     ALOGE("%s: display:%" PRIu64 " failed to flush drm buffer" PRIu64,
137           __FUNCTION__, displayId);
138     return std::make_tuple(error, base::unique_fd());
139   }
140 
141   return std::make_tuple(HWC2::Error::None, std::move(presentFence));
142 }
143 
144 }  // namespace android