1 /* 2 * Copyright (c) 2014-2017, 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_1 24 #include <vendor/display/config/1.1/IDisplayConfig.h> 25 #else 26 #include <vendor/display/config/1.0/IDisplayConfig.h> 27 #endif 28 29 #include <core/core_interface.h> 30 #include <utils/locker.h> 31 32 #include "hwc_callbacks.h" 33 #include "hwc_layers.h" 34 #include "hwc_display.h" 35 #include "hwc_display_primary.h" 36 #include "hwc_display_external.h" 37 #include "hwc_display_virtual.h" 38 #include "hwc_color_manager.h" 39 #include "hwc_socket_handler.h" 40 41 namespace sdm { 42 43 #ifdef DISPLAY_CONFIG_1_1 44 using vendor::display::config::V1_1::IDisplayConfig; 45 #else 46 using ::vendor::display::config::V1_0::IDisplayConfig; 47 #endif 48 using ::android::hardware::Return; 49 50 // Create a singleton uevent listener thread valid for life of hardware composer process. 51 // This thread blocks on uevents poll inside uevent library implementation. This poll exits 52 // only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle 53 // of this thread with HWC session cause HWC deinitialization to wait infinitely for the 54 // thread to exit. 55 class HWCUEventListener { 56 public: ~HWCUEventListener()57 virtual ~HWCUEventListener() {} 58 virtual void UEventHandler(const char *uevent_data, int length) = 0; 59 }; 60 61 class HWCUEvent { 62 public: 63 HWCUEvent(); 64 static void UEventThread(HWCUEvent *hwc_event); 65 void Register(HWCUEventListener *uevent_listener); InitDone()66 inline bool InitDone() { return init_done_; } 67 68 private: 69 std::mutex mutex_; 70 std::condition_variable caller_cv_; 71 HWCUEventListener *uevent_listener_ = nullptr; 72 bool init_done_ = false; 73 }; 74 75 class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient { 76 public: 77 struct HWCModuleMethods : public hw_module_methods_t { HWCModuleMethodsHWCModuleMethods78 HWCModuleMethods() { hw_module_methods_t::open = HWCSession::Open; } 79 }; 80 81 explicit HWCSession(const hw_module_t *module); 82 int Init(); 83 int Deinit(); 84 HWC2::Error CreateVirtualDisplayObject(uint32_t width, uint32_t height, int32_t *format); 85 86 template <typename... Args> CallDisplayFunction(hwc2_device_t * device,hwc2_display_t display,HWC2::Error (HWCDisplay::* member)(Args...),Args...args)87 static int32_t CallDisplayFunction(hwc2_device_t *device, hwc2_display_t display, 88 HWC2::Error (HWCDisplay::*member)(Args...), Args... args) { 89 if (!device) { 90 return HWC2_ERROR_BAD_PARAMETER; 91 } 92 93 if (display >= HWC_NUM_DISPLAY_TYPES) { 94 return HWC2_ERROR_BAD_DISPLAY; 95 } 96 97 SCOPE_LOCK(locker_[display]); 98 HWCSession *hwc_session = static_cast<HWCSession *>(device); 99 auto status = HWC2::Error::BadDisplay; 100 if (hwc_session->hwc_display_[display]) { 101 auto hwc_display = hwc_session->hwc_display_[display]; 102 status = (hwc_display->*member)(std::forward<Args>(args)...); 103 } 104 return INT32(status); 105 } 106 107 template <typename... Args> CallLayerFunction(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,HWC2::Error (HWCLayer::* member)(Args...),Args...args)108 static int32_t CallLayerFunction(hwc2_device_t *device, hwc2_display_t display, 109 hwc2_layer_t layer, HWC2::Error (HWCLayer::*member)(Args...), 110 Args... args) { 111 if (!device) { 112 return HWC2_ERROR_BAD_DISPLAY; 113 } 114 115 SCOPE_LOCK(locker_[display]); 116 HWCSession *hwc_session = static_cast<HWCSession *>(device); 117 auto status = HWC2::Error::BadDisplay; 118 if (hwc_session->hwc_display_[display]) { 119 status = HWC2::Error::BadLayer; 120 auto hwc_layer = hwc_session->hwc_display_[display]->GetHWCLayer(layer); 121 if (hwc_layer != nullptr) { 122 status = (hwc_layer->*member)(std::forward<Args>(args)...); 123 if (hwc_session->hwc_display_[display]->GetGeometryChanges()) { 124 hwc_session->hwc_display_[display]->ResetValidation(); 125 } 126 } 127 } 128 return INT32(status); 129 } 130 131 // HWC2 Functions that require a concrete implementation in hwc session 132 // and hence need to be member functions 133 static int32_t AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display); 134 static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display, 135 hwc2_layer_t *out_layer_id); 136 static int32_t CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height, 137 int32_t *format, hwc2_display_t *out_display_id); 138 static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer); 139 static int32_t DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display); 140 static void Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer); 141 static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display, 142 int32_t *out_retire_fence); 143 static int32_t RegisterCallback(hwc2_device_t *device, int32_t descriptor, 144 hwc2_callback_data_t callback_data, 145 hwc2_function_pointer_t pointer); 146 static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display, 147 buffer_handle_t buffer, int32_t releaseFence); 148 static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode); 149 static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display, 150 uint32_t *out_num_types, uint32_t *out_num_requests); 151 static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display, 152 int32_t /*android_color_mode_t*/ int_mode); 153 static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display, 154 const float *matrix, int32_t /*android_color_transform_t*/ hint); 155 156 private: 157 static const int kExternalConnectionTimeoutMs = 500; 158 static const int kPartialUpdateControlTimeoutMs = 100; 159 static bool disable_skip_validate_; 160 161 // hwc methods 162 static int Open(const hw_module_t *module, const char *name, hw_device_t **device); 163 static int Close(hw_device_t *device); 164 static void GetCapabilities(struct hwc2_device *device, uint32_t *outCount, 165 int32_t *outCapabilities); 166 static hwc2_function_pointer_t GetFunction(struct hwc2_device *device, int32_t descriptor); 167 168 // Uevent handler 169 virtual void UEventHandler(const char *uevent_data, int length); 170 int GetEventValue(const char *uevent_data, int length, const char *event_info); 171 int HotPlugHandler(bool connected); 172 void ResetPanel(); 173 int32_t ConnectDisplay(int disp); 174 int DisconnectDisplay(int disp); 175 int GetVsyncPeriod(int disp); 176 int32_t GetConfigCount(int disp_id, uint32_t *count); 177 int32_t GetActiveConfigIndex(int disp_id, uint32_t *config); 178 int32_t SetActiveConfigIndex(int disp_id, uint32_t config); 179 int32_t ControlPartialUpdate(int dpy, bool enable); 180 int32_t DisplayBWTransactionPending(bool *status); 181 int32_t SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status); 182 int32_t GetPanelBrightness(int *level); 183 int32_t MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level); 184 int32_t CreateExternalDisplay(int disp, uint32_t primary_width = 0, 185 uint32_t primary_height = 0, 186 bool use_primary_res = false); 187 188 // service methods 189 void StartServices(); 190 191 // Methods from ::android::hardware::display::config::V1_0::IDisplayConfig follow. 192 Return<void> isDisplayConnected(IDisplayConfig::DisplayType dpy, 193 isDisplayConnected_cb _hidl_cb) override; 194 Return<int32_t> setSecondayDisplayStatus(IDisplayConfig::DisplayType dpy, 195 IDisplayConfig::DisplayExternalStatus status) override; 196 Return<int32_t> configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op, 197 uint32_t refreshRate) override; 198 Return<void> getConfigCount(IDisplayConfig::DisplayType dpy, 199 getConfigCount_cb _hidl_cb) override; 200 Return<void> getActiveConfig(IDisplayConfig::DisplayType dpy, 201 getActiveConfig_cb _hidl_cb) override; 202 Return<int32_t> setActiveConfig(IDisplayConfig::DisplayType dpy, uint32_t config) override; 203 Return<void> getDisplayAttributes(uint32_t configIndex, IDisplayConfig::DisplayType dpy, 204 getDisplayAttributes_cb _hidl_cb) override; 205 Return<int32_t> setPanelBrightness(uint32_t level) override; 206 Return<void> getPanelBrightness(getPanelBrightness_cb _hidl_cb) override; 207 Return<int32_t> minHdcpEncryptionLevelChanged(IDisplayConfig::DisplayType dpy, 208 uint32_t min_enc_level) override; 209 Return<int32_t> refreshScreen() override; 210 Return<int32_t> controlPartialUpdate(IDisplayConfig::DisplayType dpy, bool enable) override; 211 Return<int32_t> toggleScreenUpdate(bool on) override; 212 Return<int32_t> setIdleTimeout(uint32_t value) override; 213 Return<void> getHDRCapabilities(IDisplayConfig::DisplayType dpy, 214 getHDRCapabilities_cb _hidl_cb) override; 215 Return<int32_t> setCameraLaunchStatus(uint32_t on) override; 216 Return<void> displayBWTransactionPending(displayBWTransactionPending_cb _hidl_cb) override; 217 218 // Methods from ::android::hardware::display::config::V1_1::IDisplayConfig follow. 219 #ifdef DISPLAY_CONFIG_1_1 220 Return<int32_t> setDisplayAnimating(uint64_t display_id, bool animating) override; 221 #endif 222 223 // QClient methods 224 virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel, 225 android::Parcel *output_parcel); 226 void DynamicDebug(const android::Parcel *input_parcel); 227 void SetFrameDumpConfig(const android::Parcel *input_parcel); 228 android::status_t SetMaxMixerStages(const android::Parcel *input_parcel); 229 android::status_t SetDisplayMode(const android::Parcel *input_parcel); 230 android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel); 231 android::status_t QdcmCMDHandler(const android::Parcel *input_parcel, 232 android::Parcel *output_parcel); 233 android::status_t HandleGetDisplayAttributesForConfig(const android::Parcel *input_parcel, 234 android::Parcel *output_parcel); 235 android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel, 236 android::Parcel *output_parcel); 237 android::status_t SetMixerResolution(const android::Parcel *input_parcel); 238 android::status_t SetColorModeOverride(const android::Parcel *input_parcel); 239 240 void Refresh(hwc2_display_t display); 241 void HotPlug(hwc2_display_t display, HWC2::Connection state); 242 243 static Locker locker_[HWC_NUM_DISPLAY_TYPES]; 244 CoreInterface *core_intf_ = nullptr; 245 HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr}; 246 HWCCallbacks callbacks_; 247 HWCBufferAllocator buffer_allocator_; 248 HWCBufferSyncHandler buffer_sync_handler_; 249 HWCColorManager *color_mgr_ = nullptr; 250 bool reset_panel_ = false; 251 bool secure_display_active_ = false; 252 bool external_pending_connect_ = false; 253 bool new_bw_mode_ = false; 254 bool need_invalidate_ = false; 255 int bw_mode_release_fd_ = -1; 256 qService::QService *qservice_ = nullptr; 257 HWCSocketHandler socket_handler_; 258 bool hdmi_is_primary_ = false; 259 Locker callbacks_lock_; 260 }; 261 262 } // namespace sdm 263 264 #endif // __HWC_SESSION_H__ 265