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