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