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 dpi; 36 uint32_t flag; 37 uint32_t cb; 38 bool enabled; MultiDisplayInfoMultiDisplayInfo39 MultiDisplayInfo() : 40 pos_x(0), pos_y(0), width(0), height(0), dpi(0), flag(0), cb(0), enabled(true) {} 41 MultiDisplayInfo(int32_t x, int32_t y, uint32_t w, uint32_t h, 42 uint32_t d, uint32_t f, bool e, uint32_t c = 0) : pos_xMultiDisplayInfo43 pos_x(x), pos_y(y), width(w), height(h), dpi(d), flag(f), enabled(e), cb(c) {} 44 45 }; 46 47 enum class DisplayChange { 48 DisplayChanged = 0, 49 DisplayAdded, 50 DisplayRemoved, 51 DisplayTransactionCompleted, 52 }; 53 54 struct DisplayChangeEvent { 55 DisplayChange change; 56 uint32_t displayId; 57 }; 58 59 class MultiDisplay : public base::EventNotificationSupport<DisplayChangeEvent> { 60 public: 61 MultiDisplay(const QAndroidEmulatorWindowAgent* const windowAgent, 62 const QAndroidRecordScreenAgent* const recordAgent, 63 const QAndroidVmOperations* const vmAgent, 64 bool isGuestMode); 65 static MultiDisplay* getInstance(); isMultiDisplayEnabled()66 bool isMultiDisplayEnabled() { base::AutoLock lock(mLock); return mMultiDisplay.size() > 1; } 67 int setMultiDisplay(uint32_t id, 68 int32_t x, 69 int32_t y, 70 uint32_t w, 71 uint32_t h, 72 uint32_t dpi, 73 uint32_t flag, 74 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)75 bool getMultiDisplay(uint32_t id, 76 int32_t* x, 77 int32_t* y, 78 uint32_t* width, 79 uint32_t* height, 80 uint32_t* dpi, 81 uint32_t* flag, 82 bool* enabled) { 83 return getMultiDisplay(id, x, y, width, height, dpi, flag, nullptr, enabled); 84 } 85 bool getNextMultiDisplay(int32_t start_id, 86 uint32_t* id, 87 int32_t* x, 88 int32_t* y, 89 uint32_t* w, 90 uint32_t* h, 91 uint32_t* dpi, 92 uint32_t* flag, 93 uint32_t* cb); 94 bool multiDisplayParamValidate(uint32_t id, uint32_t w, uint32_t h, 95 uint32_t dpi, uint32_t flag); 96 bool translateCoordination(uint32_t* x, uint32_t* y, uint32_t* displayId); 97 void setGpuMode(bool isGuestMode, uint32_t w, uint32_t h); 98 int createDisplay(uint32_t* displayId); 99 int setDisplayPose(uint32_t displayId, 100 int32_t x, 101 int32_t y, 102 uint32_t w, 103 uint32_t h, 104 uint32_t dpi, 105 uint32_t flag); 106 int destroyDisplay(uint32_t displayId); 107 int getDisplayPose(uint32_t displayId, 108 int32_t* x, 109 int32_t* y, 110 uint32_t* w, 111 uint32_t* h); 112 int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer); 113 int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId); 114 int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer); 115 void getCombinedDisplaySize(uint32_t* w, uint32_t* h); 116 bool isMultiDisplayWindow(); 117 void loadConfig(); 118 void onSave(base::Stream* stream); 119 void onLoad(base::Stream* stream); 120 121 bool notifyDisplayChanges(); 122 123 // 0 for default Android display 124 // 1-5 for Emulator UI 125 // 6-10 for developer from rcControl 126 static const uint32_t s_displayIdInternalBegin = 6; 127 static const uint32_t s_maxNumMultiDisplay = 11; 128 static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB; 129 130 private: 131 const QAndroidEmulatorWindowAgent* mWindowAgent; 132 const QAndroidRecordScreenAgent* mRecordAgent; 133 const QAndroidVmOperations* mVmAgent; 134 bool mGuestMode; 135 std::map<uint32_t, MultiDisplayInfo> mMultiDisplay; 136 android::base::Lock mLock; 137 138 void recomputeLayoutLocked(); 139 void getCombinedDisplaySizeLocked(uint32_t* w, uint32_t* h); 140 bool getMultiDisplay(uint32_t id, 141 int32_t* x, 142 int32_t* y, 143 uint32_t* width, 144 uint32_t* height, 145 uint32_t* dpi, 146 uint32_t* flag, 147 uint32_t* cb, 148 bool* enabled); 149 int getNumberActiveMultiDisplaysLocked(); 150 151 std::map<uint32_t, MultiDisplayInfo> parseConfig(); 152 bool hotPlugDisplayEnabled(); 153 }; 154 } // namespace android 155 156 void android_init_multi_display(const QAndroidEmulatorWindowAgent* const windowAgent, 157 const QAndroidRecordScreenAgent* const recordAgent, 158 const QAndroidVmOperations* const vmAgent, 159 bool isGUestMode = false); 160