1 /* <lambda>null2 * 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.surface 18 19 import android.graphics.Rect 20 import android.graphics.Region 21 import android.hardware.HardwareBuffer 22 import android.hardware.SyncFence 23 import android.os.Build 24 import android.view.AttachedSurfaceControl 25 import android.view.SurfaceControl 26 import android.view.SurfaceControl.Transaction 27 import android.view.SurfaceView 28 import androidx.annotation.RequiresApi 29 import androidx.hardware.SyncFenceCompat 30 import androidx.hardware.SyncFenceImpl 31 import androidx.hardware.SyncFenceV33 32 import java.util.concurrent.Executor 33 34 /** Implementation of [SurfaceControlImpl] that wraps the SDK's [SurfaceControl] API. */ 35 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 36 internal class SurfaceControlV33 internal constructor(internal val surfaceControl: SurfaceControl) : 37 SurfaceControlImpl { 38 39 /** See [SurfaceControlImpl.isValid] */ 40 override fun isValid(): Boolean = surfaceControl.isValid 41 42 /** See [SurfaceControlImpl.release] */ 43 override fun release() { 44 surfaceControl.release() 45 } 46 47 /** See [SurfaceControlImpl.Builder] */ 48 class Builder : SurfaceControlImpl.Builder { 49 50 private val builder = SurfaceControl.Builder() 51 52 /** See [SurfaceControlImpl.Builder.setParent] */ 53 override fun setParent(surfaceView: SurfaceView): SurfaceControlImpl.Builder { 54 builder.setParent(surfaceView.surfaceControl) 55 return this 56 } 57 58 /** See [SurfaceControlImpl.Builder.setParent] */ 59 override fun setParent(surfaceControl: SurfaceControlCompat): SurfaceControlImpl.Builder { 60 builder.setParent(surfaceControl.scImpl.asFrameworkSurfaceControl()) 61 return this 62 } 63 64 /** See [SurfaceControlImpl.Builder.setName] */ 65 override fun setName(name: String): Builder { 66 builder.setName(name) 67 return this 68 } 69 70 /** See [SurfaceControlImpl.Builder.build] */ 71 override fun build(): SurfaceControlImpl = SurfaceControlV33(builder.build()) 72 } 73 74 /** See [SurfaceControlImpl.Transaction] */ 75 class Transaction : SurfaceControlImpl.Transaction { 76 77 private val mTransaction = SurfaceControl.Transaction() 78 79 /** See [SurfaceControlImpl.Transaction.setOpaque] */ 80 override fun setOpaque( 81 surfaceControl: SurfaceControlImpl, 82 isOpaque: Boolean 83 ): SurfaceControlImpl.Transaction { 84 mTransaction.setOpaque(surfaceControl.asFrameworkSurfaceControl(), isOpaque) 85 return this 86 } 87 88 /** See [SurfaceControlImpl.Transaction.setVisibility] */ 89 override fun setVisibility( 90 surfaceControl: SurfaceControlImpl, 91 visible: Boolean 92 ): SurfaceControlImpl.Transaction { 93 mTransaction.setVisibility(surfaceControl.asFrameworkSurfaceControl(), visible) 94 return this 95 } 96 97 /** See [SurfaceControlImpl.Transaction.setBuffer] */ 98 override fun setBuffer( 99 surfaceControl: SurfaceControlImpl, 100 buffer: HardwareBuffer?, 101 fence: SyncFenceImpl?, 102 releaseCallback: ((SyncFenceCompat) -> Unit)? 103 ): Transaction { 104 mTransaction.setBuffer( 105 surfaceControl.asFrameworkSurfaceControl(), 106 buffer, 107 fence?.asSyncFence() 108 ) { syncFence -> 109 releaseCallback?.invoke(SyncFenceCompat(syncFence)) 110 } 111 return this 112 } 113 114 /** See [SurfaceControlImpl.Transaction.setLayer] */ 115 override fun setLayer( 116 surfaceControl: SurfaceControlImpl, 117 z: Int 118 ): SurfaceControlImpl.Transaction { 119 mTransaction.setLayer(surfaceControl.asFrameworkSurfaceControl(), z) 120 return this 121 } 122 123 /** See [SurfaceControlImpl.Transaction.reparent] */ 124 override fun reparent( 125 surfaceControl: SurfaceControlImpl, 126 newParent: SurfaceControlImpl? 127 ): Transaction { 128 mTransaction.reparent( 129 surfaceControl.asFrameworkSurfaceControl(), 130 newParent?.asFrameworkSurfaceControl() 131 ) 132 return this 133 } 134 135 /** See [SurfaceControlImpl.Transaction.reparent] */ 136 override fun reparent( 137 surfaceControl: SurfaceControlImpl, 138 attachedSurfaceControl: AttachedSurfaceControl 139 ): SurfaceControlImpl.Transaction { 140 val reparentTransaction = 141 attachedSurfaceControl.buildReparentTransaction( 142 surfaceControl.asFrameworkSurfaceControl() 143 ) 144 if (reparentTransaction != null) { 145 mTransaction.merge(reparentTransaction) 146 } 147 return this 148 } 149 150 /** See [SurfaceControlImpl.Transaction.addTransactionCommittedListener] */ 151 override fun addTransactionCommittedListener( 152 executor: Executor, 153 listener: SurfaceControlCompat.TransactionCommittedListener 154 ): SurfaceControlImpl.Transaction { 155 mTransaction.addTransactionCommittedListener(executor) { 156 listener.onTransactionCommitted() 157 } 158 return this 159 } 160 161 /** See [SurfaceControlImpl.Transaction.setDamageRegion] */ 162 override fun setDamageRegion( 163 surfaceControl: SurfaceControlImpl, 164 region: Region? 165 ): SurfaceControlImpl.Transaction { 166 mTransaction.setDamageRegion(surfaceControl.asFrameworkSurfaceControl(), region) 167 return this 168 } 169 170 /** See [SurfaceControlImpl.Transaction.setAlpha] */ 171 override fun setAlpha( 172 surfaceControl: SurfaceControlImpl, 173 alpha: Float 174 ): SurfaceControlImpl.Transaction { 175 mTransaction.setAlpha(surfaceControl.asFrameworkSurfaceControl(), alpha) 176 return this 177 } 178 179 /** See [SurfaceControlImpl.Transaction.setCrop] */ 180 override fun setCrop( 181 surfaceControl: SurfaceControlImpl, 182 crop: Rect? 183 ): SurfaceControlImpl.Transaction { 184 mTransaction.setCrop(surfaceControl.asFrameworkSurfaceControl(), crop) 185 return this 186 } 187 188 /** See [SurfaceControlImpl.Transaction.setPosition] */ 189 override fun setPosition( 190 surfaceControl: SurfaceControlImpl, 191 x: Float, 192 y: Float 193 ): SurfaceControlImpl.Transaction { 194 mTransaction.setPosition(surfaceControl.asFrameworkSurfaceControl(), x, y) 195 return this 196 } 197 198 /** See [SurfaceControlImpl.Transaction.setScale] */ 199 override fun setScale( 200 surfaceControl: SurfaceControlImpl, 201 scaleX: Float, 202 scaleY: Float 203 ): SurfaceControlImpl.Transaction { 204 mTransaction.setScale(surfaceControl.asFrameworkSurfaceControl(), scaleX, scaleY) 205 return this 206 } 207 208 /** See [SurfaceControlImpl.Transaction.setBufferTransform] */ 209 override fun setBufferTransform( 210 surfaceControl: SurfaceControlImpl, 211 @SurfaceControlCompat.Companion.BufferTransform transformation: Int 212 ): SurfaceControlImpl.Transaction { 213 mTransaction.setBufferTransform( 214 surfaceControl.asFrameworkSurfaceControl(), 215 transformation 216 ) 217 return this 218 } 219 220 /** See [SurfaceControlCompat.Transaction.setExtendedRangeBrightness] */ 221 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 222 override fun setExtendedRangeBrightness( 223 surfaceControl: SurfaceControlImpl, 224 currentBufferRatio: Float, 225 desiredRatio: Float 226 ): SurfaceControlImpl.Transaction { 227 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { 228 SurfaceControlTransactionVerificationHelperV34.setExtendedRangeBrightness( 229 mTransaction, 230 surfaceControl.asFrameworkSurfaceControl(), 231 currentBufferRatio, 232 desiredRatio 233 ) 234 return this 235 } else { 236 throw UnsupportedOperationException( 237 "Configuring the extended range brightness is only available on Android U+" 238 ) 239 } 240 } 241 242 /** See [SurfaceControlCompat.Transaction.setDataSpace] */ 243 override fun setDataSpace( 244 surfaceControl: SurfaceControlImpl, 245 dataSpace: Int 246 ): SurfaceControlImpl.Transaction { 247 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 248 SurfaceControlTransactionVerificationHelperV33.setDataSpace( 249 mTransaction, 250 surfaceControl.asFrameworkSurfaceControl(), 251 dataSpace 252 ) 253 } else { 254 throw UnsupportedOperationException( 255 "Configuring the data space is only available on Android T+" 256 ) 257 } 258 return this 259 } 260 261 override fun setFrameRate( 262 scImpl: SurfaceControlImpl, 263 frameRate: Float, 264 compatibility: Int, 265 changeFrameRateStrategy: Int 266 ): Transaction { 267 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 268 SurfaceControlVerificationHelperV31.setFrameRate( 269 mTransaction, 270 scImpl.asFrameworkSurfaceControl(), 271 frameRate, 272 compatibility, 273 changeFrameRateStrategy 274 ) 275 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { 276 SurfaceControlVerificationHelperV30.setFrameRate( 277 mTransaction, 278 scImpl.asFrameworkSurfaceControl(), 279 frameRate, 280 compatibility 281 ) 282 } 283 return this 284 } 285 286 override fun clearFrameRate(scImpl: SurfaceControlImpl): SurfaceControlImpl.Transaction { 287 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { 288 SurfaceControlVerificationHelperV34.clearFrameRate( 289 mTransaction, 290 scImpl.asFrameworkSurfaceControl() 291 ) 292 } 293 return this 294 } 295 296 /** See [SurfaceControlImpl.Transaction.commit] */ 297 override fun commit() { 298 mTransaction.apply() 299 } 300 301 /** See [SurfaceControlImpl.Transaction.close] */ 302 override fun close() { 303 mTransaction.close() 304 } 305 306 /** See [SurfaceControlImpl.Transaction.commitTransactionOnDraw] */ 307 override fun commitTransactionOnDraw(attachedSurfaceControl: AttachedSurfaceControl) { 308 attachedSurfaceControl.applyTransactionOnDraw(mTransaction) 309 } 310 311 private fun SyncFenceImpl.asSyncFence(): SyncFence = 312 if (this is SyncFenceV33) { 313 mSyncFence 314 } else { 315 throw IllegalArgumentException( 316 "Expected SyncFenceCompat implementation for API level 33" 317 ) 318 } 319 } 320 321 private companion object { 322 fun SurfaceControlImpl.asFrameworkSurfaceControl(): SurfaceControl = 323 if (this is SurfaceControlV33) { 324 surfaceControl 325 } else { 326 throw IllegalArgumentException("Parent implementation is not for Android T") 327 } 328 } 329 } 330 331 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 332 private object SurfaceControlTransactionVerificationHelperV34 { 333 setExtendedRangeBrightnessnull334 fun setExtendedRangeBrightness( 335 transaction: Transaction, 336 surfaceControl: SurfaceControl, 337 currentBufferRatio: Float, 338 desiredRatio: Float 339 ) { 340 transaction.setExtendedRangeBrightness(surfaceControl, currentBufferRatio, desiredRatio) 341 } 342 } 343 344 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 345 private object SurfaceControlTransactionVerificationHelperV33 { 346 setDataSpacenull347 fun setDataSpace(transaction: Transaction, surfaceControl: SurfaceControl, dataspace: Int) { 348 transaction.setDataSpace(surfaceControl, dataspace) 349 } 350 } 351 352 @RequiresApi(Build.VERSION_CODES.S) 353 private object SurfaceControlVerificationHelperV31 { setFrameRatenull354 fun setFrameRate( 355 transaction: Transaction, 356 surfaceControl: SurfaceControl, 357 frameRate: Float, 358 compatibility: Int, 359 strategy: Int 360 ) { 361 transaction.setFrameRate(surfaceControl, frameRate, compatibility, strategy) 362 } 363 } 364 365 @RequiresApi(Build.VERSION_CODES.R) 366 private object SurfaceControlVerificationHelperV30 { setFrameRatenull367 fun setFrameRate( 368 transaction: Transaction, 369 surfaceControl: SurfaceControl, 370 frameRate: Float, 371 compatibility: Int 372 ) { 373 transaction.setFrameRate(surfaceControl, frameRate, compatibility) 374 } 375 } 376 377 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 378 private object SurfaceControlVerificationHelperV34 { 379 clearFrameRatenull380 fun clearFrameRate(transaction: Transaction, surfaceControl: SurfaceControl) { 381 transaction.clearFrameRate(surfaceControl) 382 } 383 } 384