• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 <cutils/native_handle.h>
22 #include <utils/Thread.h>
23 #include <xf86drm.h>
24 #include <xf86drmMode.h>
25 
26 #include <map>
27 #include <memory>
28 #include <tuple>
29 #include <vector>
30 
31 #include "Common.h"
32 #include "LruCache.h"
33 #include "android/base/synchronization/AndroidLock.h"
34 
35 namespace aidl::android::hardware::graphics::composer3::impl {
36 
37 class DrmBuffer;
38 class DrmPresenter;
39 
40 // A RAII object that will clear a drm framebuffer upon destruction.
41 class DrmBuffer {
42  public:
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  private:
52   friend class DrmPresenter;
53   DrmBuffer(DrmPresenter& drmPresenter);
54 
55   DrmPresenter& mDrmPresenter;
56 
57   uint32_t mWidth = 0;
58   uint32_t mHeight = 0;
59   uint32_t mDrmFormat = 0;
60   uint32_t mPlaneFds[4] = {0, 0, 0, 0};
61   uint32_t mPlaneHandles[4] = {0, 0, 0, 0};
62   uint32_t mPlanePitches[4] = {0, 0, 0, 0};
63   uint32_t mPlaneOffsets[4] = {0, 0, 0, 0};
64   std::optional<uint32_t> mDrmFramebuffer;
65 };
66 
67 class DrmPresenter {
68  public:
69   DrmPresenter() = default;
70   ~DrmPresenter();
71 
72   DrmPresenter(const DrmPresenter&) = delete;
73   DrmPresenter& operator=(const DrmPresenter&) = delete;
74 
75   DrmPresenter(DrmPresenter&&) = delete;
76   DrmPresenter& operator=(DrmPresenter&&) = delete;
77 
78   HWC3::Error init();
79 
80   struct DisplayConfig {
81     uint32_t id;
82     uint32_t width;
83     uint32_t height;
84     uint32_t dpiX;
85     uint32_t dpiY;
86     uint32_t refreshRateHz;
87   };
88 
89   HWC3::Error getDisplayConfigs(std::vector<DisplayConfig>* configs) const;
90 
91   using HotplugCallback = std::function<void(bool /*connected*/,   //
92                                              uint32_t /*id*/,      //
93                                              uint32_t /*width*/,   //
94                                              uint32_t /*height*/,  //
95                                              uint32_t /*dpiX*/,    //
96                                              uint32_t /*dpiY*/,    //
97                                              uint32_t /*refreshRate*/)>;
98 
99   HWC3::Error registerOnHotplugCallback(const HotplugCallback& cb);
100   HWC3::Error unregisterOnHotplugCallback();
101 
refreshRate()102   uint32_t refreshRate() const { return mConnectors[0].mRefreshRateAsInteger; }
103 
104   std::tuple<HWC3::Error, std::shared_ptr<DrmBuffer>> create(
105       const native_handle_t* handle);
106 
107   std::tuple<HWC3::Error, ::android::base::unique_fd> flushToDisplay(
108       int display, const DrmBuffer& buffer,
109       ::android::base::borrowed_fd inWaitSyncFd);
110 
111   std::optional<std::vector<uint8_t>> getEdid(uint32_t id);
112 
113  private:
114   // TODO: make this cache per display when enabling hotplug support.
115   using DrmPrimeBufferHandle = uint32_t;
116   using DrmBufferCache = LruCache<DrmPrimeBufferHandle, std::shared_ptr<DrmBuffer>>;
117   std::unique_ptr<DrmBufferCache> mBufferCache;
118 
119   // Grant visibility to destroyDrmFramebuffer to DrmBuffer.
120   friend class DrmBuffer;
121   HWC3::Error destroyDrmFramebuffer(DrmBuffer* buffer);
122 
123   // Grant visibility for handleHotplug to DrmEventListener.
124   bool handleHotplug();
125 
126   bool initDrmElementsLocked();
127   void resetDrmElementsLocked();
128 
129   // Drm device.
130   ::android::base::unique_fd mFd;
131 
132   std::optional<HotplugCallback> mHotplugCallback;
133 
134   // Protects access to the below drm structs.
135   mutable ::android::base::guest::ReadWriteLock mStateMutex;
136 
137   struct DrmPlane {
138     uint32_t mId = -1;
139     uint32_t mCrtcPropertyId = -1;
140     uint32_t mInFenceFdPropertyId = -1;
141     uint32_t mFbPropertyId = -1;
142     uint32_t mCrtcXPropertyId = -1;
143     uint32_t mCrtcYPropertyId = -1;
144     uint32_t mCrtcWPropertyId = -1;
145     uint32_t mCrtcHPropertyId = -1;
146     uint32_t mSrcXPropertyId = -1;
147     uint32_t mSrcYPropertyId = -1;
148     uint32_t mSrcWPropertyId = -1;
149     uint32_t mSrcHPropertyId = -1;
150     uint32_t mTypePropertyId = -1;
151     uint64_t mType = -1;
152   };
153   std::map<uint32_t, DrmPlane> mPlanes;
154 
155   struct DrmCrtc {
156     uint32_t mId = -1;
157     uint32_t mActivePropertyId = -1;
158     uint32_t mModePropertyId = -1;
159     uint32_t mOutFencePtrPropertyId = -1;
160     uint32_t mPlaneId = -1;
161 
162     bool mDidSetCrtc = false;
163   };
164   std::vector<DrmCrtc> mCrtcs;
165 
166   struct DrmConnector {
167     uint32_t mId = -1;
168     uint32_t mCrtcPropertyId = -1;
169     drmModeModeInfo mMode;
170     int32_t dpiX;
171     int32_t dpiY;
172     drmModeConnection connection;
173     uint32_t mModeBlobId = 0;
174     float mRefreshRateAsFloat;
175     uint32_t mRefreshRateAsInteger;
176     uint64_t mEdidBlobId = -1;
177   };
178   std::vector<DrmConnector> mConnectors;
179 
180   class DrmEventListener : public ::android::Thread {
181    public:
182     DrmEventListener(DrmPresenter& presenter);
183     virtual ~DrmEventListener();
184 
185     bool init();
186 
187    private:
188     bool threadLoop() final;
189     void eventThreadLoop();
190     void processHotplug(uint64_t timestamp);
191 
192     DrmPresenter& mPresenter;
193     ::android::base::unique_fd mEventFd;
194     int mMaxFd;
195     fd_set mMonitoredFds;
196   };
197   ::android::sp<DrmEventListener> mDrmEventListener;
198 };
199 
200 }  // namespace aidl::android::hardware::graphics::composer3::impl
201 
202 #endif
203