• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include "drmdisplaycompositor.h"
18 #include "drmhwcomposer.h"
19 #include "platform.h"
20 #include "resourcemanager.h"
21 #include "vsyncworker.h"
22 
23 #include <hardware/hwcomposer2.h>
24 
25 #include <array>
26 #include <map>
27 
28 namespace android {
29 
30 class DrmHwcTwo : public hwc2_device_t {
31  public:
32   static int HookDevOpen(const struct hw_module_t *module, const char *name,
33                          struct hw_device_t **dev);
34 
35   DrmHwcTwo();
36 
37   HWC2::Error Init();
38 
39  private:
40   class HwcLayer {
41    public:
sf_type()42     HWC2::Composition sf_type() const {
43       return sf_type_;
44     }
validated_type()45     HWC2::Composition validated_type() const {
46       return validated_type_;
47     }
accept_type_change()48     void accept_type_change() {
49       sf_type_ = validated_type_;
50     }
set_validated_type(HWC2::Composition type)51     void set_validated_type(HWC2::Composition type) {
52       validated_type_ = type;
53     }
type_changed()54     bool type_changed() const {
55       return sf_type_ != validated_type_;
56     }
57 
z_order()58     uint32_t z_order() const {
59       return z_order_;
60     }
61 
buffer()62     buffer_handle_t buffer() {
63       return buffer_;
64     }
set_buffer(buffer_handle_t buffer)65     void set_buffer(buffer_handle_t buffer) {
66       buffer_ = buffer;
67     }
68 
take_acquire_fence()69     int take_acquire_fence() {
70       return acquire_fence_.Release();
71     }
set_acquire_fence(int acquire_fence)72     void set_acquire_fence(int acquire_fence) {
73       acquire_fence_.Set(dup(acquire_fence));
74     }
75 
release_fence()76     int release_fence() {
77       return release_fence_.get();
78     }
take_release_fence()79     int take_release_fence() {
80       return release_fence_.Release();
81     }
manage_release_fence()82     void manage_release_fence() {
83       release_fence_.Set(release_fence_raw_);
84       release_fence_raw_ = -1;
85     }
release_fence_output()86     OutputFd release_fence_output() {
87       return OutputFd(&release_fence_raw_);
88     }
89 
display_frame()90     hwc_rect_t display_frame() {
91       return display_frame_;
92     }
93 
94     void PopulateDrmLayer(DrmHwcLayer *layer);
95 
96     // Layer hooks
97     HWC2::Error SetCursorPosition(int32_t x, int32_t y);
98     HWC2::Error SetLayerBlendMode(int32_t mode);
99     HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
100     HWC2::Error SetLayerColor(hwc_color_t color);
101     HWC2::Error SetLayerCompositionType(int32_t type);
102     HWC2::Error SetLayerDataspace(int32_t dataspace);
103     HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
104     HWC2::Error SetLayerPlaneAlpha(float alpha);
105     HWC2::Error SetLayerSidebandStream(const native_handle_t *stream);
106     HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
107     HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
108     HWC2::Error SetLayerTransform(int32_t transform);
109     HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
110     HWC2::Error SetLayerZOrder(uint32_t z);
111 
112    private:
113     // sf_type_ stores the initial type given to us by surfaceflinger,
114     // validated_type_ stores the type after running ValidateDisplay
115     HWC2::Composition sf_type_ = HWC2::Composition::Invalid;
116     HWC2::Composition validated_type_ = HWC2::Composition::Invalid;
117 
118     HWC2::BlendMode blending_ = HWC2::BlendMode::None;
119     buffer_handle_t buffer_ = NULL;
120     UniqueFd acquire_fence_;
121     int release_fence_raw_ = -1;
122     UniqueFd release_fence_;
123     hwc_rect_t display_frame_;
124     float alpha_ = 1.0f;
125     hwc_frect_t source_crop_;
126     int32_t cursor_x_;
127     int32_t cursor_y_;
128     hwc_color_t layer_color_;
129     HWC2::Transform transform_ = HWC2::Transform::None;
130     uint32_t z_order_ = 0;
131     android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN;
132   };
133 
134   struct HwcCallback {
HwcCallbackHwcCallback135     HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f)
136         : data(d), func(f) {
137     }
138     hwc2_callback_data_t data;
139     hwc2_function_pointer_t func;
140   };
141 
142   class HwcDisplay {
143    public:
144     HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
145                std::shared_ptr<Importer> importer, hwc2_display_t handle,
146                HWC2::DisplayType type);
147     HwcDisplay(const HwcDisplay &) = delete;
148     HWC2::Error Init(std::vector<DrmPlane *> *planes);
149 
150     HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data,
151                                       hwc2_function_pointer_t func);
152     void ClearDisplay();
153 
154     std::string Dump();
155 
156     // HWC Hooks
157     HWC2::Error AcceptDisplayChanges();
158     HWC2::Error CreateLayer(hwc2_layer_t *layer);
159     HWC2::Error DestroyLayer(hwc2_layer_t layer);
160     HWC2::Error GetActiveConfig(hwc2_config_t *config);
161     HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements,
162                                            hwc2_layer_t *layers,
163                                            int32_t *types);
164     HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height,
165                                        int32_t format, int32_t dataspace);
166     HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
167     HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
168                                     int32_t *value);
169     HWC2::Error GetDisplayConfigs(uint32_t *num_configs,
170                                   hwc2_config_t *configs);
171     HWC2::Error GetDisplayName(uint32_t *size, char *name);
172     HWC2::Error GetDisplayRequests(int32_t *display_requests,
173                                    uint32_t *num_elements, hwc2_layer_t *layers,
174                                    int32_t *layer_requests);
175     HWC2::Error GetDisplayType(int32_t *type);
176     HWC2::Error GetDozeSupport(int32_t *support);
177     HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
178                                    float *max_luminance,
179                                    float *max_average_luminance,
180                                    float *min_luminance);
181     HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers,
182                                  int32_t *fences);
183     HWC2::Error PresentDisplay(int32_t *present_fence);
184     HWC2::Error SetActiveConfig(hwc2_config_t config);
185     HWC2::Error ChosePreferredConfig();
186     HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
187                                 int32_t dataspace, hwc_region_t damage);
188     HWC2::Error SetColorMode(int32_t mode);
189     HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
190     HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
191     HWC2::Error SetPowerMode(int32_t mode);
192     HWC2::Error SetVsyncEnabled(int32_t enabled);
193     HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
get_layer(hwc2_layer_t layer)194     HwcLayer *get_layer(hwc2_layer_t layer) {
195       auto it = layers_.find(layer);
196       if (it == layers_.end())
197         return nullptr;
198       return &it->second;
199     }
200 
201    private:
202     HWC2::Error CreateComposition(bool test);
203     void AddFenceToPresentFence(int fd);
204     bool HardwareSupportsLayerType(HWC2::Composition comp_type);
205     uint32_t CalcPixOps(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
206                         size_t first_z, size_t size);
207     void MarkValidated(std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map,
208                        size_t client_first_z, size_t client_size);
209 
210     constexpr static size_t MATRIX_SIZE = 16;
211 
212     ResourceManager *resource_manager_;
213     DrmDevice *drm_;
214     DrmDisplayCompositor compositor_;
215     std::shared_ptr<Importer> importer_;
216     std::unique_ptr<Planner> planner_;
217 
218     std::vector<DrmPlane *> primary_planes_;
219     std::vector<DrmPlane *> overlay_planes_;
220 
221     VSyncWorker vsync_worker_;
222     DrmConnector *connector_ = NULL;
223     DrmCrtc *crtc_ = NULL;
224     hwc2_display_t handle_;
225     HWC2::DisplayType type_;
226     uint32_t layer_idx_ = 0;
227     std::map<hwc2_layer_t, HwcLayer> layers_;
228     HwcLayer client_layer_;
229     UniqueFd present_fence_;
230     int32_t color_mode_;
231     std::array<float, MATRIX_SIZE> color_transform_matrix_;
232     android_color_transform_t color_transform_hint_;
233 
234     uint32_t frame_no_ = 0;
235     /* Statistics */
236     struct Stats {
minusStats237       Stats minus(Stats b) {
238         return {total_frames_ - b.total_frames_,
239                 total_pixops_ - b.total_pixops_, gpu_pixops_ - b.gpu_pixops_,
240                 failed_kms_validate_ - b.failed_kms_validate_,
241                 failed_kms_present_ - b.failed_kms_present_};
242       }
243 
244       uint32_t total_frames_ = 0;
245       uint64_t total_pixops_ = 0;
246       uint64_t gpu_pixops_ = 0;
247       uint32_t failed_kms_validate_ = 0;
248       uint32_t failed_kms_present_ = 0;
249     } total_stats_, prev_stats_;
250     std::string DumpDelta(DrmHwcTwo::HwcDisplay::Stats delta);
251   };
252 
253   class DrmHotplugHandler : public DrmEventHandler {
254    public:
DrmHotplugHandler(DrmHwcTwo * hwc2,DrmDevice * drm)255     DrmHotplugHandler(DrmHwcTwo *hwc2, DrmDevice *drm)
256         : hwc2_(hwc2), drm_(drm) {
257     }
258     void HandleEvent(uint64_t timestamp_us);
259 
260    private:
261     DrmHwcTwo *hwc2_;
262     DrmDevice *drm_;
263   };
264 
toDrmHwcTwo(hwc2_device_t * dev)265   static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
266     return static_cast<DrmHwcTwo *>(dev);
267   }
268 
269   template <typename PFN, typename T>
ToHook(T function)270   static hwc2_function_pointer_t ToHook(T function) {
271     static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
272     return reinterpret_cast<hwc2_function_pointer_t>(function);
273   }
274 
275   template <typename T, typename HookType, HookType func, typename... Args>
DeviceHook(hwc2_device_t * dev,Args...args)276   static T DeviceHook(hwc2_device_t *dev, Args... args) {
277     DrmHwcTwo *hwc = toDrmHwcTwo(dev);
278     return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
279   }
280 
GetDisplay(DrmHwcTwo * hwc,hwc2_display_t display_handle)281   static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
282     auto it = hwc->displays_.find(display_handle);
283     if (it == hwc->displays_.end())
284       return nullptr;
285 
286     return &it->second;
287   }
288 
289   template <typename HookType, HookType func, typename... Args>
DisplayHook(hwc2_device_t * dev,hwc2_display_t display_handle,Args...args)290   static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
291                              Args... args) {
292     HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle);
293     if (!display)
294       return static_cast<int32_t>(HWC2::Error::BadDisplay);
295 
296     return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
297   }
298 
299   template <typename HookType, HookType func, typename... Args>
LayerHook(hwc2_device_t * dev,hwc2_display_t display_handle,hwc2_layer_t layer_handle,Args...args)300   static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
301                            hwc2_layer_t layer_handle, Args... args) {
302     HwcDisplay *display = GetDisplay(toDrmHwcTwo(dev), display_handle);
303     if (!display)
304       return static_cast<int32_t>(HWC2::Error::BadDisplay);
305 
306     HwcLayer *layer = display->get_layer(layer_handle);
307     if (!layer)
308       return static_cast<int32_t>(HWC2::Error::BadLayer);
309 
310     return static_cast<int32_t>((layer->*func)(std::forward<Args>(args)...));
311   }
312 
313   // hwc2_device_t hooks
314   static int HookDevClose(hw_device_t *dev);
315   static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count,
316                                      int32_t *out_capabilities);
317   static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device,
318                                                     int32_t descriptor);
319 
320   // Device functions
321   HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
322                                    int32_t *format, hwc2_display_t *display);
323   HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
324   void Dump(uint32_t *outSize, char *outBuffer);
325   uint32_t GetMaxVirtualDisplayCount();
326   HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
327                                hwc2_function_pointer_t function);
328   HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
329   void HandleDisplayHotplug(hwc2_display_t displayid, int state);
330   void HandleInitialHotplugState(DrmDevice *drmDevice);
331 
332   ResourceManager resource_manager_;
333   std::map<hwc2_display_t, HwcDisplay> displays_;
334   std::map<HWC2::Callback, HwcCallback> callbacks_;
335 
336   std::string mDumpString;
337 };
338 }  // namespace android
339