Switch to version 2 of ComposeDevice
Note backward compatibility is maintained on emu host side while previous
version 1 will be handled correctly. This CL makes it ready for
upcoming CLs that support physical display emulation.
The key is to pass the displayId to host side to support multi-display.
Test: manually
Change-Id: Ia8e9b8953ff949e67c5f6214cde2635b2e5b82e1
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index 95b3e60..422812c 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -60,9 +60,11 @@
enum HostComposition {
HOST_COMPOSITION_NONE = 0,
HOST_COMPOSITION_V1,
+ HOST_COMPOSITION_V2,
};
static const char kHostCompositionV1[] = "ANDROID_EMU_host_composition_v1";
+static const char kHostCompositionV2[] = "ANDROID_EMU_host_composition_v2";
// No querying errors from host extension
static const char kGLESNoHostError[] = "ANDROID_EMU_gles_no_host_error";
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index be6a84e..0165ae6 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -358,7 +358,11 @@
void HostConnection::queryAndSetHostCompositionImpl(ExtendedRCEncoderContext *rcEnc) {
const std::string& glExtensions = queryGLExtensions(rcEnc);
ALOGD("HostComposition ext %s", glExtensions.c_str());
- if (glExtensions.find(kHostCompositionV1) != std::string::npos) {
+ // make sure V2 is checked first before V1, as host may declare supporting both
+ if (glExtensions.find(kHostCompositionV2) != std::string::npos) {
+ rcEnc->setHostComposition(HOST_COMPOSITION_V2);
+ }
+ else if (glExtensions.find(kHostCompositionV1) != std::string::npos) {
rcEnc->setHostComposition(HOST_COMPOSITION_V1);
}
else {
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index 22b36b0..df111fd 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -57,6 +57,8 @@
bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; }
bool hasHostCompositionV1() const {
return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; }
+ bool hasHostCompositionV2() const {
+ return m_featureInfo.hostComposition == HOST_COMPOSITION_V2; }
bool hasYUV420toNV21() const {
return m_featureInfo.hasYUV420888toNV21; }
bool hasYUVCache() const {
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp
index 00b7a21..8925a00 100644
--- a/system/hwc2/EmuHWC2.cpp
+++ b/system/hwc2/EmuHWC2.cpp
@@ -696,9 +696,15 @@
DEFINE_AND_VALIDATE_HOST_CONNECTION
hostCon->lock();
bool hostCompositionV1 = rcEnc->hasHostCompositionV1();
+ bool hostCompositionV2 = rcEnc->hasHostCompositionV2();
hostCon->unlock();
- if (hostCompositionV1) {
+ // if we supports v2, then discard v1
+ if (hostCompositionV2) {
+ hostCompositionV1 = false;
+ }
+
+ if (hostCompositionV2 || hostCompositionV1) {
uint32_t numLayer = 0;
for (auto layer: mLayers) {
if (layer->getCompositionType() == Composition::Device ||
@@ -720,13 +726,28 @@
return Error::None;
}
- if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
- mComposeMsg.reset(new ComposeMsg(numLayer));
+ if (hostCompositionV1) {
+ if (mComposeMsg == nullptr || mComposeMsg->getLayerCnt() < numLayer) {
+ mComposeMsg.reset(new ComposeMsg(numLayer));
+ }
+ } else {
+ if (mComposeMsg_v2 == nullptr || mComposeMsg_v2->getLayerCnt() < numLayer) {
+ mComposeMsg_v2.reset(new ComposeMsg_v2(numLayer));
+ }
}
// Handle the composition
- ComposeDevice* p = mComposeMsg->get();
- ComposeLayer* l = p->layer;
+ ComposeDevice* p;
+ ComposeDevice_v2* p2;
+ ComposeLayer* l;
+
+ if (hostCompositionV1) {
+ p = mComposeMsg->get();
+ l = p->layer;
+ } else {
+ p2 = mComposeMsg_v2->get();
+ l = p2->layer;
+ }
for (auto layer: mLayers) {
if (layer->getCompositionType() != Composition::Device &&
@@ -781,14 +802,28 @@
layer->getZ(), l->composeMode, l->transform);
l++;
}
- p->version = 1;
- p->targetHandle = mGralloc->getTargetCb();
- p->numLayers = numLayer;
+ if (hostCompositionV1) {
+ p->version = 1;
+ p->targetHandle = mGralloc->getTargetCb();
+ p->numLayers = numLayer;
+ } else {
+ p2->version = 2;
+ p2->displayId = (uint32_t)mId;
+ p2->targetHandle = mGralloc->getTargetCb();
+ p2->numLayers = numLayer;
+ }
hostCon->lock();
- rcEnc->rcCompose(rcEnc,
- sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
- (void *)p);
+ if (hostCompositionV1) {
+ rcEnc->rcCompose(rcEnc,
+ sizeof(ComposeDevice) + numLayer * sizeof(ComposeLayer),
+ (void *)p);
+ } else {
+ rcEnc->rcCompose(rcEnc,
+ sizeof(ComposeDevice_v2) + numLayer * sizeof(ComposeLayer),
+ (void *)p2);
+ }
+
hostCon->unlock();
// Send a retire fence and use it as the release fence for all layers,
diff --git a/system/hwc2/EmuHWC2.h b/system/hwc2/EmuHWC2.h
index a10f5c4..899d734 100644
--- a/system/hwc2/EmuHWC2.h
+++ b/system/hwc2/EmuHWC2.h
@@ -191,6 +191,25 @@
ComposeDevice* mComposeDevice;
};
+ class ComposeMsg_v2 {
+ public:
+ ComposeMsg_v2(uint32_t layerCnt = 0) :
+ mData(sizeof(ComposeDevice_v2) + layerCnt * sizeof(ComposeLayer))
+ {
+ mComposeDevice = reinterpret_cast<ComposeDevice_v2*>(mData.data());
+ mLayerCnt = layerCnt;
+ }
+
+ ComposeDevice_v2* get() { return mComposeDevice; }
+
+ uint32_t getLayerCnt() { return mLayerCnt; }
+
+ private:
+ std::vector<uint8_t> mData;
+ uint32_t mLayerCnt;
+ ComposeDevice_v2* mComposeDevice;
+ };
+
class Display {
public:
Display(EmuHWC2& device, HWC2::DisplayType type);
@@ -348,6 +367,7 @@
mutable std::mutex mStateMutex;
std::unique_ptr<GrallocModule> mGralloc;
std::unique_ptr<ComposeMsg> mComposeMsg;
+ std::unique_ptr<ComposeMsg_v2> mComposeMsg_v2;
int mSyncDeviceFd;
};