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