From f9f5822d8d391e9a4e053f89ef7b7944b26351bb Mon Sep 17 00:00:00 2001 From: Andrew Zeng Date: Tue, 8 Nov 2022 11:10:48 -0800 Subject: Fix boot animation alpha multiplication computations Previously, this was resulting in the output color roughtly as output_n = color_n * mask_n^2 * (mask_0 + mask_1 + mask_2 + mask_3) where n is a color channel between 0 and 3. This caused extra aliasing around edges, since the alpha fades too quickly along an edge. Bug: 239632466 Bug: 258246539 Test: verify pixel values for boot animation match mask on watch + phone Test: modify uFade value, verify pixel colors match Change-Id: I86742a181576e684aa698a190a8766f4223de799 --- cmds/bootanimation/BootAnimation.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'cmds/bootanimation/BootAnimation.cpp') diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 50c8e933d25f..3f6046f01f11 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -132,14 +132,14 @@ static const char IMAGE_FRAG_DYNAMIC_COLORING_SHADER_SOURCE[] = R"( uniform sampler2D uTexture; uniform float uFade; uniform float uColorProgress; - uniform vec4 uStartColor0; - uniform vec4 uStartColor1; - uniform vec4 uStartColor2; - uniform vec4 uStartColor3; - uniform vec4 uEndColor0; - uniform vec4 uEndColor1; - uniform vec4 uEndColor2; - uniform vec4 uEndColor3; + uniform vec3 uStartColor0; + uniform vec3 uStartColor1; + uniform vec3 uStartColor2; + uniform vec3 uStartColor3; + uniform vec3 uEndColor0; + uniform vec3 uEndColor1; + uniform vec3 uEndColor2; + uniform vec3 uEndColor3; varying highp vec2 vUv; void main() { vec4 mask = texture2D(uTexture, vUv); @@ -152,12 +152,12 @@ static const char IMAGE_FRAG_DYNAMIC_COLORING_SHADER_SOURCE[] = R"( * step(cWhiteMaskThreshold, g) * step(cWhiteMaskThreshold, b) * step(cWhiteMaskThreshold, a); - vec4 color = r * mix(uStartColor0, uEndColor0, uColorProgress) + vec3 color = r * mix(uStartColor0, uEndColor0, uColorProgress) + g * mix(uStartColor1, uEndColor1, uColorProgress) + b * mix(uStartColor2, uEndColor2, uColorProgress) + a * mix(uStartColor3, uEndColor3, uColorProgress); - color = mix(color, vec4(vec3((r + g + b + a) * 0.25), 1.0), useWhiteMask); - gl_FragColor = vec4(color.x, color.y, color.z, (1.0 - uFade)) * color.a; + color = mix(color, vec3((r + g + b + a) * 0.25), useWhiteMask); + gl_FragColor = vec4(color.x, color.y, color.z, (1.0 - uFade)); })"; static const char IMAGE_FRAG_SHADER_SOURCE[] = R"( precision mediump float; @@ -1440,12 +1440,12 @@ void BootAnimation::initDynamicColors() { for (int i = 0; i < DYNAMIC_COLOR_COUNT; i++) { float *startColor = mAnimation->startColors[i]; float *endColor = mAnimation->endColors[i]; - glUniform4f(glGetUniformLocation(mImageShader, + glUniform3f(glGetUniformLocation(mImageShader, (U_START_COLOR_PREFIX + std::to_string(i)).c_str()), - startColor[0], startColor[1], startColor[2], 1 /* alpha */); - glUniform4f(glGetUniformLocation(mImageShader, + startColor[0], startColor[1], startColor[2]); + glUniform3f(glGetUniformLocation(mImageShader, (U_END_COLOR_PREFIX + std::to_string(i)).c_str()), - endColor[0], endColor[1], endColor[2], 1 /* alpha */); + endColor[0], endColor[1], endColor[2]); } mImageColorProgressLocation = glGetUniformLocation(mImageShader, U_COLOR_PROGRESS); } -- cgit v1.2.3-59-g8ed1b From a166f0128e3bba1a29bca49a1a6cf8d2fa94e2f6 Mon Sep 17 00:00:00 2001 From: Mariia Sandrikova Date: Sat, 10 Dec 2022 02:32:14 +0000 Subject: Set orientation for boot animation and default display rotation. Change the default display rotation value and boot animation orientation to the value specified in the sysprop ro.bootanim.set_orientation_. Four values are supported: ORIENTATION_0, ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270. If the value isn't specified or is ORIENTATION_0, nothing will be changed. This is needed to support having default rotation behavior and boot animation in orientation different from the natural device orientation. For example, on tablets that may want to keep natural orientation portrait for applications compatibility but have landscape orientation as a default choice from the UX perspective. Bug: 260627934 Test: manual test with all 4 values and atest WmTests still pass Change-Id: I322919999ef787ff2c149293d7e1c7e669796c9a --- cmds/bootanimation/BootAnimation.cpp | 53 ++++++++++++++++++++++ cmds/bootanimation/BootAnimation.h | 4 ++ .../java/com/android/server/wm/DisplayContent.java | 2 +- .../com/android/server/wm/DisplayRotation.java | 39 ++++++++++++++-- .../android/server/wm/DisplayRotationTests.java | 8 +++- 5 files changed, 99 insertions(+), 7 deletions(-) (limited to 'cmds/bootanimation/BootAnimation.cpp') diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 3f6046f01f11..53a84bd1b21e 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -583,6 +583,15 @@ status_t BootAnimation::readyToRun() { mFlingerSurface = s; mTargetInset = -1; + // Rotate the boot animation according to the value specified in the sysprop + // ro.bootanim.set_orientation_. Four values are supported: ORIENTATION_0, + // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270. + // If the value isn't specified or is ORIENTATION_0, nothing will be changed. + // This is needed to support having boot animation in orientations different from the natural + // device orientation. For example, on tablets that may want to keep natural orientation + // portrait for applications compatibility and to have the boot animation in landscape. + rotateAwayFromNaturalOrientationIfNeeded(); + projectSceneToWindow(); // Register a display event receiver @@ -596,6 +605,50 @@ status_t BootAnimation::readyToRun() { return NO_ERROR; } +void BootAnimation::rotateAwayFromNaturalOrientationIfNeeded() { + const auto orientation = parseOrientationProperty(); + + if (orientation == ui::ROTATION_0) { + // Do nothing if the sysprop isn't set or is set to ROTATION_0. + return; + } + + if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) { + std::swap(mWidth, mHeight); + std::swap(mInitWidth, mInitHeight); + mFlingerSurfaceControl->updateDefaultBufferSize(mWidth, mHeight); + } + + Rect displayRect(0, 0, mWidth, mHeight); + Rect layerStackRect(0, 0, mWidth, mHeight); + + SurfaceComposerClient::Transaction t; + t.setDisplayProjection(mDisplayToken, orientation, layerStackRect, displayRect); + t.apply(); +} + +ui::Rotation BootAnimation::parseOrientationProperty() { + const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds(); + if (displayIds.size() == 0) { + return ui::ROTATION_0; + } + const auto displayId = displayIds[0]; + const auto syspropName = [displayId] { + std::stringstream ss; + ss << "ro.bootanim.set_orientation_" << displayId.value; + return ss.str(); + }(); + const auto syspropValue = android::base::GetProperty(syspropName, "ORIENTATION_0"); + if (syspropValue == "ORIENTATION_90") { + return ui::ROTATION_90; + } else if (syspropValue == "ORIENTATION_180") { + return ui::ROTATION_180; + } else if (syspropValue == "ORIENTATION_270") { + return ui::ROTATION_270; + } + return ui::ROTATION_0; +} + void BootAnimation::projectSceneToWindow() { glViewport(0, 0, mWidth, mHeight); glScissor(0, 0, mWidth, mHeight); diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index 86582053b4e1..8683b71a3762 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -30,6 +30,8 @@ #include #include +#include + #include #include @@ -200,6 +202,8 @@ private: ui::Size limitSurfaceSize(int width, int height) const; void resizeSurface(int newWidth, int newHeight); void projectSceneToWindow(); + void rotateAwayFromNaturalOrientationIfNeeded(); + ui::Rotation parseOrientationProperty(); bool shouldStopPlayingPart(const Animation::Part& part, int fadedFramesCount, int lastDisplayedProgress); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4c499861cb9a..4c19322a9790 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1125,7 +1125,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } mDisplayPolicy = new DisplayPolicy(mWmService, this); - mDisplayRotation = new DisplayRotation(mWmService, this); + mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address); mDeviceStateController = new DeviceStateController(mWmService.mContext, mWmService.mH, newFoldState -> { diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 185e06eecabb..4fb137b847b0 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -58,6 +58,7 @@ import android.provider.Settings; import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; +import android.view.DisplayAddress; import android.view.IWindowManager; import android.view.Surface; import android.window.TransitionRequestInfo; @@ -211,15 +212,16 @@ public class DisplayRotation { private boolean mDemoHdmiRotationLock; private boolean mDemoRotationLock; - DisplayRotation(WindowManagerService service, DisplayContent displayContent) { - this(service, displayContent, displayContent.getDisplayPolicy(), + DisplayRotation(WindowManagerService service, DisplayContent displayContent, + DisplayAddress displayAddress) { + this(service, displayContent, displayAddress, displayContent.getDisplayPolicy(), service.mDisplayWindowSettings, service.mContext, service.getWindowManagerLock()); } @VisibleForTesting DisplayRotation(WindowManagerService service, DisplayContent displayContent, - DisplayPolicy displayPolicy, DisplayWindowSettings displayWindowSettings, - Context context, Object lock) { + DisplayAddress displayAddress, DisplayPolicy displayPolicy, + DisplayWindowSettings displayWindowSettings, Context context, Object lock) { mService = service; mDisplayContent = displayContent; mDisplayPolicy = displayPolicy; @@ -235,6 +237,8 @@ public class DisplayRotation { mDeskDockRotation = readRotation(R.integer.config_deskDockRotation); mUndockedHdmiRotation = readRotation(R.integer.config_undockedHdmiRotation); + mRotation = readDefaultDisplayRotation(displayAddress); + if (isDefaultDisplay) { final Handler uiHandler = UiThread.getHandler(); mOrientationListener = new OrientationListener(mContext, uiHandler); @@ -248,6 +252,33 @@ public class DisplayRotation { } } + // Change the default value to the value specified in the sysprop + // ro.bootanim.set_orientation_. Four values are supported: ORIENTATION_0, + // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270. + // If the value isn't specified or is ORIENTATION_0, nothing will be changed. + // This is needed to support having default orientation different from the natural + // device orientation. For example, on tablets that may want to keep natural orientation + // portrait for applications compatibility but have landscape orientation as a default choice + // from the UX perspective. + @Surface.Rotation + private int readDefaultDisplayRotation(DisplayAddress displayAddress) { + if (!(displayAddress instanceof DisplayAddress.Physical)) { + return Surface.ROTATION_0; + } + final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) displayAddress; + String syspropValue = SystemProperties.get( + "ro.bootanim.set_orientation_" + physicalAddress.getPhysicalDisplayId(), + "ORIENTATION_0"); + if (syspropValue.equals("ORIENTATION_90")) { + return Surface.ROTATION_90; + } else if (syspropValue.equals("ORIENTATION_180")) { + return Surface.ROTATION_180; + } else if (syspropValue.equals("ORIENTATION_270")) { + return Surface.ROTATION_270; + } + return Surface.ROTATION_0; + } + private int readRotation(int resID) { try { final int rotation = mContext.getResources().getInteger(resID); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index b45c37f9da0c..491f876dceed 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -60,6 +60,7 @@ import android.os.PowerManagerInternal; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; import android.provider.Settings; +import android.view.DisplayAddress; import android.view.Surface; import android.view.WindowManager; @@ -101,6 +102,7 @@ public class DisplayRotationTests { private static WindowManagerService sMockWm; private DisplayContent mMockDisplayContent; private DisplayPolicy mMockDisplayPolicy; + private DisplayAddress mMockDisplayAddress; private Context mMockContext; private Resources mMockRes; private SensorManager mMockSensorManager; @@ -1091,9 +1093,11 @@ public class DisplayRotationTests { when(mMockResolver.acquireProvider(Settings.AUTHORITY)) .thenReturn(mFakeSettingsProvider.getIContentProvider()); + mMockDisplayAddress = mock(DisplayAddress.class); + mMockDisplayWindowSettings = mock(DisplayWindowSettings.class); - mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayPolicy, - mMockDisplayWindowSettings, mMockContext, new Object()); + mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayAddress, + mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object()); reset(sMockWm); captureObservers(); -- cgit v1.2.3-59-g8ed1b