Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f6519f0 authored by Ahan Wu's avatar Ahan Wu
Browse files

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
parent a1de518e
Loading
Loading
Loading
Loading
+55 −38
Original line number Diff line number Diff line
@@ -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;

        final boolean adjustWidth = bitmapWidth > surfaceWidth;
        final boolean adjustHeight = bitmapHeight > surfaceHeight;

        if (adjustWidth || adjustHeight) {
            coordinates = TEXTURES.clone();
        float[] coordinates = TEXTURES.clone();

        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;
            }

        if (adjustWidth) {
            float x = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset) / bitmapWidth;
            ratioW = (float) surfaceWidth / bitmapWidth;
            float referenceX = x + ratioW > 1f ? 1f - ratioW : x;
            // 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);
    }
}
}