1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.graphics.lowlatency 18 19 import android.opengl.GLES20 20 import android.opengl.Matrix 21 import android.os.Build 22 import androidx.annotation.RequiresApi 23 import androidx.graphics.surface.SurfaceControlCompat 24 25 /** 26 * Class responsible for computing the corresponding transformations necessary to support 27 * pre-rotation. Consumers are expected to use the corresponding [bufferWidth] and [bufferHeight] 28 * parameters to configure with [GLES20.glViewport] as well as [transform] that should be consumed 29 * in any vertex shader computations 30 */ 31 @RequiresApi(Build.VERSION_CODES.Q) 32 internal class BufferTransformer { 33 34 private val mViewTransform = FloatArray(16) 35 36 val transform: FloatArray 37 get() = mViewTransform 38 39 var logicalWidth = 0 40 private set 41 42 var logicalHeight = 0 43 private set 44 45 var bufferWidth = 0 46 private set 47 48 var bufferHeight = 0 49 private set 50 51 var computedTransform: Int = BufferTransformHintResolver.UNKNOWN_TRANSFORM 52 private set 53 invertBufferTransformnull54 fun invertBufferTransform(transform: Int): Int = 55 when (transform) { 56 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_90 -> 57 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_270 58 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_180 -> 59 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_180 60 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_270 -> 61 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_90 62 SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY -> 63 SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY 64 else -> BufferTransformHintResolver.UNKNOWN_TRANSFORM // Return unknown transform 65 } 66 67 /** 68 * Compute the corresponding transform to apply to take into account buffer transformation hints 69 */ computeTransformnull70 fun computeTransform(width: Int, height: Int, transformHint: Int) { 71 val fWidth = width.toFloat() 72 val fHeight = height.toFloat() 73 logicalWidth = width 74 logicalHeight = height 75 bufferWidth = width 76 bufferHeight = height 77 computedTransform = transformHint 78 when (transformHint) { 79 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_90 -> { 80 Matrix.setRotateM(mViewTransform, 0, -90f, 0f, 0f, 1f) 81 Matrix.translateM(mViewTransform, 0, -fWidth, 0f, 0f) 82 bufferWidth = height 83 bufferHeight = width 84 } 85 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_180 -> { 86 Matrix.setRotateM(mViewTransform, 0, 180f, 0f, 0f, 1f) 87 Matrix.translateM(mViewTransform, 0, -fWidth, -fHeight, 0f) 88 } 89 SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_270 -> { 90 Matrix.setRotateM(mViewTransform, 0, 90f, 0f, 0f, 1f) 91 Matrix.translateM(mViewTransform, 0, 0f, -fHeight, 0f) 92 bufferWidth = height 93 bufferHeight = width 94 } 95 SurfaceControlCompat.BUFFER_TRANSFORM_IDENTITY -> { 96 Matrix.setIdentityM(mViewTransform, 0) 97 } 98 // Identity or unknown case, just set the identity matrix 99 else -> { 100 computedTransform = BufferTransformHintResolver.UNKNOWN_TRANSFORM 101 Matrix.setIdentityM(mViewTransform, 0) 102 } 103 } 104 } 105 } 106