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