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