| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include "aemu/base/EventNotificationSupport.h" |
| #include "aemu/base/files/Stream.h" |
| #include "aemu/base/synchronization/Lock.h" |
| #include "host-common/record_screen_agent.h" |
| #include "host-common/vm_operations.h" |
| #include "host-common/window_agent.h" |
| |
| #include <map> |
| |
| namespace android { |
| |
| struct MultiDisplayInfo { |
| int32_t pos_x; |
| int32_t pos_y; |
| uint32_t width; |
| uint32_t height; |
| uint32_t originalWidth; |
| uint32_t originalHeight; |
| uint32_t dpi; |
| uint32_t flag; |
| uint32_t cb; |
| int32_t rotation; |
| bool enabled; |
| MultiDisplayInfo() : |
| pos_x(0), pos_y(0), width(0), height(0), originalWidth(0), |
| originalHeight(0), dpi(0), flag(0), cb(0), rotation(0), enabled(true) {} |
| MultiDisplayInfo(int32_t x, int32_t y, uint32_t w, uint32_t h, |
| uint32_t d, uint32_t f, bool e, uint32_t c = 0) : |
| pos_x(x), pos_y(y), width(w), height(h), originalWidth(w), |
| originalHeight(h), dpi(d), flag(f), rotation(0), enabled(e), cb(c) {} |
| |
| }; |
| |
| enum class DisplayChange { |
| DisplayChanged = 0, |
| DisplayAdded, |
| DisplayRemoved, |
| DisplayTransactionCompleted, |
| }; |
| |
| struct DisplayChangeEvent { |
| DisplayChange change; |
| uint32_t displayId; |
| }; |
| |
| class MultiDisplay : public base::EventNotificationSupport<DisplayChangeEvent> { |
| public: |
| MultiDisplay(const QAndroidEmulatorWindowAgent* const windowAgent, |
| const QAndroidRecordScreenAgent* const recordAgent, |
| const QAndroidVmOperations* const vmAgent, |
| bool isGuestMode); |
| static MultiDisplay* getInstance(); |
| bool isMultiDisplayEnabled() { base::AutoLock lock(mLock); return mMultiDisplay.size() > 1; } |
| int setMultiDisplay(uint32_t id, |
| int32_t x, |
| int32_t y, |
| uint32_t w, |
| uint32_t h, |
| uint32_t dpi, |
| uint32_t flag, |
| bool add); |
| bool getMultiDisplay(uint32_t id, |
| int32_t* x, |
| int32_t* y, |
| uint32_t* width, |
| uint32_t* height, |
| uint32_t* dpi, |
| uint32_t* flag, |
| bool* enabled) { |
| return getMultiDisplay(id, x, y, width, height, dpi, flag, nullptr, enabled); |
| } |
| bool getNextMultiDisplay(int32_t start_id, |
| uint32_t* id, |
| int32_t* x, |
| int32_t* y, |
| uint32_t* w, |
| uint32_t* h, |
| uint32_t* dpi, |
| uint32_t* flag, |
| uint32_t* cb); |
| bool multiDisplayParamValidate(uint32_t id, uint32_t w, uint32_t h, |
| uint32_t dpi, uint32_t flag); |
| bool translateCoordination(uint32_t* x, uint32_t* y, uint32_t* displayId); |
| void setGpuMode(bool isGuestMode, uint32_t w, uint32_t h); |
| int createDisplay(uint32_t* displayId); |
| int setDisplayPose(uint32_t displayId, |
| int32_t x, |
| int32_t y, |
| uint32_t w, |
| uint32_t h, |
| uint32_t dpi, |
| uint32_t flag); |
| int destroyDisplay(uint32_t displayId); |
| int getDisplayPose(uint32_t displayId, |
| int32_t* x, |
| int32_t* y, |
| uint32_t* w, |
| uint32_t* h); |
| int getDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer); |
| int getColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId); |
| int setDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer); |
| void getCombinedDisplaySize(uint32_t* w, uint32_t* h); |
| bool isMultiDisplayWindow(); |
| bool isPixelFold(); |
| void loadConfig(); |
| void onSave(base::Stream* stream); |
| void onLoad(base::Stream* stream); |
| void performRotation(int rot); |
| |
| bool notifyDisplayChanges(); |
| |
| // 0 for default Android display |
| // 1-5 for Emulator UI |
| // 6-10 for developer from rcControl |
| static const uint32_t s_displayIdInternalBegin = 6; |
| static const uint32_t s_maxNumMultiDisplay = 11; |
| static const uint32_t s_invalidIdMultiDisplay = 0xFFFFFFAB; |
| |
| private: |
| const QAndroidEmulatorWindowAgent* mWindowAgent; |
| const QAndroidRecordScreenAgent* mRecordAgent; |
| const QAndroidVmOperations* mVmAgent; |
| bool mGuestMode; |
| int32_t mRotation { 0 }; |
| std::map<uint32_t, MultiDisplayInfo> mMultiDisplay; |
| android::base::Lock mLock; |
| |
| void performRotationLocked(int rot); |
| void recomputeLayoutLocked(); |
| void getCombinedDisplaySizeLocked(uint32_t* w, uint32_t* h); |
| bool getMultiDisplay(uint32_t id, |
| int32_t* x, |
| int32_t* y, |
| uint32_t* width, |
| uint32_t* height, |
| uint32_t* dpi, |
| uint32_t* flag, |
| uint32_t* cb, |
| bool* enabled); |
| int getNumberActiveMultiDisplaysLocked(); |
| |
| std::map<uint32_t, MultiDisplayInfo> parseConfig(); |
| bool hotPlugDisplayEnabled(); |
| }; |
| } // namespace android |
| |
| void android_init_multi_display(const QAndroidEmulatorWindowAgent* const windowAgent, |
| const QAndroidRecordScreenAgent* const recordAgent, |
| const QAndroidVmOperations* const vmAgent, |
| bool isGUestMode = false); |