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