2
2
3
3
import android .annotation .TargetApi ;
4
4
import android .graphics .Bitmap ;
5
+ import android .graphics .PixelFormat ;
5
6
import android .graphics .SurfaceTexture ;
6
7
import android .os .Build ;
7
8
import android .os .Handler ;
26
27
27
28
public final class EngineView extends FrameLayout implements SurfaceHolder .Callback , TextureView .SurfaceTextureListener , View .OnTouchListener {
28
29
private static final FrameLayout .LayoutParams childViewLayoutParams = new FrameLayout .LayoutParams (LayoutParams .MATCH_PARENT , LayoutParams .MATCH_PARENT );
29
- private TextureView transparentTextureView ;
30
+ private SurfaceView surfaceView = null ;
30
31
private Surface transparentSurface = null ;
31
- private SurfaceView opaqueSurfaceView = null ;
32
+ private TextureView transparentTextureView = null ;
33
+
32
34
private SurfaceView xrSurfaceView ;
35
+ private boolean isTransparent = false ;
36
+ private boolean isTopMost = false ;
33
37
private final EventDispatcher reactEventDispatcher ;
34
38
private Runnable renderRunnable ;
35
39
36
40
public EngineView (ReactContext reactContext ) {
37
41
super (reactContext );
38
42
39
- this .setIsTransparent ( false );
43
+ this .setIsTransparentAndIsTopMost ( false , false );
40
44
41
45
this .xrSurfaceView = new SurfaceView (reactContext );
42
46
this .xrSurfaceView .setLayoutParams (childViewLayoutParams );
@@ -67,34 +71,54 @@ public void surfaceDestroyed(SurfaceHolder holder) {
67
71
public void setAntiAliasing (Integer value ) {
68
72
BabylonNativeInterop .updateMSAA (value );
69
73
}
74
+
75
+ public void setIsTopMost (Boolean isTopMost ) {
76
+ setIsTransparentAndIsTopMost (this .isTransparent , isTopMost );
77
+ }
70
78
// ------------------------------------
71
79
// TextureView related
72
-
73
80
public void setIsTransparent (Boolean isTransparent ) {
74
- if (isTransparent ) {
75
- if (this .opaqueSurfaceView != null ) {
76
- this .opaqueSurfaceView .setVisibility (View .GONE );
77
- this .opaqueSurfaceView = null ;
78
- }
79
- if (this .transparentTextureView == null ) {
80
- this .transparentTextureView = new TextureView (this .getContext ());
81
- this .transparentTextureView .setLayoutParams (EngineView .childViewLayoutParams );
82
- this .transparentTextureView .setSurfaceTextureListener (this );
83
- this .transparentTextureView .setOpaque (false );
84
- this .addView (this .transparentTextureView );
85
- }
81
+ setIsTransparentAndIsTopMost (isTransparent , this .isTopMost );
82
+ }
83
+
84
+ private void setIsTransparentAndIsTopMost (Boolean isTransparent , Boolean isTopMost ) {
85
+ if (this .isTransparent == isTransparent && this .isTopMost == isTopMost &&
86
+ (this .surfaceView != null || this .transparentTextureView != null )) {
87
+ return ;
88
+ }
89
+ if (this .surfaceView != null ) {
90
+ this .surfaceView .setVisibility (View .GONE );
91
+ this .surfaceView = null ;
92
+ }
93
+ if (this .transparentTextureView != null ) {
94
+ this .transparentTextureView .setVisibility (View .GONE );
95
+ this .transparentTextureView = null ;
96
+ }
97
+ if (isTransparent && !isTopMost ) {
98
+ this .transparentTextureView = new TextureView (this .getContext ());
99
+ this .transparentTextureView .setLayoutParams (EngineView .childViewLayoutParams );
100
+ this .transparentTextureView .setSurfaceTextureListener (this );
101
+ this .transparentTextureView .setOpaque (false );
102
+ this .addView (this .transparentTextureView );
86
103
} else {
87
- if (this .transparentTextureView != null ) {
88
- this .transparentTextureView .setVisibility (View .GONE );
89
- this .transparentTextureView = null ;
104
+ this .surfaceView = new SurfaceView (this .getContext ());
105
+ this .surfaceView .setLayoutParams (EngineView .childViewLayoutParams );
106
+ SurfaceHolder surfaceHolder = this .surfaceView .getHolder ();
107
+ if (isTransparent ) {
108
+ surfaceHolder .setFormat (PixelFormat .TRANSPARENT );
90
109
}
91
- if (this .opaqueSurfaceView == null ) {
92
- this .opaqueSurfaceView = new SurfaceView (this .getContext ());
93
- this .opaqueSurfaceView .setLayoutParams (EngineView .childViewLayoutParams );
94
- this .opaqueSurfaceView .getHolder ().addCallback (this );
95
- this .addView (this .opaqueSurfaceView );
110
+ if (isTopMost ) {
111
+ // ZOrder is not dynamic before Android 11. Recreate the surfaceView and set order before adding to the parent
112
+ // https://developer.android.com/reference/android/view/SurfaceView#setZOrderOnTop(boolean)
113
+ this .surfaceView .setZOrderOnTop (true );
96
114
}
115
+ surfaceHolder .addCallback (this );
116
+ this .addView (this .surfaceView );
97
117
}
118
+
119
+ this .isTransparent = isTransparent ;
120
+ this .isTopMost = isTopMost ;
121
+
98
122
// xr view needs to be on top of views that might be created after it.
99
123
if (this .xrSurfaceView != null ) {
100
124
this .xrSurfaceView .bringToFront ();
@@ -117,6 +141,9 @@ public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
117
141
this .renderRunnable = null ;
118
142
}
119
143
144
+ // ------------------------------------
145
+ // TextureView
146
+
120
147
@ Override
121
148
public void onSurfaceTextureAvailable (@ NonNull SurfaceTexture surfaceTexture , int i , int i1 ) {
122
149
this .startRenderLoop ();
@@ -140,8 +167,6 @@ public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture)
140
167
141
168
@ Override
142
169
public void onSurfaceTextureUpdated (@ NonNull SurfaceTexture surfaceTexture ) {
143
- this .acquireNewTransparentSurface (surfaceTexture );
144
- BabylonNativeInterop .updateView (this .transparentSurface );
145
170
}
146
171
147
172
private void acquireNewTransparentSurface (@ NonNull SurfaceTexture surfaceTexture ) {
@@ -182,8 +207,8 @@ public void takeSnapshot() {
182
207
Surface sourceSurface = this .transparentSurface ;
183
208
if (BabylonNativeInterop .isXRActive ()) {
184
209
sourceSurface = this .xrSurfaceView .getHolder ().getSurface ();
185
- } else if (this .opaqueSurfaceView != null ) {
186
- sourceSurface = this .opaqueSurfaceView .getHolder ().getSurface ();
210
+ } else if (this .surfaceView != null ) {
211
+ sourceSurface = this .surfaceView .getHolder ().getSurface ();
187
212
}
188
213
PixelCopy .request (sourceSurface , bitmap , getOnPixelCopyFinishedListener (bitmap , helperThread ), helperThreadHandler );
189
214
}
0 commit comments