diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlRect.java b/libraries/common/src/main/java/androidx/media3/common/util/GlRect.java new file mode 100644 index 0000000000..4b2f881742 --- /dev/null +++ b/libraries/common/src/main/java/androidx/media3/common/util/GlRect.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.common.util; + +import static androidx.media3.common.util.Assertions.checkArgument; + +/** + * Represents a rectangle by the coordinates of its 4 edges (left, bottom, right, top). + * + *
Note that the right and top coordinates are exclusive. + * + *
This class represents coordinates in the OpenGL coordinate convention: {@code left <= right}
+ * and {@code bottom <= top}.
+ */
+@UnstableApi
+public final class GlRect {
+ public int left;
+ public int bottom;
+ public int right;
+ public int top;
+
+ /** Creates an instance from (0, 0) to the specified width and height. */
+ public GlRect(int width, int height) {
+ this(/* left= */ 0, /* bottom= */ 0, width, height);
+ }
+
+ /** Creates an instance. */
+ public GlRect(int left, int bottom, int right, int top) {
+ checkArgument(left <= right && bottom <= top);
+ this.left = left;
+ this.bottom = bottom;
+ this.right = right;
+ this.top = top;
+ }
+}
diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java
index f9f43c52b6..948f3342a8 100644
--- a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java
+++ b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java
@@ -23,7 +23,6 @@ import static androidx.media3.common.util.Assertions.checkState;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
-import android.graphics.Rect;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
@@ -837,7 +836,7 @@ public final class GlUtil {
* @param drawFboId The framebuffer object to draw into.
* @param drawRect The rectangular region of {@code drawFboId} to draw into.
*/
- public static void blitFrameBuffer(int readFboId, Rect readRect, int drawFboId, Rect drawRect)
+ public static void blitFrameBuffer(int readFboId, GlRect readRect, int drawFboId, GlRect drawRect)
throws GlException {
int[] boundFramebuffer = new int[1];
GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, boundFramebuffer, /* offset= */ 0);
@@ -848,13 +847,13 @@ public final class GlUtil {
checkGlError();
GLES30.glBlitFramebuffer(
readRect.left,
- readRect.top,
- readRect.right,
readRect.bottom,
+ readRect.right,
+ readRect.top,
drawRect.left,
- drawRect.top,
- drawRect.right,
drawRect.bottom,
+ drawRect.right,
+ drawRect.top,
GLES30.GL_COLOR_BUFFER_BIT,
GLES30.GL_LINEAR);
checkGlError();
diff --git a/libraries/effect/src/androidTest/java/androidx/media3/effect/ByteBufferGlEffectTest.java b/libraries/effect/src/androidTest/java/androidx/media3/effect/ByteBufferGlEffectTest.java
index 40d58c593b..d8857e09a3 100644
--- a/libraries/effect/src/androidTest/java/androidx/media3/effect/ByteBufferGlEffectTest.java
+++ b/libraries/effect/src/androidTest/java/androidx/media3/effect/ByteBufferGlEffectTest.java
@@ -26,7 +26,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.graphics.Bitmap;
import android.graphics.Color;
-import android.graphics.Rect;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.AbsoluteSizeSpan;
@@ -34,6 +33,7 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.TypefaceSpan;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.util.Consumer;
+import androidx.media3.common.util.GlRect;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.Util;
import androidx.media3.test.utils.TextureBitmapReader;
@@ -140,12 +140,8 @@ public class ByteBufferGlEffectTest {
}
@Override
- public Rect getScaledRegion(long presentationTimeUs) {
- return new Rect(
- /* left= */ 0,
- /* top= */ 0,
- /* right= */ INPUT_FRAME_WIDTH,
- /* bottom= */ INPUT_FRAME_HEIGHT);
+ public GlRect getScaledRegion(long presentationTimeUs) {
+ return new GlRect(INPUT_FRAME_WIDTH, INPUT_FRAME_HEIGHT);
}
@Override
diff --git a/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferConcurrentEffect.java b/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferConcurrentEffect.java
index b3cc18ddb5..d3b6f8e0bb 100644
--- a/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferConcurrentEffect.java
+++ b/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferConcurrentEffect.java
@@ -19,11 +19,11 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
-import android.graphics.Rect;
import androidx.media3.common.C;
import androidx.media3.common.GlObjectsProvider;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
+import androidx.media3.common.util.GlRect;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.Util;
@@ -107,8 +107,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
textureInfo.fboId,
processor.getScaledRegion(presentationTimeUs),
effectInputTexture.fboId,
- new Rect(
- /* left= */ 0, /* top= */ 0, effectInputTexture.width, effectInputTexture.height));
+ new GlRect(effectInputTexture.width, effectInputTexture.height));
TexturePixelBuffer texturePixelBuffer = new TexturePixelBuffer(effectInputTexture);
unmappedPixelBuffers.add(texturePixelBuffer);
diff --git a/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferGlEffect.java b/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferGlEffect.java
index 00d50349fc..e8e7d411ba 100644
--- a/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferGlEffect.java
+++ b/libraries/effect/src/main/java/androidx/media3/effect/ByteBufferGlEffect.java
@@ -20,10 +20,10 @@ import static androidx.media3.common.util.Assertions.checkArgument;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
-import android.graphics.Rect;
import android.opengl.GLES20;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
+import androidx.media3.common.util.GlRect;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.UnstableApi;
import com.google.common.util.concurrent.ListenableFuture;
@@ -143,9 +143,7 @@ import java.util.concurrent.Future;
* @return The rectangular region of the input image that will be scaled to fill the effect
* input image.
*/
- // TODO: b/b/361286064 - This method misuses android.graphics.Rect for OpenGL coordinates.
- // Implement a custom GlUtils.Rect to correctly label lower left corner as (0, 0).
- Rect getScaledRegion(long presentationTimeUs);
+ GlRect getScaledRegion(long presentationTimeUs);
/**
* Processing the image data in the {@code image}.
diff --git a/libraries/effect/src/main/java/androidx/media3/effect/QueuingGlShaderProgram.java b/libraries/effect/src/main/java/androidx/media3/effect/QueuingGlShaderProgram.java
index 242ad1a3ac..e01bcde03f 100644
--- a/libraries/effect/src/main/java/androidx/media3/effect/QueuingGlShaderProgram.java
+++ b/libraries/effect/src/main/java/androidx/media3/effect/QueuingGlShaderProgram.java
@@ -18,13 +18,13 @@ package androidx.media3.effect;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkState;
-import android.graphics.Rect;
import androidx.annotation.CallSuper;
import androidx.annotation.IntRange;
import androidx.media3.common.C;
import androidx.media3.common.GlObjectsProvider;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
+import androidx.media3.common.util.GlRect;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.UnstableApi;
import com.google.common.util.concurrent.Futures;
@@ -213,10 +213,9 @@ import java.util.concurrent.TimeUnit;
checkState(inputTexture.fboId != C.INDEX_UNSET);
GlUtil.blitFrameBuffer(
inputTexture.fboId,
- new Rect(/* left= */ 0, /* top= */ 0, /* right= */ inputWidth, /* bottom= */ inputHeight),
+ new GlRect(inputWidth, inputHeight),
outputTexture.fboId,
- new Rect(
- /* left= */ 0, /* top= */ 0, /* right= */ inputWidth, /* bottom= */ inputHeight));
+ new GlRect(inputWidth, inputHeight));
Future