Merge "Use median instead of mean for sampling border luma" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-02-28 05:08:52 +00:00
committed by Android (Google) Code Review
3 changed files with 37 additions and 19 deletions

View File

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

View File

@@ -26,6 +26,8 @@ import android.view.Display;
import android.view.Surface; import android.view.Surface;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import java.util.Arrays;
/** Helper functions for the {@link com.android.server.wm.ScreenRotationAnimation} class*/ /** Helper functions for the {@link com.android.server.wm.ScreenRotationAnimation} class*/
public class RotationAnimationUtils { public class RotationAnimationUtils {
@@ -35,31 +37,35 @@ public class RotationAnimationUtils {
* luminance at the borders of the bitmap * luminance at the borders of the bitmap
* @return the average luminance of all the pixels 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); Bitmap hwBitmap = Bitmap.wrapHardwareBuffer(graphicBuffer, colorSpace);
if (hwBitmap == null) { if (hwBitmap == null) {
return 0; return 0;
} }
Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false); Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false);
float totalLuma = 0;
int height = swaBitmap.getHeight(); int height = swaBitmap.getHeight();
int width = swaBitmap.getWidth(); int width = swaBitmap.getWidth();
float[] borderLumas = new float[2 * width + 2 * height];
int i; int i;
for (i = 0; i < width; i++) { int index = 0;
totalLuma += swaBitmap.getColor(i, 0).luminance(); for (i = 0; i < width; i++, index += 2) {
totalLuma += swaBitmap.getColor(i, height - 1).luminance(); borderLumas[index] = swaBitmap.getColor(i, 0).luminance();
borderLumas[index + 1] = swaBitmap.getColor(i, height - 1).luminance();
} }
for (i = 0; i < height; i++) { for (i = 0; i < height; i++, index += 2) {
totalLuma += swaBitmap.getColor(0, i).luminance(); borderLumas[index] = swaBitmap.getColor(0, i).luminance();
totalLuma += swaBitmap.getColor(width - 1, 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}. * 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) { public static float getLumaOfSurfaceControl(Display display, SurfaceControl surfaceControl) {
if (surfaceControl == null) { if (surfaceControl == null) {
@@ -75,7 +81,7 @@ public class RotationAnimationUtils {
return 0; return 0;
} }
return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(), return RotationAnimationUtils.getMedianBorderLuma(buffer.getGraphicBuffer(),
buffer.getColorSpace()); buffer.getColorSpace());
} }

View File

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