Merge "Use median instead of mean for sampling border luma" into rvc-dev am: 3e7dd91752 am: e595386782
Change-Id: Ib5a6cb2139038ff25fe7fb04b2b366f3a9a00897
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user