diff options
author | Huihong Luo <huisinro@google.com> | 2019-09-04 13:11:42 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-09-04 13:11:42 -0700 |
commit | e849bc0d0c6dfc0ad46b7d537e5b21ed3c547fc8 (patch) | |
tree | 93b7f1d807339e02dd0c12610b22d15331765175 | |
parent | ccff49b278ea5b36ec512937582c60178a743b54 (diff) | |
parent | f97ddfce1c649ab7fc5f76c8c774e5c240b11853 (diff) | |
download | goldfish-opengl-temp_140451723.tar.gz |
Merge "Add external physical display emulation"temp_140451723
am: f97ddfce1c
Change-Id: Ie9e72b0498dcc2341d26286e9763efb68a13d3b0
-rw-r--r-- | system/hwc2/EmuHWC2.cpp | 108 | ||||
-rw-r--r-- | system/hwc2/EmuHWC2.h | 4 |
2 files changed, 112 insertions, 0 deletions
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp index 31e07895..3bda1a1b 100644 --- a/system/hwc2/EmuHWC2.cpp +++ b/system/hwc2/EmuHWC2.cpp @@ -21,6 +21,7 @@ #define LOG_TAG "EmuHWC2" #include <errno.h> +#include <cutils/properties.h> #include <log/log.h> #include <sync/sync.h> @@ -350,6 +351,13 @@ Error EmuHWC2::registerCallback(Callback descriptor, lock.unlock(); auto hotplug = reinterpret_cast<HWC2_PFN_VSYNC>(pointer); hotplug(callbackData, 0, static_cast<int32_t>(Connection::Connected)); + + int ret = populateSecondaryDisplays(); + if (ret < 0) { + ALOGE("Failed to populate secondary displays"); + } else if (ret == 0) { + hotplug(callbackData, 1, static_cast<int32_t>(Connection::Connected)); + } } return Error::None; @@ -1138,6 +1146,42 @@ int EmuHWC2::Display::populatePrimaryConfigs() { return 0; } +HWC2::Error EmuHWC2::Display::populateSecondaryConfigs(uint32_t width, uint32_t height, + uint32_t dpi) { + ALOGVV("%s DisplayId %u, width %u, height %u, dpi %u", + __FUNCTION__, (uint32_t)mId, width, height, dpi); + std::unique_lock<std::mutex> lock(mStateMutex); + + mGralloc.reset(new GrallocModule()); + auto newConfig = std::make_shared<Config>(*this); + // vsync is 60 hz; + newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod); + newConfig->setAttribute(Attribute::Width, width); + newConfig->setAttribute(Attribute::Height, height); + newConfig->setAttribute(Attribute::DpiX, dpi*1000); + newConfig->setAttribute(Attribute::DpiY, dpi*1000); + + newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size())); + ALOGV("Found new secondary config %d: %s", (uint32_t)newConfig->getId(), + newConfig->toString().c_str()); + mConfigs.emplace_back(std::move(newConfig)); + + // we need to reset these values after populatePrimaryConfigs() + mActiveConfig = mConfigs[0]; + mActiveColorMode = HAL_COLOR_MODE_NATIVE; + mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE); + + uint32_t displayId = 0; + DEFINE_AND_VALIDATE_HOST_CONNECTION + + hostCon->lock(); + rcEnc->rcCreateDisplay(rcEnc, &displayId); + rcEnc->rcSetDisplayPose(rcEnc, displayId, -1, -1, width, height); + hostCon->unlock(); + + return HWC2::Error::None; +} + // Config functions @@ -1397,6 +1441,70 @@ int EmuHWC2::populatePrimary() { return ret; } +// Note "hwservicemanager." is used to avoid selinux issue +#define EXTERANL_DISPLAY_PROP "hwservicemanager.external.displays" + +// return 0 for successful, 1 if no external displays are specified +// return < 0 if failed +int EmuHWC2::populateSecondaryDisplays() { + // this guest property, hwservicemanager.external.displays, + // specifies multi-display info, with comma (,) as separator + // each display has the following info: + // physicalId,width,height,dpi,flags + // serveral displays can be provided, e.g., following has 2 displays: + // setprop hwservicemanager.external.displays 1,1200,800,120,0,2,1200,800,120,0 + std::vector<uint64_t> values; + char displaysValue[PROPERTY_VALUE_MAX] = ""; + property_get(EXTERANL_DISPLAY_PROP, displaysValue, ""); + bool isValid = displaysValue[0] != '\0'; + if (isValid) { + char *p = displaysValue; + while (*p) { + if (!isdigit(*p) && *p != ',' && *p != ' ') { + isValid = false; + break; + } + p ++; + } + if (!isValid) { + ALOGE("Invalid syntax for the value of system prop: %s", EXTERANL_DISPLAY_PROP); + } + } + if (!isValid) { + // no external displays are specified + return 1; + } + // parse all int values to a vector + std::istringstream stream(displaysValue); + for (uint64_t id; stream >> id;) { + values.push_back(id); + if (stream.peek() == ',') + stream.ignore(); + } + // each display has 5 values + if ((values.size() % 5) != 0) { + ALOGE("%s: invalid value for system property: %s", __FUNCTION__, EXTERANL_DISPLAY_PROP); + return -1; + } + while (!values.empty()) { + uint64_t physicalId = values[0]; + uint32_t width = values[1]; + uint32_t height = values[2]; + uint32_t dpi = values[3]; + uint32_t flags = values[4]; + values.erase(values.begin(), values.begin() + 5); + + Error ret = Error::None; + auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical); + ret = display->populateSecondaryConfigs(width, height, dpi); + if (ret != Error::None) { + return -2; + } + mDisplays.emplace(display->getId(), std::move(display)); + } + return 0; +} + EmuHWC2::Display* EmuHWC2::getDisplay(hwc2_display_t id) { auto display = mDisplays.find(id); if (display == mDisplays.end()) { diff --git a/system/hwc2/EmuHWC2.h b/system/hwc2/EmuHWC2.h index 899d7344..1c0dd51e 100644 --- a/system/hwc2/EmuHWC2.h +++ b/system/hwc2/EmuHWC2.h @@ -27,6 +27,7 @@ #include <atomic> #include <map> #include <mutex> +#include <sstream> #include <vector> #include <unordered_set> #include <unordered_map> @@ -42,6 +43,7 @@ class EmuHWC2 : public hwc2_device_t { public: EmuHWC2(); int populatePrimary(); + int populateSecondaryDisplays(); private: static inline EmuHWC2* getHWC2(hwc2_device_t* device) { @@ -258,6 +260,8 @@ private: // Read configs from PRIMARY Display int populatePrimaryConfigs(); + HWC2::Error populateSecondaryConfigs(uint32_t width, uint32_t height, + uint32_t dpi); private: class Config { |