• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.FloatRange;
20 import android.annotation.Nullable;
21 import android.annotation.SuppressLint;
22 import android.compat.annotation.UnsupportedAppUsage;
23 import android.hardware.DataSpace.NamedDataSpace;
24 import android.os.Build;
25 import android.os.Handler;
26 import android.os.Looper;
27 import android.os.Message;
28 import android.os.Trace;
29 import android.view.Surface;
30 import android.view.TextureView;
31 import android.view.flags.Flags;
32 
33 import java.lang.ref.WeakReference;
34 
35 /**
36  * Captures frames from an image stream as an OpenGL ES texture.
37  *
38  * <p>The image stream may come from either camera preview or video decode. A
39  * {@link android.view.Surface} created from a SurfaceTexture can be used as an output
40  * destination for the {@link android.hardware.camera2}, {@link android.media.MediaCodec},
41  * {@link android.media.MediaPlayer}, and {@link android.renderscript.Allocation} APIs.
42  * When {@link #updateTexImage} is called, the contents of the texture object specified
43  * when the SurfaceTexture was created are updated to contain the most recent image from the image
44  * stream.  This may cause some frames of the stream to be skipped.
45  *
46  * <p>A SurfaceTexture may also be used in place of a SurfaceHolder when specifying the output
47  * destination of the older {@link android.hardware.Camera} API. Doing so will cause all the
48  * frames from the image stream to be sent to the SurfaceTexture object rather than to the device's
49  * display.
50  *
51  * <p>A typical pattern is to use SurfaceTexture to render frames to a {@link TextureView}; however,
52  * a TextureView is not <i>required</i> for using the texture object. The texture object may be used
53  * as part of an OpenGL ES shader.
54  *
55  * <p>When sampling from the texture one should first transform the texture coordinates using the
56  * matrix queried via {@link #getTransformMatrix(float[])}.  The transform matrix may change each
57  * time {@link #updateTexImage} is called, so it should be re-queried each time the texture image
58  * is updated.
59  * This matrix transforms traditional 2D OpenGL ES texture coordinate column vectors of the form (s,
60  * t, 0, 1) where s and t are on the inclusive interval [0, 1] to the proper sampling location in
61  * the streamed texture.  This transform compensates for any properties of the image stream source
62  * that cause it to appear different from a traditional OpenGL ES texture.  For example, sampling
63  * from the bottom left corner of the image can be accomplished by transforming the column vector
64  * (0, 0, 0, 1) using the queried matrix, while sampling from the top right corner of the image can
65  * be done by transforming (1, 1, 0, 1).
66  *
67  * <p>The texture object uses the GL_TEXTURE_EXTERNAL_OES texture target, which is defined by the
68  * <a href="http://www.khronos.org/registry/gles/extensions/OES/OES_EGL_image_external.txt">
69  * GL_OES_EGL_image_external</a> OpenGL ES extension.  This limits how the texture may be used.
70  * Each time the texture is bound it must be bound to the GL_TEXTURE_EXTERNAL_OES target rather than
71  * the GL_TEXTURE_2D target.  Additionally, any OpenGL ES 2.0 shader that samples from the texture
72  * must declare its use of this extension using, for example, an "#extension
73  * GL_OES_EGL_image_external : require" directive.  Such shaders must also access the texture using
74  * the samplerExternalOES GLSL sampler type.
75  *
76  * <p>SurfaceTexture objects may be created on any thread.  {@link #updateTexImage} may only be
77  * called on the thread with the OpenGL ES context that contains the texture object.  The
78  * frame-available callback is called on an arbitrary thread, so unless special care is taken {@link
79  * #updateTexImage} should not be called directly from the callback.
80  */
81 @android.ravenwood.annotation.RavenwoodKeepWholeClass
82 public class SurfaceTexture {
83     private final Looper mCreatorLooper;
84     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
85     private Handler mOnFrameAvailableHandler;
86     private Handler mOnSetFrameRateHandler;
87 
88     /**
89      * These fields are used by native code, do not access or modify.
90      */
91     @UnsupportedAppUsage(trackingBug = 176388660)
92     private long mSurfaceTexture;
93     @UnsupportedAppUsage(trackingBug = 176388660)
94     private long mProducer;
95     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
96     private long mFrameAvailableListener;
97 
98     private boolean mIsSingleBuffered;
99 
100     /**
101      * Callback interface for being notified that a new stream frame is available.
102      */
103     public interface OnFrameAvailableListener {
onFrameAvailable(SurfaceTexture surfaceTexture)104         void onFrameAvailable(SurfaceTexture surfaceTexture);
105     }
106 
107     /**
108      * Callback interface for being notified that a producer set a frame rate
109      * @hide
110      */
111     public interface OnSetFrameRateListener {
112         /**
113          * Called when the producer sets a frame rate
114          * @hide
115          */
onSetFrameRate(SurfaceTexture surfaceTexture, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility, @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy)116         void onSetFrameRate(SurfaceTexture surfaceTexture,
117                             @FloatRange(from = 0.0) float frameRate,
118                                  @Surface.FrameRateCompatibility int compatibility,
119                                  @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy);
120     }
121 
122     /**
123      * Exception thrown when a SurfaceTexture couldn't be created or resized.
124      *
125      * @deprecated No longer thrown. {@link android.view.Surface.OutOfResourcesException}
126      * is used instead.
127      */
128     @SuppressWarnings("serial")
129     @Deprecated
130     public static class OutOfResourcesException extends Exception {
OutOfResourcesException()131         public OutOfResourcesException() {
132         }
OutOfResourcesException(String name)133         public OutOfResourcesException(String name) {
134             super(name);
135         }
136     }
137 
138     /**
139      * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
140      *
141      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
142      *
143      * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
144      */
SurfaceTexture(int texName)145     public SurfaceTexture(int texName) {
146         this(texName, false);
147     }
148 
149     /**
150      * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
151      * <p>
152      * In single buffered mode the application is responsible for serializing access to the image
153      * content buffer. Each time the image content is to be updated, the
154      * {@link #releaseTexImage()} method must be called before the image content producer takes
155      * ownership of the buffer. For example, when producing image content with the NDK
156      * ANativeWindow_lock and ANativeWindow_unlockAndPost functions, {@link #releaseTexImage()}
157      * must be called before each ANativeWindow_lock, or that call will fail. When producing
158      * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first
159      * OpenGL ES function call each frame.
160      *
161      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
162      * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
163      *
164      * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
165      */
SurfaceTexture(int texName, boolean singleBufferMode)166     public SurfaceTexture(int texName, boolean singleBufferMode) {
167         mCreatorLooper = Looper.myLooper();
168         mIsSingleBuffered = singleBufferMode;
169         nativeInit(false, texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
170     }
171 
172     /**
173      * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
174      * <p>
175      * In single buffered mode the application is responsible for serializing access to the image
176      * content buffer. Each time the image content is to be updated, the
177      * {@link #releaseTexImage()} method must be called before the image content producer takes
178      * ownership of the buffer. For example, when producing image content with the NDK
179      * ANativeWindow_lock and ANativeWindow_unlockAndPost functions, {@link #releaseTexImage()}
180      * must be called before each ANativeWindow_lock, or that call will fail. When producing
181      * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first
182      * OpenGL ES function call each frame.
183      * <p>
184      * Unlike {@link #SurfaceTexture(int, boolean)}, which takes an OpenGL texture object name,
185      * this constructor creates the SurfaceTexture in detached mode. A texture name must be passed
186      * in using {@link #attachToGLContext} before calling {@link #releaseTexImage()} and producing
187      * image content using OpenGL ES.
188      *
189      * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
190      *
191      * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
192      */
SurfaceTexture(boolean singleBufferMode)193     public SurfaceTexture(boolean singleBufferMode) {
194         mCreatorLooper = Looper.myLooper();
195         mIsSingleBuffered = singleBufferMode;
196         nativeInit(true, 0, singleBufferMode, new WeakReference<SurfaceTexture>(this));
197     }
198 
199     /**
200      * Register a callback to be invoked when a new image frame becomes available to the
201      * SurfaceTexture.
202      * <p>
203      * The callback may be called on an arbitrary thread, so it is not
204      * safe to call {@link #updateTexImage} without first binding the OpenGL ES context to the
205      * thread invoking the callback.
206      * </p>
207      *
208      * @param listener The listener to use, or null to remove the listener.
209      */
setOnFrameAvailableListener(@ullable OnFrameAvailableListener listener)210     public void setOnFrameAvailableListener(@Nullable OnFrameAvailableListener listener) {
211         setOnFrameAvailableListener(listener, null);
212     }
213 
214     /**
215      * Register a callback to be invoked when a new image frame becomes available to the
216      * SurfaceTexture.
217      * <p>
218      * If a handler is specified, the callback will be invoked on that handler's thread.
219      * If no handler is specified, then the callback may be called on an arbitrary thread,
220      * so it is not safe to call {@link #updateTexImage} without first binding the OpenGL ES
221      * context to the thread invoking the callback.
222      * </p>
223      *
224      * @param listener The listener to use, or null to remove the listener.
225      * @param handler The handler on which the listener should be invoked, or null
226      * to use an arbitrary thread.
227      */
setOnFrameAvailableListener(@ullable final OnFrameAvailableListener listener, @Nullable Handler handler)228     public void setOnFrameAvailableListener(@Nullable final OnFrameAvailableListener listener,
229             @Nullable Handler handler) {
230         if (listener != null) {
231             // Although we claim the thread is arbitrary, earlier implementation would
232             // prefer to send the callback on the creating looper or the main looper
233             // so we preserve this behavior here.
234             Looper looper = handler != null ? handler.getLooper() :
235                     mCreatorLooper != null ? mCreatorLooper : Looper.getMainLooper();
236             mOnFrameAvailableHandler = new Handler(looper, null, true /*async*/) {
237                 @Override
238                 public void handleMessage(Message msg) {
239                     listener.onFrameAvailable(SurfaceTexture.this);
240                 }
241             };
242         } else {
243             mOnFrameAvailableHandler = null;
244         }
245     }
246 
247     private static class SetFrameRateArgs {
SetFrameRateArgs(@loatRangefrom = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility, @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy)248         SetFrameRateArgs(@FloatRange(from = 0.0) float frameRate,
249                                 @Surface.FrameRateCompatibility int compatibility,
250                    @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) {
251             this.mFrameRate = frameRate;
252             this.mCompatibility = compatibility;
253             this.mChangeFrameRateStrategy = changeFrameRateStrategy;
254         }
255         final float mFrameRate;
256         final int mCompatibility;
257         final int mChangeFrameRateStrategy;
258     }
259 
260     /**
261      * Register a callback to be invoked when the producer sets a frame rate using
262      * Surface.setFrameRate.
263      * @hide
264      */
setOnSetFrameRateListener(@ullable final OnSetFrameRateListener listener, @Nullable Handler handler)265     public void setOnSetFrameRateListener(@Nullable final OnSetFrameRateListener listener,
266                                             @Nullable Handler handler) {
267         if (listener != null) {
268             Looper looper = handler != null ? handler.getLooper() :
269                     mCreatorLooper != null ? mCreatorLooper : Looper.getMainLooper();
270             mOnSetFrameRateHandler = new Handler(looper, null, true /*async*/) {
271                 @Override
272                 public void handleMessage(Message msg) {
273                     Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSetFrameRateHandler");
274                     try {
275                         SetFrameRateArgs args = (SetFrameRateArgs) msg.obj;
276                         listener.onSetFrameRate(SurfaceTexture.this,
277                                 args.mFrameRate, args.mCompatibility,
278                                 args.mChangeFrameRateStrategy);
279                     } finally {
280                         Trace.traceEnd(Trace.TRACE_TAG_VIEW);
281                     }
282                 }
283             };
284         } else {
285             mOnSetFrameRateHandler = null;
286         }
287     }
288 
289     /**
290      * Set the default size of the image buffers.  The image producer may override the buffer size,
291      * in which case the producer-set buffer size will be used, not the default size set by this
292      * method.  Both video and camera based image producers do override the size.  This method may
293      * be used to set the image size when producing images with {@link android.graphics.Canvas} (via
294      * {@link android.view.Surface#lockCanvas}), or OpenGL ES (via an EGLSurface).
295      * <p>
296      * The new default buffer size will take effect the next time the image producer requests a
297      * buffer to fill.  For {@link android.graphics.Canvas} this will be the next time {@link
298      * android.view.Surface#lockCanvas} is called.  For OpenGL ES, the EGLSurface should be
299      * destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated
300      * (via {@code eglCreateWindowSurface}) to ensure that the new default size has taken effect.
301      * <p>
302      * The width and height parameters must be no greater than the minimum of
303      * {@code GL_MAX_VIEWPORT_DIMS} and {@code GL_MAX_TEXTURE_SIZE} (see
304      * {@link javax.microedition.khronos.opengles.GL10#glGetIntegerv glGetIntegerv}).
305      * An error due to invalid dimensions might not be reported until
306      * updateTexImage() is called.
307      */
setDefaultBufferSize(int width, int height)308     public void setDefaultBufferSize(int width, int height) {
309         nativeSetDefaultBufferSize(width, height);
310     }
311 
312     /**
313      * Update the texture image to the most recent frame from the image stream.  This may only be
314      * called while the OpenGL ES context that owns the texture is current on the calling thread.
315      * It will implicitly bind its texture to the {@code GL_TEXTURE_EXTERNAL_OES} texture target.
316      */
updateTexImage()317     public void updateTexImage() {
318         nativeUpdateTexImage();
319     }
320 
321     /**
322      * Releases the texture content. This is needed in single buffered mode to allow the image
323      * content producer to take ownership of the image buffer.
324      * <p>
325      * For more information see {@link #SurfaceTexture(int, boolean)}.
326      */
releaseTexImage()327     public void releaseTexImage() {
328         nativeReleaseTexImage();
329     }
330 
331     /**
332      * Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object.
333      * This call must be made with the OpenGL ES context current on the calling thread.  The OpenGL
334      * ES texture object will be deleted as a result of this call.  After calling this method all
335      * calls to {@link #updateTexImage} will throw an {@link java.lang.IllegalStateException} until
336      * a successful call to {@link #attachToGLContext} is made.
337      * <p>
338      * This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
339      * contexts.  Note, however, that the image contents are only accessible from one OpenGL ES
340      * context at a time.
341      */
detachFromGLContext()342     public void detachFromGLContext() {
343         int err = nativeDetachFromGLContext();
344         if (err != 0) {
345             throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
346         }
347     }
348 
349     /**
350      * Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread.  A
351      * new OpenGL ES texture object is created and populated with the SurfaceTexture image frame
352      * that was current at the time of the last call to {@link #detachFromGLContext}.  This new
353      * texture is bound to the {@code GL_TEXTURE_EXTERNAL_OES} texture target.
354      * <p>
355      * This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
356      * contexts.  Note, however, that the image contents are only accessible from one OpenGL ES
357      * context at a time.
358      *
359      * @param texName The name of the OpenGL ES texture that will be created.  This texture name
360      * must be unused in the OpenGL ES context that is current on the calling thread.
361      */
attachToGLContext(int texName)362     public void attachToGLContext(int texName) {
363         int err = nativeAttachToGLContext(texName);
364         if (err != 0) {
365             throw new RuntimeException("Error during attachToGLContext (see logcat for details)");
366         }
367     }
368 
369     /**
370      * Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by
371      * the most recent call to {@link #updateTexImage}.
372      * <p>
373      * This transform matrix maps 2D homogeneous texture coordinates of the form (s, t, 0, 1) with s
374      * and t in the inclusive range [0, 1] to the texture coordinate that should be used to sample
375      * that location from the texture.  Sampling the texture outside of the range of this transform
376      * is undefined.
377      * <p>
378      * The matrix is stored in column-major order so that it may be passed directly to OpenGL ES via
379      * the {@code glLoadMatrixf} or {@code glUniformMatrix4fv} functions.
380      * <p>
381      * If the underlying buffer has a crop associated with it, the transformation will also include
382      * a slight scale to cut off a 1-texel border around the edge of the crop. This ensures that
383      * when the texture is bilinear sampled that no texels outside of the buffer's valid region
384      * are accessed by the GPU, avoiding any sampling artifacts when scaling.
385      *
386      * @param mtx the array into which the 4x4 matrix will be stored.  The array must have exactly
387      *     16 elements.
388      */
getTransformMatrix(float[] mtx)389     public void getTransformMatrix(float[] mtx) {
390         // Note we intentionally don't check mtx for null, so this will result in a
391         // NullPointerException. But it's safe because it happens before the call to native.
392         if (mtx.length != 16) {
393             throw new IllegalArgumentException();
394         }
395         nativeGetTransformMatrix(mtx);
396     }
397 
398     /**
399      * Retrieve the timestamp associated with the texture image set by the most recent call to
400      * {@link #updateTexImage}.
401      *
402      * <p>This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp
403      * should be unaffected by time-of-day adjustments. The specific meaning and zero point of the
404      * timestamp depends on the source providing images to the SurfaceTexture. Unless otherwise
405      * specified by the image source, timestamps cannot generally be compared across SurfaceTexture
406      * instances, or across multiple program invocations. It is mostly useful for determining time
407      * offsets between subsequent frames.</p>
408      *
409      * <p>For camera sources, timestamps should be strictly monotonic. Timestamps from MediaPlayer
410      * sources may be reset when the playback position is set. For EGL and Vulkan producers, the
411      * timestamp is the desired present time set with the {@code EGL_ANDROID_presentation_time} or
412      * {@code VK_GOOGLE_display_timing} extensions.</p>
413      */
414 
getTimestamp()415     public long getTimestamp() {
416         return nativeGetTimestamp();
417     }
418 
419     /**
420      * Retrieve the dataspace associated with the texture image
421      * set by the most recent call to {@link #updateTexImage}.
422      */
423     @SuppressLint("MethodNameUnits")
getDataSpace()424     public @NamedDataSpace int getDataSpace() {
425         return nativeGetDataSpace();
426     }
427 
428     /**
429      * {@code release()} frees all the buffers and puts the SurfaceTexture into the
430      * 'abandoned' state. Once put in this state the SurfaceTexture can never
431      * leave it. When in the 'abandoned' state, all methods of the
432      * {@code IGraphicBufferProducer} interface will fail with the {@code NO_INIT}
433      * error.
434      * <p>
435      * Note that while calling this method causes all the buffers to be freed
436      * from the perspective of the SurfaceTexture, if there are additional
437      * references on the buffers (e.g. if a buffer is referenced by a client or
438      * by OpenGL ES as a texture) then those buffer will remain allocated.
439      * <p>
440      * Always call this method when you are done with SurfaceTexture. Failing
441      * to do so may delay resource deallocation for a significant amount of
442      * time.
443      *
444      * @see #isReleased()
445      */
release()446     public void release() {
447         nativeRelease();
448     }
449 
450     /**
451      * Returns {@code true} if the SurfaceTexture was released.
452      *
453      * @see #release()
454      */
isReleased()455     public boolean isReleased() {
456         return nativeIsReleased();
457     }
458 
459     @Override
finalize()460     protected void finalize() throws Throwable {
461         try {
462             nativeFinalize();
463         } finally {
464             super.finalize();
465         }
466     }
467 
468     /**
469      * This method is invoked from native code only.
470      */
471     @SuppressWarnings({"UnusedDeclaration"})
472     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
postEventFromNative(WeakReference<SurfaceTexture> weakSelf)473     private static void postEventFromNative(WeakReference<SurfaceTexture> weakSelf) {
474         SurfaceTexture st = weakSelf.get();
475         if (st != null) {
476             Handler handler = st.mOnFrameAvailableHandler;
477             if (handler != null) {
478                 handler.sendEmptyMessage(0);
479             }
480         }
481     }
482 
483     /**
484      * This method is invoked from native code only.
485      * @hide
486      */
487     @SuppressWarnings({"UnusedDeclaration"})
postOnSetFrameRateEventFromNative(WeakReference<SurfaceTexture> weakSelf, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility, @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy)488     private static void postOnSetFrameRateEventFromNative(WeakReference<SurfaceTexture> weakSelf,
489             @FloatRange(from = 0.0) float frameRate,
490             @Surface.FrameRateCompatibility int compatibility,
491             @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) {
492         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "postOnSetFrameRateEventFromNative");
493         try {
494             if (Flags.toolkitSetFrameRateReadOnly()) {
495                 SurfaceTexture st = weakSelf.get();
496                 if (st != null) {
497                     Handler handler = st.mOnSetFrameRateHandler;
498                     if (handler != null) {
499                         Message msg = new Message();
500                         msg.obj = new SetFrameRateArgs(frameRate, compatibility,
501                                 changeFrameRateStrategy);
502                         handler.sendMessage(msg);
503                     }
504                 }
505             }
506         } finally {
507             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
508         }
509 
510     }
511 
512     /**
513      * Returns {@code true} if the SurfaceTexture is single-buffered.
514      * @hide
515      */
isSingleBuffered()516     public boolean isSingleBuffered() {
517         return mIsSingleBuffered;
518     }
519 
nativeInit(boolean isDetached, int texName, boolean singleBufferMode, WeakReference<SurfaceTexture> weakSelf)520     private native void nativeInit(boolean isDetached, int texName,
521             boolean singleBufferMode, WeakReference<SurfaceTexture> weakSelf)
522             throws Surface.OutOfResourcesException;
nativeFinalize()523     private native void nativeFinalize();
nativeGetTransformMatrix(float[] mtx)524     private native void nativeGetTransformMatrix(float[] mtx);
nativeGetTimestamp()525     private native long nativeGetTimestamp();
nativeGetDataSpace()526     private native int nativeGetDataSpace();
nativeSetDefaultBufferSize(int width, int height)527     private native void nativeSetDefaultBufferSize(int width, int height);
nativeUpdateTexImage()528     private native void nativeUpdateTexImage();
nativeReleaseTexImage()529     private native void nativeReleaseTexImage();
530     @UnsupportedAppUsage
nativeDetachFromGLContext()531     private native int nativeDetachFromGLContext();
nativeAttachToGLContext(int texName)532     private native int nativeAttachToGLContext(int texName);
nativeRelease()533     private native void nativeRelease();
nativeIsReleased()534     private native boolean nativeIsReleased();
535 }
536