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