1 /* 2 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. 3 * Not a Contribution. 4 * 5 * Copyright 2015 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 #ifndef __HWC_SESSION_H__ 21 #define __HWC_SESSION_H__ 22 23 #ifdef DISPLAY_CONFIG_1_3 24 #include <vendor/display/config/1.3/IDisplayConfig.h> 25 #elif DISPLAY_CONFIG_1_2 26 #include <vendor/display/config/1.2/IDisplayConfig.h> 27 #elif DISPLAY_CONFIG_1_1 28 #include <vendor/display/config/1.1/IDisplayConfig.h> 29 #else 30 #include <vendor/display/config/1.0/IDisplayConfig.h> 31 #endif 32 33 #include <core/core_interface.h> 34 #include <utils/locker.h> 35 36 #include "hwc_callbacks.h" 37 #include "hwc_layers.h" 38 #include "hwc_display.h" 39 #include "hwc_display_primary.h" 40 #include "hwc_display_external.h" 41 #include "hwc_display_virtual.h" 42 #include "hwc_color_manager.h" 43 #include "hwc_socket_handler.h" 44 45 namespace sdm { 46 47 #ifdef DISPLAY_CONFIG_1_3 48 using vendor::display::config::V1_3::IDisplayConfig; 49 #elif DISPLAY_CONFIG_1_2 50 using vendor::display::config::V1_2::IDisplayConfig; 51 #elif DISPLAY_CONFIG_1_1 52 using vendor::display::config::V1_1::IDisplayConfig; 53 #else 54 using ::vendor::display::config::V1_0::IDisplayConfig; 55 #endif 56 using ::android::hardware::Return; 57 58 // Create a singleton uevent listener thread valid for life of hardware composer process. 59 // This thread blocks on uevents poll inside uevent library implementation. This poll exits 60 // only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle 61 // of this thread with HWC session cause HWC deinitialization to wait infinitely for the 62 // thread to exit. 63 class HWCUEventListener { 64 public: ~HWCUEventListener()65 virtual ~HWCUEventListener() {} 66 virtual void UEventHandler(const char *uevent_data, int length) = 0; 67 }; 68 69 class HWCUEvent { 70 public: 71 HWCUEvent(); 72 static void UEventThread(HWCUEvent *hwc_event); 73 void Register(HWCUEventListener *uevent_listener); InitDone()74 inline bool InitDone() { return init_done_; } 75 76 private: 77 std::mutex mutex_; 78 std::condition_variable caller_cv_; 79 HWCUEventListener *uevent_listener_ = nullptr; 80 bool init_done_ = false; 81 }; 82 83 constexpr int32_t kDataspaceSaturationMatrixCount = 16; 84 constexpr int32_t kDataspaceSaturationPropertyElements = 9; 85 constexpr int32_t kPropertyMax = 256; 86 87 class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient { 88 public: 89 struct HWCModuleMethods : public hw_module_methods_t { HWCModuleMethodsHWCModuleMethods90 HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; } 91 }; 92 93 explicit HWCSession(const hw_module_t *module); 94 int Init(); 95 int Deinit(); 96 HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format); 97 98 template <typename... Args> CallDisplayFunction(hwc2_device_t * device,hwc2_display_t display,HWC2::Error (HWCDisplay::* member)(Args...),Args...args)99 static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display, 100 HWC2::Error (HWCDisplay::*member)(Args...), Args... args) { 101 if (!device) { 102 return HWC2_ERROR_BAD_PARAMETER; 103 } 104 105 if (display >= HWC_NUM_DISPLAY_TYPES) { 106 return HWC2_ERROR_BAD_DISPLAY; 107 } 108 109 SCOPE_LOCK(locker_[display]); 110 HWCSession *hwc_session = static_cast<HWCSession *>(device); 111 auto status = HWC2::Error::BadDisplay; 112 if (hwc_session->hwc_display_[display]) { 113 auto hwc_display = hwc_session->hwc_display_[display]; 114 status = (hwc_display->*member)(std::forward<Args>(args)...); 115 } 116 return INT32(status); 117 } 118 119 template <typename... Args> CallLayerFunction(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,HWC2::Error (HWCLayer::* member)(Args...),Args...args)120 static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display, 121 hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...), 122 Args... args) { 123 if (!device) { 124 return HWC2_ERROR_BAD_PARAMETER; 125 } 126 127 if (display >= HWC_NUM_DISPLAY_TYPES) { 128 return HWC2_ERROR_BAD_DISPLAY; 129 } 130 131 SCOPE_LOCK(locker_[display]); 132 HWCSession *hwc_session = static_cast<HWCSession *>(device); 133 auto status = HWC2::Error::BadDisplay; 134 if (hwc_session->hwc_display_[display]) { 135 status = HWC2::Error::BadLayer; 136 auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer); 137 if (hwc_layer != nullptr) { 138 status = (hwc_layer->*member)(std::forward<Args>(args)...); 139 if (hwc_session->hwc_display_[display]->GetGeometryChanges()) { 140 hwc_session->hwc_display_[display]->ResetValidation(); 141 } 142 } 143 } 144 return INT32(status); 145 } 146 147 // HWC2 Functions that require a concrete implementation in hwc session 148 // and hence need to be member functions 149 static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display); 150 static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display, 151 hwc2_layer_t *out_layer_id); 152 static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height, 153 int32_t *format, hwc2_display_t *out_display_id); 154 static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer); 155 static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display); 156 static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer); 157 static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display, 158 int32_t *out_retire_fence); 159 static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor, 160 hwc2_callback_data_t callback_data, 161 hwc2_function_pointer_t pointer); 162 static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display, 163 buffer_handle_t buffer, int32_t releaseFence); 164 static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode); 165 static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display, 166 uint32_t *out_num_types, uint32_t *out_num_requests); 167 static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display, 168 int32_t /*ColorMode*/ int_mode); 169 static int32_t SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display, 170 int32_t /*ColorMode*/ int_mode, 171 int32_t /*RenderIntent*/ int_render_intent); 172 static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display, 173 const float *matrix, int32_t /*android_color_transform_t*/ hint); 174 static int32_t GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display, 175 int32_t *format, int32_t *dataspace); 176 static int32_t SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t display, 177 const native_handle_t *buffer, int32_t acquire_fence); 178 static int32_t GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display, 179 int32_t *release_fence); 180 static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display, 181 int32_t *out_support); 182 static int32_t GetDisplayCapabilities(hwc2_device_t* device, hwc2_display_t display, 183 uint32_t* outNumCapabilities, uint32_t* outCapabilities); 184 static int32_t SetDisplayBrightness(hwc2_device_t *device, hwc2_display_t display, 185 float brightness); 186 187 static Locker locker_[HWC_NUM_DISPLAY_TYPES]; 188 189 private: 190 static const int kExternalConnectionTimeoutMs = 500; 191 static const int kCommitDoneTimeoutMs = 100; 192 193 // hwc methods 194 static int Open(const hw_module_t *module, const char *name, hw_device_t **device); 195 static int Close(hw_device_t *device); 196 static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount, 197 int32_t *outCapabilities); 198 static int32_t GetDisplayBrightnessSupport(hwc2_device_t *device, hwc2_display_t display, 199 bool *out_support); 200 static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor); 201 202 // Uevent handler 203 virtual void UEventHandler(const char *uevent_data, int length); 204 int GetEventValue(const char *uevent_data, int length, const char *event_info); 205 void HandleExtHPD(const char *uevent_data, int length); 206 int HotPlugHandler(bool connected); 207 void ResetPanel(); 208 int32_t ConnectDisplay(int disp); 209 int DisconnectDisplay(int disp); 210 int GetVsyncPeriod(int disp); 211 int32_t GetConfigCount(int disp_id, uint32_t *count); 212 int32_t GetActiveConfigIndex(int disp_id, uint32_t *config); 213 int32_t SetActiveConfigIndex(int disp_id, uint32_t config); 214 int32_t ControlPartialUpdate(int dpy, bool enable); 215 int32_t DisplayBWTransactionPending(bool *status); 216 int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status); 217 int32_t GetPanelBrightness(int *level); 218 int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level); 219 int32_t CreateExternalDisplay(int disp_id, uint32_t primary_width, uint32_t primary_height, 220 bool use_primary_res); 221 222 // service methods 223 void StartServices(); 224 225 // Methods from ::android::hardware::display::config::V1_0::IDisplayConfig follow. 226 Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy, 227 isDisplayConnected_cb _hidl_cb) override; 228 Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy, 229 IDisplayConfig::DisplayExternalStatus status) override; 230 Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op, 231 uint32_t refreshRate) override; 232 Return<void> getConfigCount(IDisplayConfig::DisplayType dpy, 233 getConfigCount_cb _hidl_cb) override; 234 Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy, 235 getActiveConfig_cb _hidl_cb) override; 236 Return<int32_t> setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) override; 237 Return<void> getDisplayAttributes(uint32_t configIndex, IDisplayConfig::DisplayType dpy, 238 getDisplayAttributes_cb _hidl_cb) override; 239 Return<int32_t> setPanelBrightness(uint32_t level) override; 240 Return<void> getPanelBrightness(getPanelBrightness_cb _hidl_cb) override; 241 Return<int32_t> minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy, 242 uint32_t min_enc_level) override; 243 Return<int32_t> refreshScreen() override; 244 Return<int32_t> controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) override; 245 Return<int32_t> toggleScreenUpdate(bool on) override; 246 Return<int32_t> setIdleTimeout(uint32_t value) override; 247 Return<void> getHDRCapabilities(IDisplayConfig::DisplayType dpy, 248 getHDRCapabilities_cb _hidl_cb) override; 249 Return<int32_t> setCameraLaunchStatus(uint32_t on) override; 250 Return<void> displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) override; 251 #ifdef DISPLAY_CONFIG_1_1 252 Return<int32_t> setDisplayAnimating(uint64_t display_id, bool animating) override; 253 #endif 254 // Methods from ::android::hardware::display::config::V1_2::IDisplayConfig follow. 255 #ifdef DISPLAY_CONFIG_1_2 setDisplayIndex(IDisplayConfig::DisplayTypeExt disp_type,uint32_t base,uint32_t count)256 Return<int32_t> setDisplayIndex(IDisplayConfig::DisplayTypeExt disp_type, 257 uint32_t base, uint32_t count) { return 0; } 258 #endif 259 #ifdef DISPLAY_CONFIG_1_3 260 Return<int32_t> controlIdlePowerCollapse(bool enable, bool synchronous) override; 261 #endif 262 263 // QClient methods 264 virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel, 265 android::Parcel *output_parcel); 266 void DynamicDebug(const android::Parcel *input_parcel); 267 android::status_t SetFrameDumpConfig(const android::Parcel *input_parcel); 268 android::status_t SetMaxMixerStages(const android::Parcel *input_parcel); 269 android::status_t SetDisplayMode(const android::Parcel *input_parcel); 270 android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel); 271 android::status_t QdcmCMDHandler(const android::Parcel *input_parcel, 272 android::Parcel *output_parcel); 273 android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel, 274 android::Parcel *output_parcel); 275 android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel, 276 android::Parcel *output_parcel); 277 android::status_t SetMixerResolution(const android::Parcel *input_parcel); 278 android::status_t SetColorModeOverride(const android::Parcel *input_parcel); 279 android::status_t SetColorModeWithRenderIntentOverride(const android::Parcel *input_parcel); 280 android::status_t SetWhiteCompensation(const android::Parcel *input_parcel); 281 282 android::status_t SetColorModeById(const android::Parcel *input_parcel); 283 android::status_t getComposerStatus(); 284 android::status_t SetIdlePC(const android::Parcel *input_parcel); 285 286 android::status_t setColorSamplingEnabled(const android::Parcel *input_parcel); 287 288 void Refresh(hwc2_display_t display); 289 void HotPlug(hwc2_display_t display, HWC2::Connection state); 290 HWC2::Error ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types, 291 uint32_t *out_num_requests); 292 HWC2::Error PresentDisplayInternal(hwc2_display_t display, int32_t *out_retire_fence); 293 294 CoreInterface *core_intf_ = nullptr; 295 HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr}; 296 HWCCallbacks callbacks_; 297 HWCBufferAllocator buffer_allocator_; 298 HWCBufferSyncHandler buffer_sync_handler_; 299 HWCColorManager *color_mgr_ = nullptr; 300 bool reset_panel_ = false; 301 bool secure_display_active_ = false; 302 bool external_pending_connect_ = false; 303 bool new_bw_mode_ = false; 304 bool need_invalidate_ = false; 305 int bw_mode_release_fd_ = -1; 306 qService::QService *qservice_ = nullptr; 307 HWCSocketHandler socket_handler_; 308 bool hdmi_is_primary_ = false; 309 bool is_composer_up_ = false; 310 Locker callbacks_lock_; 311 int hpd_bpp_ = 0; 312 int hpd_pattern_ = 0; 313 uint32_t idle_pc_ref_cnt_ = 0; 314 int brightness_fd_ = -1; 315 }; 316 317 } // namespace sdm 318 319 #endif // __HWC_SESSION_H__ 320