From 7f6519f0f13bf3a07800ddb48c92bafca70ed989 Mon Sep 17 00:00:00 2001 From: Ahan Wu Date: Wed, 10 Apr 2019 23:16:39 +0800 Subject: [PATCH] Reset the texture coordinates and also take aspect ratio into account. Reset (clean) the texture coordinates before we are going to adjust the texture coordinates. This cl also takes aspect ratio into account to prevent the bitmap from being stretched due to the adjusted texture coordinates. Bug: 124355528 Bug: 126398998 Test: Manually set appropriate wallpaper, rotates the device between portrait and landscape back and forth. Change-Id: I76d523f6506174a9655d6ff194394f40cf78d848 --- .../glwallpaper/ImageGLWallpaper.java | 91 +++++++++++-------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java index 21406e57ad7b7..d935466757de1 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java @@ -34,7 +34,6 @@ import static android.opengl.GLES20.glVertexAttribPointer; import android.graphics.Bitmap; import android.opengl.GLUtils; -import android.os.Build; import android.util.Log; import java.nio.ByteBuffer; @@ -196,58 +195,76 @@ class ImageGLWallpaper { glUniform1i(mUniTexture, 0); } + /** + * This method adjust s(x-axis), t(y-axis) texture coordinates + * to prevent the wallpaper from being stretched. + * The adjustment happens if either the width or height of the bitmap is larger than + * corresponding size of the surface. + * If both width and height are larger than corresponding size of the surface, + * the adjustment will happen at both s, t side. + * + * @param bitmapWidth The width of the bitmap. + * @param bitmapHeight The height of the bitmap. + * @param surfaceWidth The width of the surface. + * @param surfaceHeight The height of the surface. + * @param xOffset The offset amount along s axis. + * @param yOffset The offset amount along t axis. + */ void adjustTextureCoordinates(int bitmapWidth, int bitmapHeight, int surfaceWidth, int surfaceHeight, float xOffset, float yOffset) { - float ratioW = 1f; - float ratioH = 1f; - float rX = 0f; - float rY = 0f; - float[] coordinates = null; + float[] coordinates = TEXTURES.clone(); - final boolean adjustWidth = bitmapWidth > surfaceWidth; - final boolean adjustHeight = bitmapHeight > surfaceHeight; - - if (adjustWidth || adjustHeight) { - coordinates = TEXTURES.clone(); - } - - if (adjustWidth) { - float x = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset) / bitmapWidth; - ratioW = (float) surfaceWidth / bitmapWidth; - float referenceX = x + ratioW > 1f ? 1f - ratioW : x; + if (bitmapWidth > surfaceWidth) { + // Calculate the new s pos in pixels. + float pixelS = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset); + // Calculate the s pos in texture coordinate. + float coordinateS = pixelS / bitmapWidth; + // Calculate the percentage occupied by the surface width in bitmap width. + float surfacePercentageW = (float) surfaceWidth / bitmapWidth; + // Need also consider the case if bitmap height is smaller than surface height. + if (bitmapHeight < surfaceHeight) { + // We will narrow the surface percentage to keep aspect ratio. + surfacePercentageW *= (float) bitmapHeight / surfaceHeight; + } + // Determine the final s pos, also limit the legal s pos to prevent from out of range. + float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS; + // Traverse the s pos in texture coordinates array and adjust the s pos accordingly. for (int i = 0; i < coordinates.length; i += 2) { + // indices 2, 4 and 6 are the end of s coordinates. if (i == 2 || i == 4 || i == 6) { - coordinates[i] = Math.min(1f, referenceX + ratioW); + coordinates[i] = Math.min(1f, s + surfacePercentageW); } else { - coordinates[i] = referenceX; + coordinates[i] = s; } } - rX = referenceX; } - - if (adjustHeight) { - float y = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset) / bitmapHeight; - ratioH = (float) surfaceHeight / bitmapHeight; - float referenceY = y + ratioH > 1f ? 1f - ratioH : y; + if (bitmapHeight > surfaceHeight) { + // Calculate the new t pos in pixels. + float pixelT = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset); + // Calculate the t pos in texture coordinate. + float coordinateT = pixelT / bitmapHeight; + // Calculate the percentage occupied by the surface height in bitmap height. + float surfacePercentageH = (float) surfaceHeight / bitmapHeight; + // Need also consider the case if bitmap width is smaller than surface width. + if (bitmapWidth < surfaceWidth) { + // We will narrow the surface percentage to keep aspect ratio. + surfacePercentageH *= (float) bitmapWidth / surfaceWidth; + } + // Determine the final t pos, also limit the legal t pos to prevent from out of range. + float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT; + // Traverse the t pos in texture coordinates array and adjust the t pos accordingly. for (int i = 1; i < coordinates.length; i += 2) { + // indices 1, 3 and 11 are the end of t coordinates. if (i == 1 || i == 3 || i == 11) { - coordinates[i] = Math.min(1f, referenceY + ratioH); + coordinates[i] = Math.min(1f, t + surfacePercentageH); } else { - coordinates[i] = referenceY; + coordinates[i] = t; } } - rY = referenceY; } - if (adjustWidth || adjustHeight) { - if (Build.IS_DEBUGGABLE) { - Log.d(TAG, "adjustTextureCoordinates: sW=" + surfaceWidth + ", sH=" + surfaceHeight - + ", bW=" + bitmapWidth + ", bH=" + bitmapHeight - + ", rW=" + ratioW + ", rH=" + ratioH + ", rX=" + rX + ", rY=" + rY); - } - mTextureBuffer.put(coordinates); - mTextureBuffer.position(0); - } + mTextureBuffer.put(coordinates); + mTextureBuffer.position(0); } }