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