1 /* 2 * Copyright (C) 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 android.surfaceflinger; 18 19 import android.annotation.ColorInt; 20 import android.graphics.Canvas; 21 import android.graphics.GraphicBuffer; 22 import android.graphics.PixelFormat; 23 import android.hardware.HardwareBuffer; 24 import android.hardware.SyncFence; 25 import android.view.SurfaceControl; 26 27 import java.util.concurrent.ArrayBlockingQueue; 28 29 /** 30 * Allocates n amount of buffers to a SurfaceControl using a Queue implementation. Executes a 31 * releaseCallback so a buffer can be safely re-used. 32 * 33 * @hide 34 */ 35 public class BufferFlinger { 36 ArrayBlockingQueue<GraphicBuffer> mBufferQ; 37 BufferFlinger(int numOfBuffers, @ColorInt int color)38 public BufferFlinger(int numOfBuffers, @ColorInt int color) { 39 mBufferQ = new ArrayBlockingQueue<>(numOfBuffers); 40 41 while (numOfBuffers > 0) { 42 GraphicBuffer buffer = GraphicBuffer.create(500, 500, 43 PixelFormat.RGBA_8888, 44 GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER 45 | GraphicBuffer.USAGE_SW_WRITE_RARELY); 46 47 Canvas canvas = buffer.lockCanvas(); 48 canvas.drawColor(color); 49 buffer.unlockCanvasAndPost(canvas); 50 51 mBufferQ.add(buffer); 52 numOfBuffers--; 53 } 54 } 55 addBuffer(SurfaceControl.Transaction t, SurfaceControl surfaceControl)56 public void addBuffer(SurfaceControl.Transaction t, SurfaceControl surfaceControl) { 57 try { 58 final GraphicBuffer buffer = mBufferQ.take(); 59 t.setBuffer(surfaceControl, 60 HardwareBuffer.createFromGraphicBuffer(buffer), 61 null, 62 (SyncFence fence) -> { 63 releaseCallback(fence, buffer); 64 }); 65 } catch (InterruptedException ignore) { 66 } 67 } 68 releaseCallback(SyncFence fence, GraphicBuffer buffer)69 public void releaseCallback(SyncFence fence, GraphicBuffer buffer) { 70 if (fence != null) { 71 fence.awaitForever(); 72 } 73 mBufferQ.add(buffer); 74 } 75 freeBuffers()76 public void freeBuffers() { 77 for (GraphicBuffer buffer : mBufferQ) { 78 buffer.destroy(); 79 } 80 } 81 } 82