Resizable emulator: enable multiple display configs in framebuffer
Bug: 196986384
Bug: 265182971
Change-Id: I0af1be86f131bd5dad4292652f7d5be80d860299
diff --git a/gl-host-common/include/host-common/opengles.h b/gl-host-common/include/host-common/opengles.h
index e51faec..500cd5f 100644
--- a/gl-host-common/include/host-common/opengles.h
+++ b/gl-host-common/include/host-common/opengles.h
@@ -154,6 +154,10 @@
/* Set vsync rate at runtime */
AEMU_EXPORT void android_setVsyncHz(int vsyncHz);
+AEMU_EXPORT void android_setOpenglesDisplayConfigs(int configId, int w, int h,
+ int dpiX, int dpiY);
+AEMU_EXPORT void android_setOpenglesDisplayActiveConfig(int configId);
+
#ifndef USING_ANDROID_BP
ANDROID_END_HEADER
#endif
diff --git a/gl-host-common/opengles.cpp b/gl-host-common/opengles.cpp
index ede2bf1..faca808 100644
--- a/gl-host-common/opengles.cpp
+++ b/gl-host-common/opengles.cpp
@@ -709,3 +709,16 @@
sRenderer->setVsyncHz(vsyncHz);
}
}
+
+void android_setOpenglesDisplayConfigs(int configId, int w, int h, int dpiX,
+ int dpiY) {
+ if (sRenderer) {
+ sRenderer->setDisplayConfigs(configId, w, h, dpiX, dpiY);
+ }
+}
+
+void android_setOpenglesDisplayActiveConfig(int configId) {
+ if (sRenderer) {
+ sRenderer->setDisplayActiveConfig(configId);
+ }
+}
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index 8cb6584..3f66769 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -522,6 +522,8 @@
m_postThread([this](Post&& post) { return postWorkerFunc(post); }),
m_logger(CreateMetricsLogger()),
m_healthMonitor(CreateHealthMonitor(*m_logger)) {
+ mDisplayActiveConfigId = 0;
+ mDisplayConfigs[0] = {p_width, p_height, 160, 160};
uint32_t displayId = 0;
if (createDisplay(&displayId) < 0) {
fprintf(stderr, "Failed to create default display\n");
@@ -2981,6 +2983,15 @@
stream->putBe32(m_framebufferWidth);
stream->putBe32(m_framebufferHeight);
stream->putFloat(m_dpr);
+ stream->putBe32(mDisplayActiveConfigId);
+ saveCollection(stream, mDisplayConfigs,
+ [](Stream* s, const std::map<int, DisplayConfig>::value_type& pair) {
+ s->putBe32(pair.first);
+ s->putBe32(pair.second.w);
+ s->putBe32(pair.second.h);
+ s->putBe32(pair.second.dpiX);
+ s->putBe32(pair.second.dpiY);
+ });
stream->putBe32(m_useSubWindow);
stream->putBe32(/*Obsolete m_eglContextInitialized =*/1);
@@ -3157,6 +3168,17 @@
m_framebufferWidth = stream->getBe32();
m_framebufferHeight = stream->getBe32();
m_dpr = stream->getFloat();
+ mDisplayActiveConfigId = stream->getBe32();
+ loadCollection(stream, &mDisplayConfigs,
+ [](Stream* s) -> std::map<int, DisplayConfig>::value_type {
+ int idx = static_cast<int>(s->getBe32());
+ int w = static_cast<int>(s->getBe32());
+ int h = static_cast<int>(s->getBe32());
+ int dpiX = static_cast<int>(s->getBe32());
+ int dpiY = static_cast<int>(s->getBe32());
+ return {idx, {w, h, dpiX, dpiY}};
+ });
+
// TODO: resize the window
//
m_useSubWindow = stream->getBe32();
@@ -3694,3 +3716,58 @@
m_vsyncThread->schedule(task);
}
+
+void FrameBuffer::setDisplayConfigs(int configId, int w, int h,
+ int dpiX, int dpiY) {
+ AutoLock mutex(m_lock);
+ mDisplayConfigs[configId] = {w, h, dpiX, dpiY};
+ INFO("setDisplayConfigs w %d h %d dpiX %d dpiY %d", w, h, dpiX, dpiY);
+}
+
+void FrameBuffer::setDisplayActiveConfig(int configId) {
+ AutoLock mutex(m_lock);
+ if (mDisplayConfigs.find(configId) == mDisplayConfigs.end()) {
+ ERR("config %d not set", configId);
+ return;
+ }
+ mDisplayActiveConfigId = configId;
+ m_framebufferWidth = mDisplayConfigs[configId].w;
+ m_framebufferHeight = mDisplayConfigs[configId].h;
+ setDisplayPose(0, 0, 0, getWidth(), getHeight(), 0);
+ INFO("setDisplayActiveConfig %d", configId);
+}
+
+const int FrameBuffer::getDisplayConfigsCount() {
+ AutoLock mutex(m_lock);
+ return mDisplayConfigs.size();
+}
+
+const int FrameBuffer::getDisplayConfigsParam(int configId, EGLint param) {
+ AutoLock mutex(m_lock);
+ if (mDisplayConfigs.find(configId) == mDisplayConfigs.end()) {
+ return -1;
+ }
+ switch (param) {
+ case FB_WIDTH:
+ return mDisplayConfigs[configId].w;
+ case FB_HEIGHT:
+ return mDisplayConfigs[configId].h;
+ case FB_XDPI:
+ return mDisplayConfigs[configId].dpiX;
+ case FB_YDPI:
+ return mDisplayConfigs[configId].dpiY;
+ case FB_FPS:
+ return 60;
+ case FB_MIN_SWAP_INTERVAL:
+ return -1;
+ case FB_MAX_SWAP_INTERVAL:
+ return -1;
+ default:
+ return -1;
+ }
+}
+
+const int FrameBuffer::getDisplayActiveConfig() {
+ AutoLock mutex(m_lock);
+ return mDisplayActiveConfigId >= 0 ? mDisplayActiveConfigId : -1;
+}
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index 3e9aea8..75971f0 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -656,6 +656,11 @@
void setVsyncHz(int vsyncHz);
void scheduleVsyncTask(VsyncThread::VsyncTask task);
+ void setDisplayConfigs(int configId, int w, int h, int dpiX, int dpiY);
+ void setDisplayActiveConfig(int configId);
+ const int getDisplayConfigsCount();
+ const int getDisplayConfigsParam(int configId, EGLint param);
+ const int getDisplayActiveConfig();
private:
FrameBuffer(int p_width, int p_height, bool useSubWindow);
@@ -883,5 +888,17 @@
// Vsync thread.
std::unique_ptr<VsyncThread> m_vsyncThread = {};
+
+ struct DisplayConfig{
+ int w;
+ int h;
+ int dpiX;
+ int dpiY;
+ DisplayConfig() {}
+ DisplayConfig(int w, int h, int x, int y)
+ : w(w), h(h), dpiX(x), dpiY(y) {}
+ };
+ std::map<int, DisplayConfig> mDisplayConfigs;
+ int mDisplayActiveConfigId = -1;
};
#endif
diff --git a/stream-servers/RenderWindow.cpp b/stream-servers/RenderWindow.cpp
index fc242ae..92da684 100644
--- a/stream-servers/RenderWindow.cpp
+++ b/stream-servers/RenderWindow.cpp
@@ -63,6 +63,8 @@
CMD_HAS_GUEST_POSTED_A_FRAME,
CMD_RESET_GUEST_POSTED_A_FRAME,
CMD_SET_VSYNC_HZ,
+ CMD_SET_DISPLAY_CONFIGS,
+ CMD_SET_DISPLAY_ACTIVE_CONFIG,
CMD_FINALIZE,
};
@@ -116,6 +118,17 @@
// CMD_SET_VSYNC_HZ
int vsyncHz;
+ // CMD_SET_COMPOSE_DIMENSIONS
+ struct {
+ int configId;
+ int width;
+ int height;
+ int dpiX;
+ int dpiY;
+ } displayConfigs;
+
+ int displayActiveConfig;
+
// result of operations.
bool result;
};
@@ -267,6 +280,34 @@
}
break;
+ case CMD_SET_DISPLAY_CONFIGS:
+ GL_LOG("CMD_SET_DISPLAY_CONFIGS");
+ D("CMD_SET_DISPLAY_CONFIGS");
+ fb = FrameBuffer::getFB();
+ if (fb) {
+ fb->setDisplayConfigs(msg.displayConfigs.configId,
+ msg.displayConfigs.width,
+ msg.displayConfigs.height,
+ msg.displayConfigs.dpiX,
+ msg.displayConfigs.dpiY);
+ result = true;
+ } else {
+ GL_LOG("CMD_SET_DISPLAY_CONFIGS: no FrameBuffer");
+ }
+ break;
+
+ case CMD_SET_DISPLAY_ACTIVE_CONFIG:
+ GL_LOG("CMD_SET_DISPLAY_ACTIVE_CONFIG");
+ D("CMD_SET_DISPLAY_ACTIVE_CONFIG");
+ fb = FrameBuffer::getFB();
+ if (fb) {
+ fb->setDisplayActiveConfig(msg.displayActiveConfig);
+ result = true;
+ } else {
+ GL_LOG("CMD_SET_DISPLAY_ACTIVE_CONFIG: no FrameBuffer");
+ }
+ break;
+
default:
;
}
@@ -614,6 +655,29 @@
D("Exiting\n");
}
+void RenderWindow::setDisplayConfigs(int configId, int w, int h,
+ int dpiX, int dpiY) {
+ D("Entering\n");
+ RenderWindowMessage msg = {};
+ msg.cmd = CMD_SET_DISPLAY_CONFIGS;
+ msg.displayConfigs.configId = configId;
+ msg.displayConfigs.width = w;
+ msg.displayConfigs.height= h;
+ msg.displayConfigs.dpiX= dpiX;
+ msg.displayConfigs.dpiY = dpiY;
+ (void) processMessage(msg);
+ D("Exiting\n");
+}
+
+void RenderWindow::setDisplayActiveConfig(int configId) {
+ D("Entering\n");
+ RenderWindowMessage msg = {};
+ msg.cmd = CMD_SET_DISPLAY_ACTIVE_CONFIG;
+ msg.displayActiveConfig = configId;
+ (void) processMessage(msg);
+ D("Exiting\n");
+}
+
bool RenderWindow::processMessage(const RenderWindowMessage& msg) {
if (useThread()) {
if (msg.cmd == CMD_REPAINT) {
diff --git a/stream-servers/RenderWindow.h b/stream-servers/RenderWindow.h
index a3b59a9..68e7ca1 100644
--- a/stream-servers/RenderWindow.h
+++ b/stream-servers/RenderWindow.h
@@ -148,6 +148,8 @@
void removeListener(emugl::Renderer::FrameBufferChangeEventListener* listener);
void setVsyncHz(int vsyncHz);
+ void setDisplayConfigs(int configId, int w, int h, int dpiX, int dpiY);
+ void setDisplayActiveConfig(int configId);
private:
bool processMessage(const RenderWindowMessage& msg);
bool useThread() const { return mThread != nullptr; }
diff --git a/stream-servers/RendererImpl.cpp b/stream-servers/RendererImpl.cpp
index a52ad29..602dea9 100644
--- a/stream-servers/RendererImpl.cpp
+++ b/stream-servers/RendererImpl.cpp
@@ -677,17 +677,15 @@
void RendererImpl::setDisplayConfigs(int configId, int w, int h,
int dpiX, int dpiY) {
- // TODO: need CP
- (void)configId;
- (void)w;
- (void)h;
- (void)dpiX;
- (void)dpiY;
+ if (mRenderWindow) {
+ mRenderWindow->setDisplayConfigs(configId, w, h, dpiX, dpiY);
+ }
}
void RendererImpl::setDisplayActiveConfig(int configId) {
- // TODO: need CP
- (void)configId;
+ if (mRenderWindow) {
+ mRenderWindow->setDisplayActiveConfig(configId);
+ }
}
} // namespace emugl