1 /* 2 * Copyright (C) 2020 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 #pragma once 18 19 #include "aemu/base/EventNotificationSupport.h" 20 #include "aemu/base/files/Stream.h" 21 #include "aemu/base/synchronization/Lock.h" 22 #include "host-common/record_screen_agent.h" 23 #include "host-common/vm_operations.h" 24 #include "host-common/window_agent.h" 25 26 #include <map> 27 28 namespace android { 29 30 struct MultiDisplayInfo { 31 int32_t pos_x; 32 int32_t pos_y; 33 uint32_t width; 34 uint32_t height; 35 uint32_t originalWidth; 36 uint32_t originalHeight; 37 uint32_t dpi; 38 uint32_t flag; 39 uint32_t cb; 40 int32_t rotation; 41 bool enabled; MultiDisplayInfoMultiDisplayInfo42 MultiDisplayInfo() : 43 pos_x(0), pos_y(0), width(0), height(0), originalWidth(0), 44 originalHeight(0), dpi(0), flag(0), cb(0), rotation(0), enabled(true) {} 45 MultiDisplayInfo(int32_t x, int32_t y, uint32_t w, uint32_t h, 46 uint32_t d, uint32_t f, bool e, uint32_t c = 0) : pos_xMultiDisplayInfo47 pos_x(x), pos_y(y), width(w), height(h), originalWidth(w), 48 originalHeight(h), dpi(d), flag(f), rotation(0), enabled(e), cb(c) {} 49 50 }; 51 52 enum class DisplayChange { 53 DisplayChanged = 0, 54 DisplayAdded, 55 DisplayRemoved, 56 DisplayTransactionCompleted, 57 }; 58 59 struct DisplayChangeEvent { 60 DisplayChange change; 61 uint32_t displayId; 62 }; 63 64 class MultiDisplay : public base::EventNotificationSupport<DisplayChangeEvent> { 65 public: 66 MultiDisplay(const QAndroidEmulatorWindowAgent* const windowAgent, 67 const QAndroidRecordScreenAgent* const recordAgent, 68 const QAndroidVmOperations* const vmAgent, 69 bool isGuestMode); 70 static MultiDisplay* getInstance(); isMultiDisplayEnabled()71 bool isMultiDisplayEnabled() { base::AutoLock lock(mLock); return mMultiDisplay.size() > 1; } 72 int setMultiDisplay(uint32_t id, 73 int32_t x, 74 int32_t y, 75 uint32_t w, 76 uint32_t h, 77 uint32_t dpi, 78 uint32_t flag, 79 bool add); getMultiDisplay(uint32_t id,int32_t * x,int32_t * y,uint32_t * width,uint32_t * height,uint32_t * dpi,uint32_t * flag,bool * enabled)80 bool getMultiDisplay(uint32_t id, 81 int32_t* x, 82 int32_t* y, 83 uint32_t* width, 84 uint32_t* height, 85 uint32_t* dpi, 86 uint32_t* flag, 87 bool* enabled) { 88 return getMultiDisplay(id, x, y, width, height, dpi, flag, nullptr, enabled); 89 } 90 bool getNextMultiDisplay(int32_t start_id, 91 uint32_t* id, 92 int32_t* x, 93 int32_t* y, 94 uint32_t* w, 95 uint32_t* h, 96 uint32_t* dpi, 97 uint32_t* flag, 98 uint32_t* cb); 99 bool multiDisplayParamValidate(uint32_t id, uint32_t w, uint32_t h, 100 uint32_t dpi, uint32_t flag); 101 bool translateCoordination(uint32_t* x, uint32_t* y, uint32_t* displayId); 102 void setGpuMode(bool isGuestMode, uint32_t w, uint32_t h); 103 int createDisplay(uint32_t* displayId); 104 int setDisplayPose(uint32_t displayId, 105 int32_t x, 106 int32_t y, 107 uint32_t w, 108 uint32_t h, 109 uint32_t dpi, 110 uint32_t flag); 111 int destroyDisplay(uint32_t displayId); 112 int getDisplayPose(uint32_t displayId, 113 int32_t* x, 114 int32_t* y, 115 uint32_t* w, 116 uint32_t* h); 117 int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer); 118 int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId); 119 int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer); 120 void getCombinedDisplaySize(uint32_t* w, uint32_t* h); 121 bool isMultiDisplayWindow(); 122 bool isPixelFold(); 123 void loadConfig(); 124 void onSave(base::Stream* stream); 125 void onLoad(base::Stream* stream); 126 void performRotation(int rot); 127 128 bool notifyDisplayChanges(); 129 bool isOrientationSupported(); 130 131 // 0 for default Android display 132 // 1-5 for Emulator UI 133 // 6-10 for developer from rcControl 134 static constexpr uint32_t s_displayIdInternalBegin = 6; 135 static constexpr uint32_t s_maxNumMultiDisplay = 11; 136 static constexpr uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB; 137 138 private: 139 const QAndroidEmulatorWindowAgent* mWindowAgent; 140 const QAndroidRecordScreenAgent* mRecordAgent; 141 const QAndroidVmOperations* mVmAgent; 142 bool mGuestMode; 143 int32_t mRotation { 0 }; 144 std::map<uint32_t, MultiDisplayInfo> mMultiDisplay; 145 android::base::Lock mLock; 146 147 void performRotationLocked(int rot); 148 void recomputeLayoutLocked(); 149 void recomputeStackedLayoutLocked(); 150 void getCombinedDisplaySizeLocked(uint32_t* w, uint32_t* h); 151 bool getMultiDisplay(uint32_t id, 152 int32_t* x, 153 int32_t* y, 154 uint32_t* width, 155 uint32_t* height, 156 uint32_t* dpi, 157 uint32_t* flag, 158 uint32_t* cb, 159 bool* enabled); 160 int getNumberActiveMultiDisplaysLocked(); 161 162 std::map<uint32_t, MultiDisplayInfo> parseConfig(); 163 bool hotPlugDisplayEnabled(); 164 }; 165 } // namespace android 166 167 void android_init_multi_display(const QAndroidEmulatorWindowAgent* const windowAgent, 168 const QAndroidRecordScreenAgent* const recordAgent, 169 const QAndroidVmOperations* const vmAgent, 170 bool isGUestMode = false); 171