• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #ifndef ANDROID_HWC_DRMPRESENTER_H
18 #define ANDROID_HWC_DRMPRESENTER_H
19 
20 #include <android-base/unique_fd.h>
21 #include <utils/Thread.h>
22 #include <xf86drm.h>
23 #include <xf86drmMode.h>
24 
25 #include <map>
26 #include <memory>
27 #include <tuple>
28 #include <vector>
29 
30 #include "Common.h"
31 #include "android/base/synchronization/AndroidLock.h"
32 #include "drmhwcgralloc.h"
33 
34 namespace android {
35 
36 class DrmBuffer;
37 class DrmPresenter;
38 
39 // A RAII object that will clear a drm framebuffer upon destruction.
40 class DrmBuffer {
41  public:
42   DrmBuffer(const native_handle_t* handle, DrmPresenter* drmPresenter);
43   ~DrmBuffer();
44 
45   DrmBuffer(const DrmBuffer&) = delete;
46   DrmBuffer& operator=(const DrmBuffer&) = delete;
47 
48   DrmBuffer(DrmBuffer&&) = delete;
49   DrmBuffer& operator=(DrmBuffer&&) = delete;
50 
51   std::tuple<HWC2::Error, base::unique_fd> flushToDisplay(
52       int display, base::borrowed_fd inWaitSyncFd);
53 
54  private:
55   int convertBoInfo(const native_handle_t* handle);
56 
57   DrmPresenter* mDrmPresenter;
58   hwc_drm_bo_t mBo;
59 };
60 
61 class DrmPresenter {
62  public:
63   DrmPresenter() = default;
64   ~DrmPresenter() = default;
65 
66   DrmPresenter(const DrmPresenter&) = delete;
67   DrmPresenter& operator=(const DrmPresenter&) = delete;
68 
69   DrmPresenter(DrmPresenter&&) = delete;
70   DrmPresenter& operator=(DrmPresenter&&) = delete;
71 
72   using HotplugCallback = std::function<void(
73       bool /*connected*/, uint32_t /*id*/, uint32_t /*width*/,
74       uint32_t /*height*/, uint32_t /*dpiX*/, uint32_t /*dpiY*/,
75       uint32_t /*refreshRate*/)>;
76 
77   bool init(const HotplugCallback& cb);
78 
refreshRate(uint32_t display)79   uint32_t refreshRate(uint32_t display) const {
80     if (display < mConnectors.size()) {
81       return mConnectors[display].mRefreshRateAsInteger;
82     }
83 
84     return -1;
85   }
86 
87   std::tuple<HWC2::Error, base::unique_fd> flushToDisplay(
88       int display, hwc_drm_bo_t& fb, base::borrowed_fd inWaitSyncFd);
89 
90   std::optional<std::vector<uint8_t>> getEdid(uint32_t id);
91 
92  private:
93   // Grant visibility for getDrmFB and clearDrmFB to DrmBuffer.
94   friend class DrmBuffer;
95   int getDrmFB(hwc_drm_bo_t& bo);
96   int clearDrmFB(hwc_drm_bo_t& bo);
97 
98   // Grant visibility for handleHotplug to DrmEventListener.
99   bool handleHotplug();
100 
101   bool initDrmElementsLocked();
102   void resetDrmElementsLocked();
103 
104   // Drm device.
105   android::base::unique_fd mFd;
106 
107   HotplugCallback mHotplugCallback;
108 
109   // Protects access to the below drm structs.
110   android::base::guest::ReadWriteLock mStateMutex;
111 
112   struct DrmPlane {
113     uint32_t mId = -1;
114     uint32_t mCrtcPropertyId = -1;
115     uint32_t mInFenceFdPropertyId = -1;
116     uint32_t mFbPropertyId = -1;
117     uint32_t mCrtcXPropertyId = -1;
118     uint32_t mCrtcYPropertyId = -1;
119     uint32_t mCrtcWPropertyId = -1;
120     uint32_t mCrtcHPropertyId = -1;
121     uint32_t mSrcXPropertyId = -1;
122     uint32_t mSrcYPropertyId = -1;
123     uint32_t mSrcWPropertyId = -1;
124     uint32_t mSrcHPropertyId = -1;
125     uint32_t mTypePropertyId = -1;
126     uint64_t mType = -1;
127   };
128   std::map<uint32_t, DrmPlane> mPlanes;
129 
130   struct DrmCrtc {
131     uint32_t mId = -1;
132     uint32_t mActivePropertyId = -1;
133     uint32_t mModePropertyId = -1;
134     uint32_t mOutFencePtrPropertyId = -1;
135     uint32_t mPlaneId = -1;
136 
137     bool mDidSetCrtc = false;
138   };
139   std::vector<DrmCrtc> mCrtcs;
140 
141   struct DrmConnector {
142     uint32_t mId = -1;
143     uint32_t mCrtcPropertyId = -1;
144     drmModeModeInfo mMode;
145     int32_t dpiX;
146     int32_t dpiY;
147     drmModeConnection connection;
148     uint32_t mModeBlobId = 0;
149     float mRefreshRateAsFloat;
150     uint32_t mRefreshRateAsInteger;
151     uint64_t mEdidBlobId = -1;
152   };
153   std::vector<DrmConnector> mConnectors;
154 
155   class DrmEventListener : public Thread {
156    public:
157     DrmEventListener(DrmPresenter& presenter);
158     virtual ~DrmEventListener();
159 
160     bool init();
161 
162    private:
163     bool threadLoop() final;
164     void eventThreadLoop();
165     void processHotplug(uint64_t timestamp);
166 
167     DrmPresenter& mPresenter;
168     android::base::unique_fd mEventFd;
169     int mMaxFd;
170     fd_set mMonitoredFds;
171   };
172   android::sp<DrmEventListener> mDrmEventListener;
173 };
174 
175 }  // namespace android
176 
177 #endif
178