Merge "Use median instead of mean for sampling border luma" into rvc-dev am: 3e7dd91752

Change-Id: I64bd708b2c6615561fc286e43350212aebe6b810
This commit is contained in:
Automerger Merge Worker
2020-02-28 05:15:55 +00:00
3 changed files with 37 additions and 19 deletions

View File

@@ -205,7 +205,7 @@ class ScreenRotationAnimation {
SurfaceControl.ScreenshotGraphicBuffer gb =
mService.mDisplayManagerInternal.screenshot(displayId);
if (gb != null) {
mStartLuma = RotationAnimationUtils.getAvgBorderLuma(gb.getGraphicBuffer(),
mStartLuma = RotationAnimationUtils.getMedianBorderLuma(gb.getGraphicBuffer(),
gb.getColorSpace());
try {
surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),

View File

@@ -26,6 +26,8 @@ import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
import java.util.Arrays;
/** Helper functions for the {@link com.android.server.wm.ScreenRotationAnimation} class*/
public class RotationAnimationUtils {
@@ -35,31 +37,35 @@ public class RotationAnimationUtils {
* luminance at the borders of the bitmap
* @return the average luminance of all the pixels at the borders of the bitmap
*/
public static float getAvgBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
public static float getMedianBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
Bitmap hwBitmap = Bitmap.wrapHardwareBuffer(graphicBuffer, colorSpace);
if (hwBitmap == null) {
return 0;
}
Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false);
float totalLuma = 0;
int height = swaBitmap.getHeight();
int width = swaBitmap.getWidth();
float[] borderLumas = new float[2 * width + 2 * height];
int i;
for (i = 0; i < width; i++) {
totalLuma += swaBitmap.getColor(i, 0).luminance();
totalLuma += swaBitmap.getColor(i, height - 1).luminance();
int index = 0;
for (i = 0; i < width; i++, index += 2) {
borderLumas[index] = swaBitmap.getColor(i, 0).luminance();
borderLumas[index + 1] = swaBitmap.getColor(i, height - 1).luminance();
}
for (i = 0; i < height; i++) {
totalLuma += swaBitmap.getColor(0, i).luminance();
totalLuma += swaBitmap.getColor(width - 1, i).luminance();
for (i = 0; i < height; i++, index += 2) {
borderLumas[index] = swaBitmap.getColor(0, i).luminance();
borderLumas[index + 1] = swaBitmap.getColor(width - 1, i).luminance();
}
return totalLuma / (2 * width + 2 * height);
// Oh, is this too simple and inefficient for you?
// How about implementing a O(n) solution? https://en.wikipedia.org/wiki/Median_of_medians
Arrays.sort(borderLumas);
return borderLumas[borderLumas.length / 2];
}
/**
* Gets the average border luma by taking a screenshot of the {@param surfaceControl}.
* @see #getAvgBorderLuma(GraphicBuffer, ColorSpace)
* @see #getMedianBorderLuma(GraphicBuffer, ColorSpace)
*/
public static float getLumaOfSurfaceControl(Display display, SurfaceControl surfaceControl) {
if (surfaceControl == null) {
@@ -75,7 +81,7 @@ public class RotationAnimationUtils {
return 0;
}
return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(),
return RotationAnimationUtils.getMedianBorderLuma(buffer.getGraphicBuffer(),
buffer.getColorSpace());
}

View File

@@ -50,7 +50,7 @@ public class RotationAnimationUtilsTest {
public void blackLuma() {
Bitmap swBitmap = createBitmap(0);
GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
assertEquals(0, borderLuma, 0);
}
@@ -58,7 +58,15 @@ public class RotationAnimationUtilsTest {
public void whiteLuma() {
Bitmap swBitmap = createBitmap(1);
GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
assertEquals(1, borderLuma, 0);
}
@Test
public void unevenBitmapDimens() {
Bitmap swBitmap = createBitmap(1, BITMAP_WIDTH + 1, BITMAP_HEIGHT + 1);
GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
assertEquals(1, borderLuma, 0);
}
@@ -67,7 +75,7 @@ public class RotationAnimationUtilsTest {
Bitmap swBitmap = createBitmap(1);
setBorderLuma(swBitmap, 0);
GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
assertEquals(0, borderLuma, 0);
}
@@ -76,7 +84,7 @@ public class RotationAnimationUtilsTest {
Bitmap swBitmap = createBitmap(0);
setBorderLuma(swBitmap, 1);
GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap);
float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace);
float borderLuma = RotationAnimationUtils.getMedianBorderLuma(gb, mColorSpace);
assertEquals(1, borderLuma, 0);
}
@@ -123,9 +131,13 @@ public class RotationAnimationUtilsTest {
}
private Bitmap createBitmap(float luma) {
Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, ARGB_8888);
for (int i = 0; i < BITMAP_WIDTH; i++) {
for (int j = 0; j < BITMAP_HEIGHT; j++) {
return createBitmap(luma, BITMAP_WIDTH, BITMAP_HEIGHT);
}
private Bitmap createBitmap(float luma, int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, ARGB_8888);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
bitmap.setPixel(i, j, Color.argb(1, luma, luma, luma));
}
}