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 "drmresources.h" 20 #include "platform.h" 21 #include "vsyncworker.h" 22 23 #include <hardware/hwcomposer2.h> 24 25 #include <map> 26 27 namespace android { 28 29 class DrmHwcTwo : public hwc2_device_t { 30 public: 31 static int HookDevOpen(const struct hw_module_t *module, const char *name, 32 struct hw_device_t **dev); 33 34 DrmHwcTwo(); 35 36 HWC2::Error Init(); 37 38 private: 39 class HwcLayer { 40 public: sf_type()41 HWC2::Composition sf_type() const { 42 return sf_type_; 43 } validated_type()44 HWC2::Composition validated_type() const { 45 return validated_type_; 46 } accept_type_change()47 void accept_type_change() { 48 sf_type_ = validated_type_; 49 } set_validated_type(HWC2::Composition type)50 void set_validated_type(HWC2::Composition type) { 51 validated_type_ = type; 52 } type_changed()53 bool type_changed() const { 54 return sf_type_ != validated_type_; 55 } 56 z_order()57 uint32_t z_order() const { 58 return z_order_; 59 } 60 buffer()61 buffer_handle_t buffer() { 62 return buffer_; 63 } set_buffer(buffer_handle_t buffer)64 void set_buffer(buffer_handle_t buffer) { 65 buffer_ = buffer; 66 } 67 take_acquire_fence()68 int take_acquire_fence() { 69 return acquire_fence_.Release(); 70 } set_acquire_fence(int acquire_fence)71 void set_acquire_fence(int acquire_fence) { 72 acquire_fence_.Set(dup(acquire_fence)); 73 } 74 release_fence()75 int release_fence() { 76 return release_fence_.get(); 77 } take_release_fence()78 int take_release_fence() { 79 return release_fence_.Release(); 80 } manage_release_fence()81 void manage_release_fence() { 82 release_fence_.Set(release_fence_raw_); 83 release_fence_raw_ = -1; 84 } release_fence_output()85 OutputFd release_fence_output() { 86 return OutputFd(&release_fence_raw_); 87 } 88 89 void PopulateDrmLayer(DrmHwcLayer *layer); 90 91 // Layer hooks 92 HWC2::Error SetCursorPosition(int32_t x, int32_t y); 93 HWC2::Error SetLayerBlendMode(int32_t mode); 94 HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence); 95 HWC2::Error SetLayerColor(hwc_color_t color); 96 HWC2::Error SetLayerCompositionType(int32_t type); 97 HWC2::Error SetLayerDataspace(int32_t dataspace); 98 HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame); 99 HWC2::Error SetLayerPlaneAlpha(float alpha); 100 HWC2::Error SetLayerSidebandStream(const native_handle_t *stream); 101 HWC2::Error SetLayerSourceCrop(hwc_frect_t crop); 102 HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage); 103 HWC2::Error SetLayerTransform(int32_t transform); 104 HWC2::Error SetLayerVisibleRegion(hwc_region_t visible); 105 HWC2::Error SetLayerZOrder(uint32_t z); 106 107 private: 108 // sf_type_ stores the initial type given to us by surfaceflinger, 109 // validated_type_ stores the type after running ValidateDisplay 110 HWC2::Composition sf_type_ = HWC2::Composition::Invalid; 111 HWC2::Composition validated_type_ = HWC2::Composition::Invalid; 112 113 HWC2::BlendMode blending_ = HWC2::BlendMode::None; 114 buffer_handle_t buffer_; 115 UniqueFd acquire_fence_; 116 int release_fence_raw_ = -1; 117 UniqueFd release_fence_; 118 hwc_rect_t display_frame_; 119 float alpha_ = 1.0f; 120 hwc_frect_t source_crop_; 121 int32_t cursor_x_; 122 int32_t cursor_y_; 123 HWC2::Transform transform_ = HWC2::Transform::None; 124 uint32_t z_order_ = 0; 125 android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN; 126 }; 127 128 struct HwcCallback { HwcCallbackHwcCallback129 HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f) 130 : data(d), func(f) { 131 } 132 hwc2_callback_data_t data; 133 hwc2_function_pointer_t func; 134 }; 135 136 class HwcDisplay { 137 public: 138 HwcDisplay(DrmResources *drm, std::shared_ptr<Importer> importer, 139 const gralloc_module_t *gralloc, hwc2_display_t handle, 140 HWC2::DisplayType type); 141 HwcDisplay(const HwcDisplay &) = delete; 142 HWC2::Error Init(std::vector<DrmPlane *> *planes); 143 144 HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data, 145 hwc2_function_pointer_t func); 146 147 // HWC Hooks 148 HWC2::Error AcceptDisplayChanges(); 149 HWC2::Error CreateLayer(hwc2_layer_t *layer); 150 HWC2::Error DestroyLayer(hwc2_layer_t layer); 151 HWC2::Error GetActiveConfig(hwc2_config_t *config); 152 HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements, 153 hwc2_layer_t *layers, 154 int32_t *types); 155 HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, 156 int32_t format, int32_t dataspace); 157 HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes); 158 HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute, 159 int32_t *value); 160 HWC2::Error GetDisplayConfigs(uint32_t *num_configs, 161 hwc2_config_t *configs); 162 HWC2::Error GetDisplayName(uint32_t *size, char *name); 163 HWC2::Error GetDisplayRequests(int32_t *display_requests, 164 uint32_t *num_elements, hwc2_layer_t *layers, 165 int32_t *layer_requests); 166 HWC2::Error GetDisplayType(int32_t *type); 167 HWC2::Error GetDozeSupport(int32_t *support); 168 HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types, 169 float *max_luminance, 170 float *max_average_luminance, 171 float *min_luminance); 172 HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers, 173 int32_t *fences); 174 HWC2::Error PresentDisplay(int32_t *retire_fence); 175 HWC2::Error SetActiveConfig(hwc2_config_t config); 176 HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence, 177 int32_t dataspace, hwc_region_t damage); 178 HWC2::Error SetColorMode(int32_t mode); 179 HWC2::Error SetColorTransform(const float *matrix, int32_t hint); 180 HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence); 181 HWC2::Error SetPowerMode(int32_t mode); 182 HWC2::Error SetVsyncEnabled(int32_t enabled); 183 HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests); get_layer(hwc2_layer_t layer)184 HwcLayer &get_layer(hwc2_layer_t layer) { 185 return layers_.at(layer); 186 } 187 188 private: 189 void AddFenceToRetireFence(int fd); 190 191 DrmResources *drm_; 192 DrmDisplayCompositor compositor_; 193 std::shared_ptr<Importer> importer_; 194 std::unique_ptr<Planner> planner_; 195 const gralloc_module_t *gralloc_; 196 197 std::vector<DrmPlane *> primary_planes_; 198 std::vector<DrmPlane *> overlay_planes_; 199 200 VSyncWorker vsync_worker_; 201 DrmConnector *connector_ = NULL; 202 DrmCrtc *crtc_ = NULL; 203 hwc2_display_t handle_; 204 HWC2::DisplayType type_; 205 uint32_t layer_idx_ = 0; 206 std::map<hwc2_layer_t, HwcLayer> layers_; 207 HwcLayer client_layer_; 208 UniqueFd retire_fence_; 209 UniqueFd next_retire_fence_; 210 int32_t color_mode_; 211 212 uint32_t frame_no_ = 0; 213 }; 214 toDrmHwcTwo(hwc2_device_t * dev)215 static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) { 216 return static_cast<DrmHwcTwo *>(dev); 217 } 218 219 template <typename PFN, typename T> ToHook(T function)220 static hwc2_function_pointer_t ToHook(T function) { 221 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer"); 222 return reinterpret_cast<hwc2_function_pointer_t>(function); 223 } 224 225 template <typename T, typename HookType, HookType func, typename... Args> DeviceHook(hwc2_device_t * dev,Args...args)226 static T DeviceHook(hwc2_device_t *dev, Args... args) { 227 DrmHwcTwo *hwc = toDrmHwcTwo(dev); 228 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...)); 229 } 230 231 template <typename HookType, HookType func, typename... Args> DisplayHook(hwc2_device_t * dev,hwc2_display_t display_handle,Args...args)232 static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle, 233 Args... args) { 234 DrmHwcTwo *hwc = toDrmHwcTwo(dev); 235 HwcDisplay &display = hwc->displays_.at(display_handle); 236 return static_cast<int32_t>((display.*func)(std::forward<Args>(args)...)); 237 } 238 239 template <typename HookType, HookType func, typename... Args> LayerHook(hwc2_device_t * dev,hwc2_display_t display_handle,hwc2_layer_t layer_handle,Args...args)240 static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle, 241 hwc2_layer_t layer_handle, Args... args) { 242 DrmHwcTwo *hwc = toDrmHwcTwo(dev); 243 HwcDisplay &display = hwc->displays_.at(display_handle); 244 HwcLayer &layer = display.get_layer(layer_handle); 245 return static_cast<int32_t>((layer.*func)(std::forward<Args>(args)...)); 246 } 247 248 // hwc2_device_t hooks 249 static int HookDevClose(hw_device_t *dev); 250 static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count, 251 int32_t *out_capabilities); 252 static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device, 253 int32_t descriptor); 254 255 // Device functions 256 HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height, 257 int32_t *format, 258 hwc2_display_t *display); 259 HWC2::Error DestroyVirtualDisplay(hwc2_display_t display); 260 void Dump(uint32_t *size, char *buffer); 261 uint32_t GetMaxVirtualDisplayCount(); 262 HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data, 263 hwc2_function_pointer_t function); 264 265 DrmResources drm_; 266 std::shared_ptr<Importer> importer_; // Shared with HwcDisplay 267 const gralloc_module_t *gralloc_; 268 std::map<hwc2_display_t, HwcDisplay> displays_; 269 std::map<HWC2::Callback, HwcCallback> callbacks_; 270 }; 271 } 272