1 /* 2 * Copyright (C) 2011 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.annotation.Nullable; 21 import android.view.View; 22 23 import com.android.internal.util.VirtualRefBasePtr; 24 25 /** 26 * TextureLayer represents a SurfaceTexture that will be composited by RenderThread into the 27 * frame when drawn in a HW accelerated Canvas. This is backed by a DeferredLayerUpdater on 28 * the native side. 29 * 30 * @hide TODO: Make this a SystemApi for b/155905258 31 */ 32 public final class TextureLayer implements AutoCloseable { 33 private HardwareRenderer mRenderer; 34 private VirtualRefBasePtr mFinalizer; 35 TextureLayer(@onNull HardwareRenderer renderer, long deferredUpdater)36 private TextureLayer(@NonNull HardwareRenderer renderer, long deferredUpdater) { 37 if (renderer == null || deferredUpdater == 0) { 38 throw new IllegalArgumentException("Either hardware renderer: " + renderer 39 + " or deferredUpdater: " + deferredUpdater + " is invalid"); 40 } 41 mRenderer = renderer; 42 mFinalizer = new VirtualRefBasePtr(deferredUpdater); 43 } 44 45 /** 46 * Update the paint used when drawing this layer. 47 * 48 * @param paint The paint used when the layer is drawn into the destination canvas. 49 * @see View#setLayerPaint(android.graphics.Paint) 50 */ setLayerPaint(@ullable Paint paint)51 public void setLayerPaint(@Nullable Paint paint) { 52 nSetLayerPaint(mFinalizer.get(), paint != null ? paint.getNativeInstance() : 0); 53 mRenderer.pushLayerUpdate(this); 54 } 55 56 /** 57 * Indicates whether this layer can be rendered. 58 * 59 * @return True if the layer can be rendered into, false otherwise 60 */ isValid()61 private boolean isValid() { 62 return mFinalizer != null && mFinalizer.get() != 0; 63 } 64 65 /** 66 * Destroys resources without waiting for a GC. 67 */ 68 @Override close()69 public void close() { 70 if (!isValid()) { 71 // Already destroyed 72 return; 73 } 74 mRenderer.onLayerDestroyed(this); 75 mRenderer = null; 76 mFinalizer.release(); 77 mFinalizer = null; 78 } 79 getDeferredLayerUpdater()80 /*package*/ long getDeferredLayerUpdater() { 81 return mFinalizer.get(); 82 } 83 84 /** 85 * Copies this layer into the specified bitmap. 86 * 87 * @param bitmap The bitmap to copy they layer into 88 * 89 * @return True if the copy was successful, false otherwise 90 */ copyInto(@onNull Bitmap bitmap)91 public boolean copyInto(@NonNull Bitmap bitmap) { 92 return mRenderer.copyLayerInto(this, bitmap); 93 } 94 95 /** 96 * Update the layer's properties. Note that after calling this isValid() may 97 * return false if the requested width/height cannot be satisfied 98 * 99 * @param width The new width of this layer 100 * @param height The new height of this layer 101 * @param isOpaque Whether this layer is opaque 102 * 103 * @return true if the layer's properties will change, false if they already 104 * match the desired values. 105 */ prepare(int width, int height, boolean isOpaque)106 public boolean prepare(int width, int height, boolean isOpaque) { 107 return nPrepare(mFinalizer.get(), width, height, isOpaque); 108 } 109 110 /** 111 * Sets an optional transform on this layer. 112 * 113 * @param matrix The transform to apply to the layer. 114 */ setTransform(@onNull Matrix matrix)115 public void setTransform(@NonNull Matrix matrix) { 116 nSetTransform(mFinalizer.get(), matrix.ni()); 117 mRenderer.pushLayerUpdate(this); 118 } 119 120 /** 121 * Indicates that this layer has lost its texture. 122 */ detachSurfaceTexture()123 public void detachSurfaceTexture() { 124 mRenderer.detachSurfaceTexture(mFinalizer.get()); 125 } 126 getLayerHandle()127 /*package*/ long getLayerHandle() { 128 return mFinalizer.get(); 129 } 130 setSurfaceTexture(@onNull SurfaceTexture surface)131 public void setSurfaceTexture(@NonNull SurfaceTexture surface) { 132 nSetSurfaceTexture(mFinalizer.get(), surface); 133 mRenderer.pushLayerUpdate(this); 134 } 135 updateSurfaceTexture()136 public void updateSurfaceTexture() { 137 nUpdateSurfaceTexture(mFinalizer.get()); 138 mRenderer.pushLayerUpdate(this); 139 } 140 adoptTextureLayer(@onNull HardwareRenderer renderer, long layer)141 /*package*/ static TextureLayer adoptTextureLayer(@NonNull HardwareRenderer renderer, 142 long layer) { 143 return new TextureLayer(renderer, layer); 144 } 145 nPrepare(long layerUpdater, int width, int height, boolean isOpaque)146 private static native boolean nPrepare(long layerUpdater, int width, int height, 147 boolean isOpaque); nSetLayerPaint(long layerUpdater, long paint)148 private static native void nSetLayerPaint(long layerUpdater, long paint); nSetTransform(long layerUpdater, long matrix)149 private static native void nSetTransform(long layerUpdater, long matrix); nSetSurfaceTexture(long layerUpdater, @NonNull SurfaceTexture surface)150 private static native void nSetSurfaceTexture(long layerUpdater, 151 @NonNull SurfaceTexture surface); nUpdateSurfaceTexture(long layerUpdater)152 private static native void nUpdateSurfaceTexture(long layerUpdater); 153 } 154