Support multiple display configs for default display, DO NOT MERGE ANYWHERE
Bug: 196986384
Test: run emulator with multiple display configs,
switch config using 'service call SurfaceFlinger 1035 i32 <configId>'
Change-Id: I18fb06763a04ead67999f93bf5bf538777f93b19
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index 74f64c8..8a243c2 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -138,6 +138,9 @@
// DMA for readback
static const char kReadColorBufferDma[] = "ANDROID_EMU_read_color_buffer_dma";
+// HWC multiple display configs
+static const char kHWCMultiConfigs[] = "ANDROID_EMU_hwc_multi_configs";
+
// Struct describing available emulator features
struct EmulatorFeatureInfo {
@@ -166,7 +169,8 @@
hasVulkanBatchedDescriptorSetUpdate(false),
hasSyncBufferData(false),
hasVulkanAsyncQsri(false),
- hasReadColorBufferDma(false)
+ hasReadColorBufferDma(false),
+ hasHWCMultiConfigs(false)
{ }
SyncImpl syncImpl;
@@ -194,6 +198,7 @@
bool hasSyncBufferData;
bool hasVulkanAsyncQsri;
bool hasReadColorBufferDma;
+ bool hasHWCMultiConfigs;
};
enum HostConnectionType {
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 6fd3318..8399f2a 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -674,6 +674,7 @@
queryAndSetSyncBufferData(rcEnc);
queryAndSetVulkanAsyncQsri(rcEnc);
queryAndSetReadColorBufferDma(rcEnc);
+ queryAndSetHWCMultiConfigs(rcEnc);
queryVersion(rcEnc);
if (m_processPipe) {
m_processPipe->processPipeInit(m_connectionType, rcEnc);
@@ -987,6 +988,13 @@
}
}
+void HostConnection::queryAndSetHWCMultiConfigs(ExtendedRCEncoderContext* rcEnc) {
+ std::string glExtensions = queryGLExtensions(rcEnc);
+ if (glExtensions.find(kHWCMultiConfigs) != std::string::npos) {
+ rcEnc->featureInfo()->hasHWCMultiConfigs = true;
+ }
+}
+
GLint HostConnection::queryVersion(ExtendedRCEncoderContext* rcEnc) {
GLint version = m_rcEnc->rcGetRendererVersion(m_rcEnc.get());
return version;
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index 0f7c351..6bec6ac 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -77,6 +77,9 @@
}
bool hasSyncBufferData() const {
return m_featureInfo.hasSyncBufferData; }
+ bool hasHWCMultiConfigs() const {
+ return m_featureInfo.hasHWCMultiConfigs;
+ }
DmaImpl getDmaVersion() const { return m_featureInfo.dmaImpl; }
void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; }
void bindDmaDirectly(void* dmaPtr, uint64_t dmaPhysAddr) {
@@ -246,6 +249,7 @@
void queryAndSetSyncBufferData(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanAsyncQsri(ExtendedRCEncoderContext *rcEnc);
void queryAndSetReadColorBufferDma(ExtendedRCEncoderContext *rcEnc);
+ void queryAndSetHWCMultiConfigs(ExtendedRCEncoderContext* rcEnc);
GLint queryVersion(ExtendedRCEncoderContext* rcEnc);
private:
diff --git a/system/hwc2/Composer.h b/system/hwc2/Composer.h
index eea4f56..b0c3248 100644
--- a/system/hwc2/Composer.h
+++ b/system/hwc2/Composer.h
@@ -54,6 +54,7 @@
// to the display.
virtual HWC2::Error presentDisplay(Display* display,
int32_t* outPresentFence) = 0;
+ virtual HWC2::Error onActiveConfigChange(Display* display) = 0;
};
} // namespace android
diff --git a/system/hwc2/Device.cpp b/system/hwc2/Device.cpp
index ab30026..1f06f43 100644
--- a/system/hwc2/Device.cpp
+++ b/system/hwc2/Device.cpp
@@ -97,18 +97,17 @@
return HWC2::Error::NoResources;
}
- std::vector<DisplayConfig> displayConfigs;
+ std::vector<DisplayMultiConfigs> displays;
- HWC2::Error error = findDisplayConfigs(&displayConfigs);
+ HWC2::Error error = findDisplays(displays);
if (error != HWC2::Error::None) {
ALOGE("%s failed to find display configs", __FUNCTION__);
return error;
}
- for (const DisplayConfig& displayConfig : displayConfigs) {
- error = createDisplay(displayConfig.id, displayConfig.width,
- displayConfig.height, displayConfig.dpiX,
- displayConfig.dpiY, displayConfig.refreshRateHz);
+ for (const auto& iter: displays) {
+
+ error = createDisplay(iter.configs, iter.activeConfigId);
if (error != HWC2::Error::None) {
ALOGE("%s failed to create display from config", __FUNCTION__);
return error;
@@ -118,9 +117,8 @@
return HWC2::Error::None;
}
-HWC2::Error Device::createDisplay(uint32_t displayId, uint32_t width,
- uint32_t height, uint32_t dpiX, uint32_t dpiY,
- uint32_t refreshRateHz) {
+HWC2::Error Device::createDisplay(const std::vector<DisplayConfig>& configs,
+ int activeConfig) {
DEBUG_LOG("%s", __FUNCTION__);
if (!mComposer) {
@@ -128,13 +126,15 @@
return HWC2::Error::NoResources;
}
- auto display = std::make_unique<Display>(*this, mComposer.get(), displayId);
+ uint32_t displayId = configs[0].id;
+ auto display = std::make_unique<Display>(*this, mComposer.get(),
+ displayId);
if (display == nullptr) {
ALOGE("%s failed to allocate display", __FUNCTION__);
return HWC2::Error::NoResources;
}
- HWC2::Error error = display->init(width, height, dpiX, dpiY, refreshRateHz);
+ HWC2::Error error = display->init(configs, activeConfig);
if (error != HWC2::Error::None) {
ALOGE("%s failed to initialize display:%" PRIu32, __FUNCTION__, displayId);
return error;
@@ -539,7 +539,11 @@
display->unlock();
}
if (connected) {
- createDisplay(id, width, height, dpiX, dpiY, refreshRate);
+ std::vector<DisplayConfig> config;
+ config.push_back({static_cast<int>(id), static_cast<int>(width),
+ static_cast<int>(height), static_cast<int>(dpiX),
+ static_cast<int>(dpiY), static_cast<int>(refreshRate)});
+ createDisplay(config, 0);
ALOGD("callback hotplugConnect display %" PRIu32 " width %" PRIu32
" height %" PRIu32 " dpiX %" PRIu32 " dpiY %" PRIu32 "fps %" PRIu32,
id, width, height, dpiX, dpiY, refreshRate);
diff --git a/system/hwc2/Device.h b/system/hwc2/Device.h
index 7c990b9..b49d1a0 100644
--- a/system/hwc2/Device.h
+++ b/system/hwc2/Device.h
@@ -53,8 +53,8 @@
HWC2::Error createDisplays();
- HWC2::Error createDisplay(uint32_t displayId, uint32_t width, uint32_t height,
- uint32_t dpiX, uint32_t dpiY, uint32_t refreshRate);
+ HWC2::Error createDisplay(const std::vector<DisplayConfig>& configs,
+ int activeConfig);
Display* getDisplay(hwc2_display_t displayId);
diff --git a/system/hwc2/Display.cpp b/system/hwc2/Display.cpp
index 2feca77..f95992b 100644
--- a/system/hwc2/Display.cpp
+++ b/system/hwc2/Display.cpp
@@ -70,29 +70,34 @@
Display::~Display() {}
-HWC2::Error Display::init(uint32_t width, uint32_t height, uint32_t dpiX,
- uint32_t dpiY, uint32_t refreshRateHz,
+HWC2::Error Display::init(const std::vector<DisplayConfig>& configs,
+ int activeConfig,
const std::optional<std::vector<uint8_t>>& edid) {
ALOGD("%s initializing display:%" PRIu64
" width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
- __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);
+ __FUNCTION__, mId, configs[activeConfig].width,
+ configs[activeConfig].height,
+ configs[activeConfig].dpiX,
+ configs[activeConfig].dpiY,
+ configs[activeConfig].refreshRateHz);
std::unique_lock<std::recursive_mutex> lock(mStateMutex);
- mVsyncPeriod = 1000 * 1000 * 1000 / refreshRateHz;
+ mVsyncPeriod = 1000 * 1000 * 1000 / configs[activeConfig].refreshRateHz;
mVsyncThread->run("", ANDROID_PRIORITY_URGENT_DISPLAY);
- hwc2_config_t configId = sNextConfigId++;
+ for (hwc2_config_t id = 0; id < configs.size(); id++) {
+ Config config(id);
+ config.setAttribute(HWC2::Attribute::VsyncPeriod,
+ 1000 * 1000 * 1000 / configs[id].refreshRateHz);
+ config.setAttribute(HWC2::Attribute::Width, configs[id].width);
+ config.setAttribute(HWC2::Attribute::Height, configs[id].height);
+ config.setAttribute(HWC2::Attribute::DpiX, configs[id].dpiX * 1000);
+ config.setAttribute(HWC2::Attribute::DpiY, configs[id].dpiY * 1000);
+ mConfigs.emplace(id, config);
+ }
+ mActiveConfigId = activeConfig;
- Config config(configId);
- config.setAttribute(HWC2::Attribute::VsyncPeriod, mVsyncPeriod);
- config.setAttribute(HWC2::Attribute::Width, width);
- config.setAttribute(HWC2::Attribute::Height, height);
- config.setAttribute(HWC2::Attribute::DpiX, dpiX * 1000);
- config.setAttribute(HWC2::Attribute::DpiY, dpiY * 1000);
- mConfigs.emplace(configId, config);
-
- mActiveConfigId = configId;
mActiveColorMode = HAL_COLOR_MODE_NATIVE;
mColorModes.emplace((android_color_mode_t)HAL_COLOR_MODE_NATIVE);
mEdid = edid;
@@ -507,7 +512,14 @@
return HWC2::Error::BadConfig;
}
- mActiveConfigId = configId;
+ if (mActiveConfigId != configId) {
+ if (mComposer == nullptr) {
+ ALOGE("%s: display:%" PRIu64 " missing composer", __FUNCTION__, mId);
+ return HWC2::Error::NoResources;
+ }
+ mActiveConfigId = configId;
+ return mComposer->onActiveConfigChange(this);
+ }
return HWC2::Error::None;
}
diff --git a/system/hwc2/Display.h b/system/hwc2/Display.h
index ee94756..c5385a8 100644
--- a/system/hwc2/Display.h
+++ b/system/hwc2/Display.h
@@ -29,6 +29,7 @@
#include "Common.h"
#include "Composer.h"
+#include "DisplayFinder.h"
#include "FencedBuffer.h"
#include "Layer.h"
@@ -53,9 +54,7 @@
Display(Display&& display) = delete;
Display& operator=(Display&& display) = delete;
- HWC2::Error init(
- uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY,
- uint32_t refreshRateHz,
+ HWC2::Error init(const std::vector<DisplayConfig>& configs, int activeConfig,
const std::optional<std::vector<uint8_t>>& edid = std::nullopt);
HWC2::Error updateParameters(
diff --git a/system/hwc2/DisplayFinder.cpp b/system/hwc2/DisplayFinder.cpp
index 1a3c079..765ec50 100644
--- a/system/hwc2/DisplayFinder.cpp
+++ b/system/hwc2/DisplayFinder.cpp
@@ -30,7 +30,7 @@
return android::base::GetProperty("ro.product.board", "") == "cutf";
}
-HWC2::Error findCuttlefishDisplayConfigs(std::vector<DisplayConfig>* configs) {
+HWC2::Error findCuttlefishDisplays(std::vector<DisplayMultiConfigs>& displays) {
DEBUG_LOG("%s", __FUNCTION__);
// TODO: replace with initializing directly from DRM info.
@@ -38,18 +38,18 @@
int displayId = 0;
for (const auto& deviceDisplayConfig : deviceConfig.display_config()) {
- DisplayConfig displayConfig = {
+ DisplayMultiConfigs display = {
.id = displayId,
- .width = deviceDisplayConfig.width(),
- .height = deviceDisplayConfig.height(),
- .dpiX = deviceDisplayConfig.dpi(),
- .dpiY = deviceDisplayConfig.dpi(),
- .refreshRateHz = deviceDisplayConfig.refresh_rate_hz(),
+ .activeConfigId = 0,
+ .configs = {{displayId,
+ deviceDisplayConfig.width(),
+ deviceDisplayConfig.width(),
+ deviceDisplayConfig.dpi(),
+ deviceDisplayConfig.dpi(),
+ deviceDisplayConfig.refresh_rate_hz()}},
};
-
+ displays.push_back(display);
++displayId;
-
- configs->push_back(displayConfig);
}
return HWC2::Error::None;
@@ -71,33 +71,54 @@
return static_cast<int>(vsyncPeriod);
}
-HWC2::Error findGoldfishPrimaryDisplayConfig(
- std::vector<DisplayConfig>* configs) {
+HWC2::Error findGoldfishPrimaryDisplay(std::vector<DisplayMultiConfigs>& displays) {
DEBUG_LOG("%s", __FUNCTION__);
DEFINE_AND_VALIDATE_HOST_CONNECTION
hostCon->lock();
- const int width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
- const int height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
- const int dpiX = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
- const int dpiY = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
- hostCon->unlock();
+ int activeConfigId;
const int refreshRateHz = getVsyncHzFromProperty();
+ DisplayMultiConfigs display;
+ display.id = 0;
+ if (rcEnc->hasHWCMultiConfigs()) {
+ int count= rcEnc->rcGetFBDisplayConfigsCount(rcEnc);
+ if (count <= 0) {
+ ALOGE("%s failed to allocate primary display, config count %d", __func__, count);
+ return HWC2::Error::NoResources;
+ }
+ display.activeConfigId = rcEnc->rcGetFBDisplayActiveConfig(rcEnc);
+ for(int configId = 0; configId < count; configId++) {
+ display.configs.push_back({
+ 0,
+ rcEnc->rcGetFBDisplayConfigsParam(
+ rcEnc, configId, FB_WIDTH),
+ rcEnc->rcGetFBDisplayConfigsParam(
+ rcEnc, configId, FB_HEIGHT),
+ rcEnc->rcGetFBDisplayConfigsParam(
+ rcEnc, configId, FB_XDPI),
+ rcEnc->rcGetFBDisplayConfigsParam(
+ rcEnc, configId, FB_YDPI),
+ refreshRateHz,
+ });
+ }
+ } else {
+ display.activeConfigId = 0;
+ display.configs.push_back({
+ 0,
+ rcEnc->rcGetFBParam(rcEnc, FB_WIDTH),
+ rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT),
+ rcEnc->rcGetFBParam(rcEnc, FB_XDPI),
+ rcEnc->rcGetFBParam(rcEnc, FB_YDPI),
+ refreshRateHz});
+ }
+ hostCon->unlock();
- configs->push_back(DisplayConfig{
- .id = 0,
- .width = width,
- .height = height,
- .dpiX = dpiX,
- .dpiY = dpiY,
- .refreshRateHz = refreshRateHz,
- });
+ displays.push_back(display);
return HWC2::Error::None;
}
-HWC2::Error findGoldfishSecondaryDisplayConfigs(
- std::vector<DisplayConfig>* configs) {
+HWC2::Error findGoldfishSecondaryDisplays(std::vector<DisplayMultiConfigs>& displays) {
DEBUG_LOG("%s", __FUNCTION__);
static constexpr const char kExternalDisplayProp[] =
@@ -131,7 +152,10 @@
int secondaryDisplayId = 1;
while (!propIntParts.empty()) {
- configs->push_back(DisplayConfig{
+ DisplayMultiConfigs display;
+ display.id = secondaryDisplayId;
+ display.activeConfigId = 0;
+ display.configs.push_back(DisplayConfig{
.id = secondaryDisplayId,
.width = propIntParts[1],
.height = propIntParts[2],
@@ -139,6 +163,7 @@
.dpiY = propIntParts[3],
.refreshRateHz = 160,
});
+ displays.push_back(display);
++secondaryDisplayId;
@@ -148,14 +173,14 @@
return HWC2::Error::None;
}
-HWC2::Error findGoldfishDisplayConfigs(std::vector<DisplayConfig>* configs) {
- HWC2::Error error = findGoldfishPrimaryDisplayConfig(configs);
+HWC2::Error findGoldfishDisplays(std::vector<DisplayMultiConfigs>& displays) {
+ HWC2::Error error = findGoldfishPrimaryDisplay(displays);
if (error != HWC2::Error::None) {
ALOGE("%s failed to find Goldfish primary display", __FUNCTION__);
return error;
}
- error = findGoldfishSecondaryDisplayConfigs(configs);
+ error = findGoldfishSecondaryDisplays(displays);
if (error != HWC2::Error::None) {
ALOGE("%s failed to find Goldfish secondary displays", __FUNCTION__);
}
@@ -165,11 +190,11 @@
} // namespace
-HWC2::Error findDisplayConfigs(std::vector<DisplayConfig>* configs) {
+HWC2::Error findDisplays(std::vector<DisplayMultiConfigs>& displays) {
if (IsCuttlefish()) {
- return findCuttlefishDisplayConfigs(configs);
+ return findCuttlefishDisplays(displays);
} else {
- return findGoldfishDisplayConfigs(configs);
+ return findGoldfishDisplays(displays);
}
}
diff --git a/system/hwc2/DisplayFinder.h b/system/hwc2/DisplayFinder.h
index 642fca2..44a09a6 100644
--- a/system/hwc2/DisplayFinder.h
+++ b/system/hwc2/DisplayFinder.h
@@ -32,8 +32,15 @@
int refreshRateHz;
};
-HWC2::Error findDisplayConfigs(std::vector<DisplayConfig>* configs);
+struct DisplayMultiConfigs {
+ int id;
+ int activeConfigId;
+ // Modes that this display can be configured to use.
+ std::vector<DisplayConfig> configs;
+};
+
+HWC2::Error findDisplays(std::vector<DisplayMultiConfigs>& displays);
} // namespace android
-#endif
\ No newline at end of file
+#endif
diff --git a/system/hwc2/GuestComposer.h b/system/hwc2/GuestComposer.h
index ff202cc..db6bf3e 100644
--- a/system/hwc2/GuestComposer.h
+++ b/system/hwc2/GuestComposer.h
@@ -57,6 +57,10 @@
HWC2::Error presentDisplay(Display* display,
int32_t* outPresentFence) override;
+ HWC2::Error onActiveConfigChange(Display* /*display*/) override {
+ return HWC2::Error::None;
+ };
+
private:
struct DisplayConfig {
int width;
diff --git a/system/hwc2/HostComposer.cpp b/system/hwc2/HostComposer.cpp
index f028818..9501bb6 100644
--- a/system/hwc2/HostComposer.cpp
+++ b/system/hwc2/HostComposer.cpp
@@ -198,15 +198,13 @@
return error;
}
- auto it = mDisplayInfos.find(displayId);
- if (it != mDisplayInfos.end()) {
- ALOGE("%s: display:%" PRIu64 " already created?", __FUNCTION__, displayId);
- }
-
HostComposerDisplayInfo& displayInfo = mDisplayInfos[displayId];
displayInfo.hostDisplayId = hostDisplayId;
+ if (displayInfo.compositionResultBuffer) {
+ FreeDisplayColorBuffer(displayInfo.compositionResultBuffer);
+ }
displayInfo.compositionResultBuffer =
AllocateDisplayColorBuffer(displayWidth, displayHeight);
if (displayInfo.compositionResultBuffer == nullptr) {
@@ -682,4 +680,15 @@
hostCon->unlock();
}
+HWC2::Error HostComposer::onActiveConfigChange(Display* display) {
+ DEBUG_LOG("%s: display:%" PRIu64, __FUNCTION__, display->getId());
+ HWC2::Error error = createHostComposerDisplayInfo(display, display->getId());
+ if (error != HWC2::Error::None) {
+ ALOGE("%s failed to update host info for display:%" PRIu64,
+ __FUNCTION__, display->getId());
+ return error;
+ }
+ return HWC2::Error::None;
+}
+
} // namespace android
diff --git a/system/hwc2/HostComposer.h b/system/hwc2/HostComposer.h
index c6c9082..f722ffc 100644
--- a/system/hwc2/HostComposer.h
+++ b/system/hwc2/HostComposer.h
@@ -53,6 +53,8 @@
HWC2::Error presentDisplay(Display* display,
int32_t* outPresentFence) override;
+ HWC2::Error onActiveConfigChange(Display* display) override;
+
private:
HWC2::Error createHostComposerDisplayInfo(Display* display,
uint32_t hostDisplayId);
diff --git a/system/renderControl_enc/renderControl_client_context.cpp b/system/renderControl_enc/renderControl_client_context.cpp
index eb5c921..27dd37e 100644
--- a/system/renderControl_enc/renderControl_client_context.cpp
+++ b/system/renderControl_enc/renderControl_client_context.cpp
@@ -75,6 +75,9 @@
rcCreateDisplayById = (rcCreateDisplayById_client_proc_t) getProc("rcCreateDisplayById", userData);
rcSetDisplayPoseDpi = (rcSetDisplayPoseDpi_client_proc_t) getProc("rcSetDisplayPoseDpi", userData);
rcReadColorBufferDMA = (rcReadColorBufferDMA_client_proc_t) getProc("rcReadColorBufferDMA", userData);
+ rcGetFBDisplayConfigsCount = (rcGetFBDisplayConfigsCount_client_proc_t) getProc("rcGetFBDisplayConfigsCount", userData);
+ rcGetFBDisplayConfigsParam = (rcGetFBDisplayConfigsParam_client_proc_t) getProc("rcGetFBDisplayConfigsParam", userData);
+ rcGetFBDisplayActiveConfig = (rcGetFBDisplayActiveConfig_client_proc_t) getProc("rcGetFBDisplayActiveConfig", userData);
return 0;
}
diff --git a/system/renderControl_enc/renderControl_client_context.h b/system/renderControl_enc/renderControl_client_context.h
index 395e4bb..862a70d 100644
--- a/system/renderControl_enc/renderControl_client_context.h
+++ b/system/renderControl_enc/renderControl_client_context.h
@@ -75,6 +75,9 @@
rcCreateDisplayById_client_proc_t rcCreateDisplayById;
rcSetDisplayPoseDpi_client_proc_t rcSetDisplayPoseDpi;
rcReadColorBufferDMA_client_proc_t rcReadColorBufferDMA;
+ rcGetFBDisplayConfigsCount_client_proc_t rcGetFBDisplayConfigsCount;
+ rcGetFBDisplayConfigsParam_client_proc_t rcGetFBDisplayConfigsParam;
+ rcGetFBDisplayActiveConfig_client_proc_t rcGetFBDisplayActiveConfig;
virtual ~renderControl_client_context_t() {}
typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
diff --git a/system/renderControl_enc/renderControl_client_proc.h b/system/renderControl_enc/renderControl_client_proc.h
index 2e52898..2c28127 100644
--- a/system/renderControl_enc/renderControl_client_proc.h
+++ b/system/renderControl_enc/renderControl_client_proc.h
@@ -77,6 +77,9 @@
typedef int (renderControl_APIENTRY *rcCreateDisplayById_client_proc_t) (void * ctx, uint32_t);
typedef int (renderControl_APIENTRY *rcSetDisplayPoseDpi_client_proc_t) (void * ctx, uint32_t, GLint, GLint, uint32_t, uint32_t, uint32_t);
typedef int (renderControl_APIENTRY *rcReadColorBufferDMA_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*, uint32_t);
+typedef int (renderControl_APIENTRY *rcGetFBDisplayConfigsCount_client_proc_t) (void * ctx);
+typedef int (renderControl_APIENTRY *rcGetFBDisplayConfigsParam_client_proc_t) (void * ctx, int, EGLint);
+typedef int (renderControl_APIENTRY *rcGetFBDisplayActiveConfig_client_proc_t) (void * ctx);
#endif
diff --git a/system/renderControl_enc/renderControl_enc.cpp b/system/renderControl_enc/renderControl_enc.cpp
index 5efed5f..7fdcab9 100644
--- a/system/renderControl_enc/renderControl_enc.cpp
+++ b/system/renderControl_enc/renderControl_enc.cpp
@@ -2523,8 +2523,8 @@
if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
- // stream->readback(pixels, __size_pixels);
- // if (useChecksum) checksumCalculator->addBuffer(pixels, __size_pixels);
+ // Skip readback for var pixels as it's DMA
+ // Skip checksum for var pixels as it's DMA
int retval;
stream->readback(&retval, 4);
@@ -2542,6 +2542,128 @@
return retval;
}
+int rcGetFBDisplayConfigsCount_enc(void *self )
+{
+ AEMU_SCOPED_TRACE("rcGetFBDisplayConfigsCount encode");
+
+ renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_rcGetFBDisplayConfigsCount;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+ int retval;
+ stream->readback(&retval, 4);
+ if (useChecksum) checksumCalculator->addBuffer(&retval, 4);
+ if (useChecksum) {
+ unsigned char *checksumBufPtr = NULL;
+ unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+ if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+ stream->readback(checksumBufPtr, checksumSize);
+ if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+ ALOGE("rcGetFBDisplayConfigsCount: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+ return retval;
+}
+
+int rcGetFBDisplayConfigsParam_enc(void *self , int configId, EGLint param)
+{
+ AEMU_SCOPED_TRACE("rcGetFBDisplayConfigsParam encode");
+
+ renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 4 + 4;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_rcGetFBDisplayConfigsParam;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &configId, 4); ptr += 4;
+ memcpy(ptr, ¶m, 4); ptr += 4;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+ int retval;
+ stream->readback(&retval, 4);
+ if (useChecksum) checksumCalculator->addBuffer(&retval, 4);
+ if (useChecksum) {
+ unsigned char *checksumBufPtr = NULL;
+ unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+ if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+ stream->readback(checksumBufPtr, checksumSize);
+ if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+ ALOGE("rcGetFBDisplayConfigsParam: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+ return retval;
+}
+
+int rcGetFBDisplayActiveConfig_enc(void *self )
+{
+ AEMU_SCOPED_TRACE("rcGetFBDisplayActiveConfig encode");
+
+ renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_rcGetFBDisplayActiveConfig;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+ int retval;
+ stream->readback(&retval, 4);
+ if (useChecksum) checksumCalculator->addBuffer(&retval, 4);
+ if (useChecksum) {
+ unsigned char *checksumBufPtr = NULL;
+ unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+ if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+ stream->readback(checksumBufPtr, checksumSize);
+ if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+ ALOGE("rcGetFBDisplayActiveConfig: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+ return retval;
+}
+
} // namespace
renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -2614,5 +2736,8 @@
this->rcCreateDisplayById = &rcCreateDisplayById_enc;
this->rcSetDisplayPoseDpi = &rcSetDisplayPoseDpi_enc;
this->rcReadColorBufferDMA = &rcReadColorBufferDMA_enc;
+ this->rcGetFBDisplayConfigsCount = &rcGetFBDisplayConfigsCount_enc;
+ this->rcGetFBDisplayConfigsParam = &rcGetFBDisplayConfigsParam_enc;
+ this->rcGetFBDisplayActiveConfig = &rcGetFBDisplayActiveConfig_enc;
}
diff --git a/system/renderControl_enc/renderControl_entry.cpp b/system/renderControl_enc/renderControl_entry.cpp
index 5b2bedd..e756322 100644
--- a/system/renderControl_enc/renderControl_entry.cpp
+++ b/system/renderControl_enc/renderControl_entry.cpp
@@ -70,6 +70,9 @@
int rcCreateDisplayById(uint32_t displayId);
int rcSetDisplayPoseDpi(uint32_t displayId, GLint x, GLint y, uint32_t w, uint32_t h, uint32_t dpi);
int rcReadColorBufferDMA(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels, uint32_t pixels_size);
+ int rcGetFBDisplayConfigsCount();
+ int rcGetFBDisplayConfigsParam(int configId, EGLint param);
+ int rcGetFBDisplayActiveConfig();
};
#ifndef GET_CONTEXT
@@ -468,3 +471,21 @@
return ctx->rcReadColorBufferDMA(ctx, colorbuffer, x, y, width, height, format, type, pixels, pixels_size);
}
+int rcGetFBDisplayConfigsCount()
+{
+ GET_CONTEXT;
+ return ctx->rcGetFBDisplayConfigsCount(ctx);
+}
+
+int rcGetFBDisplayConfigsParam(int configId, EGLint param)
+{
+ GET_CONTEXT;
+ return ctx->rcGetFBDisplayConfigsParam(ctx, configId, param);
+}
+
+int rcGetFBDisplayActiveConfig()
+{
+ GET_CONTEXT;
+ return ctx->rcGetFBDisplayActiveConfig(ctx);
+}
+
diff --git a/system/renderControl_enc/renderControl_ftable.h b/system/renderControl_enc/renderControl_ftable.h
index 577cbae..9a0f9e9 100644
--- a/system/renderControl_enc/renderControl_ftable.h
+++ b/system/renderControl_enc/renderControl_ftable.h
@@ -73,6 +73,9 @@
{"rcCreateDisplayById", (void*)rcCreateDisplayById},
{"rcSetDisplayPoseDpi", (void*)rcSetDisplayPoseDpi},
{"rcReadColorBufferDMA", (void*)rcReadColorBufferDMA},
+ {"rcGetFBDisplayConfigsCount", (void*)rcGetFBDisplayConfigsCount},
+ {"rcGetFBDisplayConfigsParam", (void*)rcGetFBDisplayConfigsParam},
+ {"rcGetFBDisplayActiveConfig", (void*)rcGetFBDisplayActiveConfig},
};
static const int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name);
diff --git a/system/renderControl_enc/renderControl_opcodes.h b/system/renderControl_enc/renderControl_opcodes.h
index 00249d6..cf4ff82 100644
--- a/system/renderControl_enc/renderControl_opcodes.h
+++ b/system/renderControl_enc/renderControl_opcodes.h
@@ -68,7 +68,10 @@
#define OP_rcCreateDisplayById 10062
#define OP_rcSetDisplayPoseDpi 10063
#define OP_rcReadColorBufferDMA 10064
-#define OP_last 10065
+#define OP_rcGetFBDisplayConfigsCount 10065
+#define OP_rcGetFBDisplayConfigsParam 10066
+#define OP_rcGetFBDisplayActiveConfig 10067
+#define OP_last 10068
#endif