Render boot animation with same size as framebuffer

When ro.surface_flinger.max_graphics_{width|height} is
set the framebuffer size is limited by this property.
However the boot animation size matches the display active
mode size which can cause it to be off-center or partially
visible.

This change limits the boot animation surface size with
accordance with ro.surface_flinger.max_graphics_width.

Bug: 153991408
Test: manual
Change-Id: Idfd1c9adc1f6b10f44bc04ec2078dbc823f28ed6
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 3bcabe5..bb2de17 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -349,6 +349,25 @@
     return config;
 }
 
+ui::Size BootAnimation::limitSurfaceSize(int width, int height) const {
+    ui::Size limited(width, height);
+    bool wasLimited = false;
+    const float aspectRatio = float(width) / float(height);
+    if (mMaxWidth != 0 && width > mMaxWidth) {
+        limited.height = mMaxWidth / aspectRatio;
+        limited.width = mMaxWidth;
+        wasLimited = true;
+    }
+    if (mMaxHeight != 0 && limited.height > mMaxHeight) {
+        limited.height = mMaxHeight;
+        limited.width = mMaxHeight * aspectRatio;
+        wasLimited = true;
+    }
+    SLOGV_IF(wasLimited, "Surface size has been limited to [%dx%d] from [%dx%d]",
+             limited.width, limited.height, width, height);
+    return limited;
+}
+
 status_t BootAnimation::readyToRun() {
     mAssets.addDefaultAssets();
 
@@ -362,8 +381,10 @@
     if (error != NO_ERROR)
         return error;
 
-    const ui::Size& resolution = displayConfig.resolution;
-
+    mMaxWidth = android::base::GetIntProperty("ro.surface_flinger.max_graphics_width", 0);
+    mMaxHeight = android::base::GetIntProperty("ro.surface_flinger.max_graphics_height", 0);
+    ui::Size resolution = displayConfig.resolution;
+    resolution = limitSurfaceSize(resolution.width, resolution.height);
     // create the native surface
     sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
             resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
@@ -459,8 +480,9 @@
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglDestroySurface(mDisplay, mSurface);
 
-    mWidth = newWidth;
-    mHeight = newHeight;
+    const auto limitedSize = limitSurfaceSize(newWidth, newHeight);
+    mWidth = limitedSize.width;
+    mHeight = limitedSize.height;
 
     SurfaceComposerClient::Transaction t;
     t.setSize(mFlingerSurfaceControl, mWidth, mHeight);
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 36cd91b..6ba7fd4 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -170,6 +170,7 @@
     bool findBootAnimationFileInternal(const std::vector<std::string>& files);
     bool preloadAnimation();
     EGLConfig getEglConfig(const EGLDisplay&);
+    ui::Size limitSurfaceSize(int width, int height) const;
     void resizeSurface(int newWidth, int newHeight);
 
     void checkExit();
@@ -181,6 +182,8 @@
     Texture     mAndroid[2];
     int         mWidth;
     int         mHeight;
+    int         mMaxWidth = 0;
+    int         mMaxHeight = 0;
     int         mCurrentInset;
     int         mTargetInset;
     bool        mUseNpotTextures = false;