1 /* 2 * Copyright (C) 2019 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 android.graphics; 18 19 import android.annotation.NonNull; 20 import android.os.IBinder; 21 import android.view.Surface; 22 import android.view.SurfaceControl; 23 24 import java.util.function.Consumer; 25 26 /** 27 * @hide 28 */ 29 @android.ravenwood.annotation.RavenwoodKeepWholeClass 30 public final class BLASTBufferQueue { 31 // Note: This field is accessed by native code. 32 public long mNativeObject; // BLASTBufferQueue* 33 nativeCreate(String name, boolean updateDestinationFrame)34 private static native long nativeCreate(String name, boolean updateDestinationFrame); nativeDestroy(long ptr)35 private static native void nativeDestroy(long ptr); nativeGetSurface(long ptr, boolean includeSurfaceControlHandle)36 private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle); nativeSyncNextTransaction(long ptr, Consumer<SurfaceControl.Transaction> callback, boolean acquireSingleBuffer)37 private static native boolean nativeSyncNextTransaction(long ptr, 38 Consumer<SurfaceControl.Transaction> callback, boolean acquireSingleBuffer); nativeStopContinuousSyncTransaction(long ptr)39 private static native void nativeStopContinuousSyncTransaction(long ptr); nativeClearSyncTransaction(long ptr)40 private static native void nativeClearSyncTransaction(long ptr); nativeUpdate(long ptr, long surfaceControl, long width, long height, int format)41 private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height, 42 int format); nativeMergeWithNextTransaction(long ptr, long transactionPtr, long frameNumber)43 private static native void nativeMergeWithNextTransaction(long ptr, long transactionPtr, 44 long frameNumber); nativeGetLastAcquiredFrameNum(long ptr)45 private static native long nativeGetLastAcquiredFrameNum(long ptr); nativeApplyPendingTransactions(long ptr, long frameNumber)46 private static native void nativeApplyPendingTransactions(long ptr, long frameNumber); nativeIsSameSurfaceControl(long ptr, long surfaceControlPtr)47 private static native boolean nativeIsSameSurfaceControl(long ptr, long surfaceControlPtr); nativeGatherPendingTransactions(long ptr, long frameNumber)48 private static native SurfaceControl.Transaction nativeGatherPendingTransactions(long ptr, 49 long frameNumber); nativeSetTransactionHangCallback(long ptr, TransactionHangCallback callback)50 private static native void nativeSetTransactionHangCallback(long ptr, 51 TransactionHangCallback callback); nativeSetApplyToken(long ptr, IBinder applyToken)52 private static native void nativeSetApplyToken(long ptr, IBinder applyToken); nativeSetWaitForBufferReleaseCallback(long ptr, WaitForBufferReleaseCallback callback)53 private static native void nativeSetWaitForBufferReleaseCallback(long ptr, 54 WaitForBufferReleaseCallback callback); 55 56 public interface TransactionHangCallback { onTransactionHang(String reason)57 void onTransactionHang(String reason); 58 } 59 60 61 public interface WaitForBufferReleaseCallback { 62 /** 63 * Indicates that the client is waiting on buffer release 64 * due to no free buffers being available to render into. 65 * @param durationNanos The length of time in nanoseconds 66 * that the client was blocked on buffer release. 67 */ onWaitForBufferRelease(long durationNanos)68 void onWaitForBufferRelease(long durationNanos); 69 } 70 71 /** Create a new connection with the surface flinger. */ BLASTBufferQueue(String name, boolean updateDestinationFrame)72 public BLASTBufferQueue(String name, boolean updateDestinationFrame) { 73 mNativeObject = nativeCreate(name, updateDestinationFrame); 74 } 75 destroy()76 public void destroy() { 77 nativeDestroy(mNativeObject); 78 mNativeObject = 0; 79 } 80 81 /** 82 * @return a new Surface instance from the IGraphicsBufferProducer of the adapter. 83 */ createSurface()84 public Surface createSurface() { 85 return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */); 86 } 87 88 /** 89 * @return a new Surface instance from the IGraphicsBufferProducer of the adapter and 90 * the SurfaceControl handle. 91 */ createSurfaceWithHandle()92 public Surface createSurfaceWithHandle() { 93 return nativeGetSurface(mNativeObject, true /* includeSurfaceControlHandle */); 94 } 95 96 /** 97 * Send a callback that accepts a transaction to BBQ. BBQ will acquire buffers into the a 98 * transaction it created and will eventually send the transaction into the callback 99 * when it is ready. 100 * @param callback The callback invoked when the buffer has been added to the transaction. The 101 * callback will contain the transaction with the buffer. 102 * @param acquireSingleBuffer If true, only acquire a single buffer when processing frames. The 103 * callback will be cleared once a single buffer has been 104 * acquired. If false, continue to acquire all buffers into the 105 * transaction until stopContinuousSyncTransaction is called. 106 */ syncNextTransaction(boolean acquireSingleBuffer, @NonNull Consumer<SurfaceControl.Transaction> callback)107 public boolean syncNextTransaction(boolean acquireSingleBuffer, 108 @NonNull Consumer<SurfaceControl.Transaction> callback) { 109 return nativeSyncNextTransaction(mNativeObject, callback, acquireSingleBuffer); 110 } 111 112 /** 113 * Send a callback that accepts a transaction to BBQ. BBQ will acquire buffers into the a 114 * transaction it created and will eventually send the transaction into the callback 115 * when it is ready. 116 * @param callback The callback invoked when the buffer has been added to the transaction. The 117 * callback will contain the transaction with the buffer. 118 */ syncNextTransaction(@onNull Consumer<SurfaceControl.Transaction> callback)119 public boolean syncNextTransaction(@NonNull Consumer<SurfaceControl.Transaction> callback) { 120 return syncNextTransaction(true /* acquireSingleBuffer */, callback); 121 } 122 123 /** 124 * Tell BBQ to stop acquiring buffers into a single transaction. BBQ will send the sync 125 * transaction callback after this has been called. This should only be used when 126 * syncNextTransaction was called with acquireSingleBuffer set to false. 127 */ stopContinuousSyncTransaction()128 public void stopContinuousSyncTransaction() { 129 nativeStopContinuousSyncTransaction(mNativeObject); 130 } 131 132 /** 133 * Tell BBQ to clear the sync transaction that was previously set. The callback will not be 134 * invoked when the next frame is acquired. 135 */ clearSyncTransaction()136 public void clearSyncTransaction() { 137 nativeClearSyncTransaction(mNativeObject); 138 } 139 140 /** 141 * Updates {@link SurfaceControl}, size, and format for a particular BLASTBufferQueue 142 * @param sc The new SurfaceControl that this BLASTBufferQueue will update 143 * @param width The new width for the buffer. 144 * @param height The new height for the buffer. 145 * @param format The new format for the buffer. 146 */ update(SurfaceControl sc, int width, int height, @PixelFormat.Format int format)147 public void update(SurfaceControl sc, int width, int height, @PixelFormat.Format int format) { 148 nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format); 149 } 150 151 @Override finalize()152 protected void finalize() throws Throwable { 153 try { 154 if (mNativeObject != 0) { 155 nativeDestroy(mNativeObject); 156 } 157 } finally { 158 super.finalize(); 159 } 160 } 161 162 /** 163 * Merge the transaction passed in to the next transaction in BlastBufferQueue. The next 164 * transaction will be applied or merged when the next frame with specified frame number 165 * is available. 166 */ mergeWithNextTransaction(SurfaceControl.Transaction t, long frameNumber)167 public void mergeWithNextTransaction(SurfaceControl.Transaction t, long frameNumber) { 168 nativeMergeWithNextTransaction(mNativeObject, t.mNativeObject, frameNumber); 169 } 170 171 /** 172 * Merge the transaction passed in to the next transaction in BlastBufferQueue. 173 * @param nativeTransaction native handle passed from native c/c++ code. 174 */ mergeWithNextTransaction(long nativeTransaction, long frameNumber)175 public void mergeWithNextTransaction(long nativeTransaction, long frameNumber) { 176 nativeMergeWithNextTransaction(mNativeObject, nativeTransaction, frameNumber); 177 } 178 179 /** 180 * Apply any transactions that were passed to {@link #mergeWithNextTransaction} with the 181 * specified frameNumber. This is intended to ensure transactions don't get stuck as pending 182 * if the specified frameNumber is never drawn. 183 * 184 * @param frameNumber The frameNumber used to determine which transactions to apply. 185 */ applyPendingTransactions(long frameNumber)186 public void applyPendingTransactions(long frameNumber) { 187 nativeApplyPendingTransactions(mNativeObject, frameNumber); 188 } 189 getLastAcquiredFrameNum()190 public long getLastAcquiredFrameNum() { 191 return nativeGetLastAcquiredFrameNum(mNativeObject); 192 } 193 194 /** 195 * @return True if the associated SurfaceControl has the same handle as {@param sc}. 196 */ isSameSurfaceControl(SurfaceControl sc)197 public boolean isSameSurfaceControl(SurfaceControl sc) { 198 return nativeIsSameSurfaceControl(mNativeObject, sc.mNativeObject); 199 } 200 201 /** 202 * Get any transactions that were passed to {@link #mergeWithNextTransaction} with the 203 * specified frameNumber. This is intended to ensure transactions don't get stuck as pending 204 * if the specified frameNumber is never drawn. 205 * 206 * @param frameNumber The frameNumber used to determine which transactions to apply. 207 * @return a Transaction that contains the merge of all the transactions that were sent to 208 * mergeWithNextTransaction 209 */ gatherPendingTransactions(long frameNumber)210 public SurfaceControl.Transaction gatherPendingTransactions(long frameNumber) { 211 return nativeGatherPendingTransactions(mNativeObject, frameNumber); 212 } 213 setTransactionHangCallback(TransactionHangCallback hangCallback)214 public void setTransactionHangCallback(TransactionHangCallback hangCallback) { 215 nativeSetTransactionHangCallback(mNativeObject, hangCallback); 216 } 217 setApplyToken(IBinder applyToken)218 public void setApplyToken(IBinder applyToken) { 219 nativeSetApplyToken(mNativeObject, applyToken); 220 } 221 222 /** 223 * Propagate callback about being blocked on buffer release. 224 */ setWaitForBufferReleaseCallback(WaitForBufferReleaseCallback waitCallback)225 public void setWaitForBufferReleaseCallback(WaitForBufferReleaseCallback waitCallback) { 226 nativeSetWaitForBufferReleaseCallback(mNativeObject, waitCallback); 227 } 228 } 229