Allow GPU composition to occur at a lower resolution
Add a vendor-specified system property to allow GPU fallback composition to occur at a lower resolution than the display mode resolution.
Bug: 144574809
Test: Tested with sysprop disabled, and tested backport in Android Q with sysprop enabled. Unable to test on Android R due to device issues.
Change-Id: I02948ce72f49d20416d0e4dd45a4cffe99e28820
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 36544b6..aeffb0e 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -57,9 +57,12 @@
*/
FramebufferSurface::FramebufferSurface(HWComposer& hwc, DisplayId displayId,
- const sp<IGraphicBufferConsumer>& consumer)
+ const sp<IGraphicBufferConsumer>& consumer,
+ uint32_t maxWidth, uint32_t maxHeight)
: ConsumerBase(consumer),
mDisplayId(displayId),
+ mMaxWidth(maxWidth),
+ mMaxHeight(maxHeight),
mCurrentBufferSlot(-1),
mCurrentBuffer(),
mCurrentFence(Fence::NO_FENCE),
@@ -75,14 +78,16 @@
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
const auto& activeConfig = mHwc.getActiveConfig(displayId);
- mConsumer->setDefaultBufferSize(activeConfig->getWidth(),
- activeConfig->getHeight());
+ ui::Size limitedSize =
+ limitFramebufferSize(activeConfig->getWidth(), activeConfig->getHeight());
+ mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
mConsumer->setMaxAcquiredBufferCount(
SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
}
-void FramebufferSurface::resizeBuffers(const uint32_t width, const uint32_t height) {
- mConsumer->setDefaultBufferSize(width, height);
+void FramebufferSurface::resizeBuffers(uint32_t width, uint32_t height) {
+ ui::Size limitedSize = limitFramebufferSize(width, height);
+ mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
}
status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
@@ -177,6 +182,29 @@
}
}
+ui::Size FramebufferSurface::limitFramebufferSize(uint32_t width, uint32_t height) {
+ // TODO(b/149495759): Use the ui::Size constructor once it no longer is broken.
+ ui::Size framebufferSize;
+ framebufferSize.width = width;
+ framebufferSize.height = height;
+ bool wasLimited = true;
+ if (width > mMaxWidth && mMaxWidth != 0) {
+ float aspectRatio = float(width) / float(height);
+ framebufferSize.height = mMaxWidth / aspectRatio;
+ framebufferSize.width = mMaxWidth;
+ wasLimited = true;
+ }
+ if (height > mMaxHeight && mMaxHeight != 0) {
+ float aspectRatio = float(width) / float(height);
+ framebufferSize.height = mMaxHeight;
+ framebufferSize.width = mMaxHeight * aspectRatio;
+ wasLimited = true;
+ }
+ ALOGI_IF(wasLimited, "framebuffer size has been limited to [%dx%d] from [%dx%d]",
+ framebufferSize.width, framebufferSize.height, width, height);
+ return framebufferSize;
+}
+
void FramebufferSurface::dumpAsString(String8& result) const {
Mutex::Autolock lock(mMutex);
result.appendFormat(" FramebufferSurface: dataspace: %s(%d)\n",