Skip to content

Commit 335a662

Browse files
Jamie GennisAndroid (Google) Code Review
authored andcommitted
Merge changes Iac9cc917,I8eed4b0d
* changes: TextureView: add setSurfaceTexture method SurfaceTexture: add GL context attach & detach
2 parents aca9ef4 + 2af3524 commit 335a662

File tree

5 files changed

+123
-13
lines changed

5 files changed

+123
-13
lines changed

core/java/android/view/GLES20TextureLayer.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class GLES20TextureLayer extends GLES20Layer {
4242
}
4343
}
4444

45+
GLES20TextureLayer(SurfaceTexture surface, boolean isOpaque) {
46+
this(isOpaque);
47+
mSurface = surface;
48+
mSurface.attachToGLContext(mTexture);
49+
}
50+
4551
@Override
4652
boolean isValid() {
4753
return mLayer != 0 && mTexture != 0;
@@ -72,6 +78,14 @@ SurfaceTexture getSurfaceTexture() {
7278
return mSurface;
7379
}
7480

81+
void setSurfaceTexture(SurfaceTexture surfaceTexture) {
82+
if (mSurface != null) {
83+
mSurface.release();
84+
}
85+
mSurface = surfaceTexture;
86+
mSurface.attachToGLContext(mTexture);
87+
}
88+
7589
@Override
7690
void update(int width, int height, boolean isOpaque) {
7791
super.update(width, height, isOpaque);

core/java/android/view/HardwareRenderer.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,9 @@ abstract boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbac
391391
* @param isOpaque Whether the layer should be opaque or not
392392
*
393393
* @return A hardware layer
394-
*/
394+
*/
395395
abstract HardwareLayer createHardwareLayer(boolean isOpaque);
396-
396+
397397
/**
398398
* Creates a new hardware layer.
399399
*
@@ -416,6 +416,15 @@ abstract boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbac
416416
*/
417417
abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
418418

419+
/**
420+
* Sets the {@link android.graphics.SurfaceTexture} that will be used to
421+
* render into the specified hardware layer.
422+
*
423+
* @param layer The layer to render into using a {@link android.graphics.SurfaceTexture}
424+
* @param surfaceTexture The {@link android.graphics.SurfaceTexture} to use for the layer
425+
*/
426+
abstract void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture);
427+
419428
/**
420429
* Initializes the hardware renderer for the specified surface and setup the
421430
* renderer for drawing, if needed. This is invoked when the ViewAncestor has
@@ -1344,6 +1353,11 @@ SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
13441353
return ((GLES20TextureLayer) layer).getSurfaceTexture();
13451354
}
13461355

1356+
@Override
1357+
void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
1358+
((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture);
1359+
}
1360+
13471361
@Override
13481362
void destroyLayers(View view) {
13491363
if (view != null && isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) {

core/java/android/view/TextureView.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public class TextureView extends View {
115115

116116
private final Object[] mLock = new Object[0];
117117
private boolean mUpdateLayer;
118+
private boolean mUpdateSurface;
118119

119120
private SurfaceTexture.OnFrameAvailableListener mUpdateListener;
120121

@@ -208,6 +209,8 @@ protected void onDetachedFromWindow() {
208209

209210
private void destroySurface() {
210211
if (mLayer != null) {
212+
mSurface.detachFromGLContext();
213+
211214
boolean shouldRelease = true;
212215
if (mListener != null) {
213216
shouldRelease = mListener.onSurfaceTextureDestroyed(mSurface);
@@ -322,9 +325,13 @@ HardwareLayer getHardwareLayer() {
322325
}
323326

324327
mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
325-
mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
328+
if (!mUpdateSurface) {
329+
// We already have a SurfaceTexture to use, and we will pass it
330+
// to mLayer below.
331+
mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
332+
}
326333
nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
327-
nCreateNativeWindow(mSurface);
334+
nCreateNativeWindow(mSurface);
328335

329336
mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
330337
@Override
@@ -344,6 +351,15 @@ public void onFrameAvailable(SurfaceTexture surfaceTexture) {
344351
}
345352
}
346353

354+
if (mUpdateSurface) {
355+
// Someone has requested that we use a specific SurfaceTexture, so
356+
// tell mLayer about it and set the SurfaceTexture to use the
357+
// current view size.
358+
mUpdateSurface = false;
359+
mAttachInfo.mHardwareRenderer.setSurfaceTexture(mLayer, mSurface);
360+
nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
361+
}
362+
347363
applyUpdate();
348364
applyTransformMatrix();
349365

@@ -371,7 +387,7 @@ private void updateLayer() {
371387
mUpdateLayer = true;
372388
invalidate();
373389
}
374-
390+
375391
private void applyUpdate() {
376392
if (mLayer == null) {
377393
return;
@@ -635,6 +651,32 @@ public SurfaceTexture getSurfaceTexture() {
635651
return mSurface;
636652
}
637653

654+
/**
655+
* Set the {@link SurfaceTexture} for this view to use. If a {@link
656+
* SurfaceTexture} is already being used by this view, it is immediately
657+
* released and not be usable any more. The {@link
658+
* SurfaceTextureListener#onSurfaceTextureDestroyed} callback is <b>not</b>
659+
* called.
660+
*
661+
* The {@link SurfaceTexture} object must be detached from all OpenGL ES
662+
* contexts prior to calling this method.
663+
*
664+
* @param surfaceTexture The {@link SurfaceTexture} that the view should use.
665+
* @see SurfaceTexture#detachFromGLContext()
666+
* @hide
667+
*/
668+
public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
669+
if (surfaceTexture == null) {
670+
throw new NullPointerException("surfaceTexture must not be null");
671+
}
672+
if (mSurface != null) {
673+
mSurface.release();
674+
}
675+
mSurface = surfaceTexture;
676+
mUpdateSurface = true;
677+
invalidateParentIfNeeded();
678+
}
679+
638680
/**
639681
* Returns the {@link SurfaceTextureListener} currently associated with this
640682
* texture view.

core/jni/android/graphics/SurfaceTexture.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,18 @@ static jint SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
218218
return surfaceTexture->updateTexImage();
219219
}
220220

221+
static jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
222+
{
223+
sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
224+
return surfaceTexture->detachFromContext();
225+
}
226+
227+
static jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
228+
{
229+
sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
230+
return surfaceTexture->attachToContext((GLuint)tex);
231+
}
232+
221233
static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
222234
jfloatArray jmtx)
223235
{
@@ -242,14 +254,16 @@ static void SurfaceTexture_release(JNIEnv* env, jobject thiz)
242254
// ----------------------------------------------------------------------------
243255

244256
static JNINativeMethod gSurfaceTextureMethods[] = {
245-
{"nativeClassInit", "()V", (void*)SurfaceTexture_classInit },
246-
{"nativeInit", "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
247-
{"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
257+
{"nativeClassInit", "()V", (void*)SurfaceTexture_classInit },
258+
{"nativeInit", "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
259+
{"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
248260
{"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
249-
{"nativeUpdateTexImage", "()I", (void*)SurfaceTexture_updateTexImage },
250-
{"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
251-
{"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
252-
{"nativeRelease", "()V", (void*)SurfaceTexture_release },
261+
{"nativeUpdateTexImage", "()I", (void*)SurfaceTexture_updateTexImage },
262+
{"nativeDetachFromGLContext", "()I", (void*)SurfaceTexture_detachFromGLContext },
263+
{"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext },
264+
{"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
265+
{"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
266+
{"nativeRelease", "()V", (void*)SurfaceTexture_release },
253267
};
254268

255269
int register_android_graphics_SurfaceTexture(JNIEnv* env)

graphics/java/android/graphics/SurfaceTexture.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,31 @@ public void setDefaultBufferSize(int width, int height) {
161161
public void updateTexImage() {
162162
int err = nativeUpdateTexImage();
163163
if (err != 0) {
164-
throw new RuntimeException("Error during updateTexImage (see logs)");
164+
throw new RuntimeException("Error during updateTexImage (see logcat for details)");
165+
}
166+
}
167+
168+
/**
169+
* Detach the SurfaceTexture from the OpenGL ES context with which it is currently associated.
170+
* This can be used to change from one OpenGL ES context to another.
171+
*
172+
* @hide
173+
*/
174+
public void detachFromGLContext() {
175+
int err = nativeDetachFromGLContext();
176+
if (err != 0) {
177+
throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
178+
}
179+
}
180+
181+
/**
182+
*
183+
* @hide
184+
*/
185+
public void attachToGLContext(int texName) {
186+
int err = nativeAttachToGLContext(texName);
187+
if (err != 0) {
188+
throw new RuntimeException("Error during detachFromGLContext (see logcat for details)");
165189
}
166190
}
167191

@@ -269,6 +293,8 @@ private static void postEventFromNative(Object selfRef) {
269293
private native long nativeGetTimestamp();
270294
private native void nativeSetDefaultBufferSize(int width, int height);
271295
private native int nativeUpdateTexImage();
296+
private native int nativeDetachFromGLContext();
297+
private native int nativeAttachToGLContext(int texName);
272298
private native int nativeGetQueuedCount();
273299
private native void nativeRelease();
274300

0 commit comments

Comments
 (0)