Project

General

Profile

« Previous | Next » 

Revision 0de83d97

Added by Leszek Koltunski almost 6 years ago

Fix several more apps for the 'center-of-matrix-effects-in-screen-center' change.

View differences:

src/main/AndroidManifest.xml
37 37
        <activity android:name=".quaternion.QuaternionActivity" />          
38 38
        <activity android:name=".effects3d.Effects3DActivity" />
39 39
        <activity android:name=".effects3d.Effects3DActivity2"/>
40
        <activity android:name=".plainmonalisa.PlainMonaLisaActivity" />
40
        <activity android:name=".surfaceview.SurfaceViewActivity" />
41 41
        <activity android:name=".save.SaveActivity"/>
42 42
        <activity android:name=".flag.FlagActivity"/>
43 43
        <activity android:name=".wind.WindActivity"/>
src/main/java/org/distorted/examples/TableOfContents.java
54 54
import org.distorted.examples.inflate.InflateActivity;
55 55
import org.distorted.examples.quaternion.QuaternionActivity;
56 56
import org.distorted.examples.effects3d.Effects3DActivity;
57
import org.distorted.examples.plainmonalisa.PlainMonaLisaActivity;
57
import org.distorted.examples.surfaceview.SurfaceViewActivity;
58 58
import org.distorted.examples.save.SaveActivity;
59 59
import org.distorted.examples.flag.FlagActivity;
60 60
import org.distorted.examples.wind.WindActivity;
......
278 278
      item.put(ITEM_TITLE, (i+1)+". "+getText(R.string.example_plainmonalisa));
279 279
      item.put(ITEM_SUBTITLE, getText(R.string.example_plainmonalisa_subtitle));
280 280
      data.add(item);
281
      activityMapping.put(i++, PlainMonaLisaActivity.class);
281
      activityMapping.put(i++, SurfaceViewActivity.class);
282 282
   }
283 283

  
284 284
   {
src/main/java/org/distorted/examples/flag/FlagRenderer.java
24 24
import android.opengl.GLSurfaceView;
25 25

  
26 26
import org.distorted.examples.R;
27
import org.distorted.library.effect.MatrixEffectMove;
28 27
import org.distorted.library.effect.MatrixEffectQuaternion;
29 28
import org.distorted.library.effect.MatrixEffectScale;
30 29
import org.distorted.library.effect.VertexEffectWave;
......
55 54
    private Dynamic5D mWaveDyn;
56 55
    private Static5D mWaveSta1, mWaveSta2;
57 56
    private int mObjWidth, mObjHeight;
58
    private Static3D mMove, mScale, mCenter;
57
    private Static3D mScale;
59 58

  
60 59
    Static4D mQuat1, mQuat2;
61 60
    int mScreenMin;
......
88 87
      DistortedEffects effects = new DistortedEffects();
89 88
      effects.apply( new VertexEffectWave(mWaveDyn, waveCenter, waveRegion) );
90 89

  
91
      mMove  = new Static3D(0,0,0);
92 90
      mScale = new Static3D(1,1,1);
93
      mCenter= new Static3D(0,0,0);
91
      Static3D center= new Static3D(0,0,0);
94 92

  
95
      effects.apply( new MatrixEffectMove(mMove));
96 93
      effects.apply( new MatrixEffectScale(mScale));
97
      effects.apply( new MatrixEffectQuaternion(mQuat1, mCenter) );
98
      effects.apply( new MatrixEffectQuaternion(mQuat2, mCenter) );
94
      effects.apply( new MatrixEffectQuaternion(mQuat1, center) );
95
      effects.apply( new MatrixEffectQuaternion(mQuat2, center) );
99 96

  
100 97
      final int GRIDX = 50;
101 98
      final int GRIDY = 30;
......
160 157
      {
161 158
      mScreenMin = width<height ? width:height;
162 159
      float factor = ( width*mObjHeight > height*mObjWidth ) ? (0.8f*height)/mObjHeight : (0.8f*width)/mObjWidth;
163
      mMove.set((width-factor*mObjWidth)/2 , (height-factor*mObjHeight)/2 , 0);
164 160
      mScale.set(factor,factor,factor);
165
      mCenter.set(mObjWidth/2,mObjHeight/2, 0);
166 161
      mScreen.resize(width, height);
167 162
      }
168 163

  
src/main/java/org/distorted/examples/plainmonalisa/EglCore.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.plainmonalisa;
21

  
22
import android.graphics.SurfaceTexture;
23
import android.opengl.EGL14;
24
import android.opengl.EGLConfig;
25
import android.opengl.EGLContext;
26
import android.opengl.EGLDisplay;
27
import android.opengl.EGLExt;
28
import android.opengl.EGLSurface;
29
import android.os.Build;
30
import android.util.Log;
31
import android.view.Surface;
32

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

  
35
public final class EglCore
36
  {
37
  private static final String TAG = "EglCore";
38

  
39
  public static final int FLAG_RECORDABLE = 0x01;           // Surface must be recordable.  This discourages EGL from using a
40
                                                            // pixel format that cannot be converted efficiently to something 
41
                                                            // usable by the video encoder.
42
  public static final int FLAG_TRY_GLES3 = 0x02;            // Ask for GLES3, fall back to GLES2 if not available.
43

  
44
  private static final int EGL_RECORDABLE_ANDROID = 0x3142; // Android-specific extension
45

  
46
  private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
47
  private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
48
  private EGLConfig mEGLConfig = null;
49
  private int mGlVersion = -1;
50

  
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

  
53
  public EglCore()
54
    {
55
    this(null, 0);
56
    }
57

  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

  
60
  public EglCore(EGLContext sharedContext, int flags)
61
    {
62
    if (mEGLDisplay != EGL14.EGL_NO_DISPLAY)
63
      {
64
      throw new RuntimeException("EGL already set up");
65
      }
66

  
67
    if (sharedContext == null)
68
      {
69
      sharedContext = EGL14.EGL_NO_CONTEXT;
70
      }
71

  
72
    mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
73

  
74
    if (mEGLDisplay == EGL14.EGL_NO_DISPLAY)
75
      {
76
      throw new RuntimeException("unable to get EGL14 display");
77
      }
78

  
79
    int[] version = new int[2];
80

  
81
    if (!EGL14.eglInitialize(mEGLDisplay, version, 0, version, 1))
82
      {
83
      mEGLDisplay = null;
84
      throw new RuntimeException("unable to initialize EGL14");
85
      }
86

  
87
    // Try to get a GLES3 context, if requested.
88
    if ((flags & FLAG_TRY_GLES3) != 0)
89
      {
90
      //Log.d(TAG, "Trying GLES 3");
91
      EGLConfig config = getConfig(flags, 3);
92

  
93
      if (config != null)
94
        {
95
        int[] attrib3_list =  { EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE };
96
        EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib3_list, 0);
97

  
98
        if (EGL14.eglGetError() == EGL14.EGL_SUCCESS)
99
          {
100
          //Log.d(TAG, "Got GLES 3 config");
101
          mEGLConfig = config;
102
          mEGLContext = context;
103
          mGlVersion = 3;
104
          }
105
        }
106
      }
107

  
108
    if (mEGLContext == EGL14.EGL_NO_CONTEXT)
109
      {  // GLES 2 only, or GLES 3 attempt failed
110
         //Log.d(TAG, "Trying GLES 2");
111
      EGLConfig config = getConfig(flags, 2);
112

  
113
      if (config == null)
114
        {
115
        throw new RuntimeException("Unable to find a suitable EGLConfig");
116
        }
117
      int[] attrib2_list = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE };
118
      EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib2_list, 0);
119
      checkEglError("eglCreateContext");
120
      mEGLConfig = config;
121
      mEGLContext = context;
122
      mGlVersion = 2;
123
      }
124

  
125
    // Confirm with query.
126
    int[] values = new int[1];
127
    EGL14.eglQueryContext(mEGLDisplay, mEGLContext, EGL14.EGL_CONTEXT_CLIENT_VERSION, values, 0);
128

  
129
    Log.d(TAG, "EGLContext created, client version " + values[0]);
130
    }
131

  
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

  
134
  private EGLConfig getConfig(int flags, int version)
135
    {
136
    int renderableType = EGL14.EGL_OPENGL_ES2_BIT;
137

  
138
    if (version >= 3)
139
      {
140
      renderableType |= EGLExt.EGL_OPENGL_ES3_BIT_KHR;
141
      }
142

  
143
    // The actual surface is generally RGBA or RGBX, so situationally omitting alpha
144
    // doesn't really help.  It can also lead to a huge performance hit on glReadPixels()
145
    // when reading into a GL_RGBA buffer.
146

  
147
    int [] normalAttribList =
148
                {
149
                EGL14.EGL_RED_SIZE, 8,
150
                EGL14.EGL_GREEN_SIZE, 8,
151
                EGL14.EGL_BLUE_SIZE, 8,
152
                EGL14.EGL_ALPHA_SIZE, 8,
153
                EGL14.EGL_RENDERABLE_TYPE, renderableType,
154
                EGL14.EGL_NONE, 0,      // placeholder for recordable [@-3]
155
                EGL14.EGL_NONE
156
                };
157

  
158
    if ((flags & FLAG_RECORDABLE) != 0)
159
      {
160
      normalAttribList[normalAttribList.length - 3] = EGL_RECORDABLE_ANDROID;
161
      normalAttribList[normalAttribList.length - 2] = 1;
162
      }
163

  
164
    int [] emulatorAttribList =
165
                {
166
                EGL14.EGL_RED_SIZE, 8,
167
                EGL14.EGL_GREEN_SIZE, 8,
168
                EGL14.EGL_BLUE_SIZE, 8,
169
                EGL14.EGL_ALPHA_SIZE, 8,
170
                EGL14.EGL_DEPTH_SIZE, 16,
171
                EGL14.EGL_STENCIL_SIZE, 0,
172
                EGL14.EGL_NONE
173
                };
174

  
175
    boolean isEmulator=
176
               Build.FINGERPRINT.startsWith("generic")
177
            || Build.FINGERPRINT.startsWith("unknown")
178
            || Build.MODEL.contains("google_sdk")
179
            || Build.MODEL.contains("Emulator")
180
            || Build.MODEL.contains("Android SDK built for x86")
181
            || Build.MANUFACTURER.contains("Genymotion")
182
            || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
183
            || "google_sdk".equals(Build.PRODUCT);
184

  
185
    int [] attribList = (isEmulator ? emulatorAttribList:normalAttribList);
186

  
187
    if( isEmulator )
188
      {
189
      Log.w(TAG, "Using emulator config!" );
190
      }
191

  
192
    EGLConfig[] configs = new EGLConfig[1];
193
    int[] numConfigs = new int[1];
194

  
195
    if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0))
196
      {
197
      Log.w(TAG, "unable to find RGB8888 / " + version + " EGLConfig");
198
      return null;
199
      }
200

  
201
    return configs[0];
202
    }
203

  
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

  
206
  public void release()
207
    {
208
    if (mEGLDisplay != EGL14.EGL_NO_DISPLAY)
209
      {
210
      EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
211
      EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
212
      EGL14.eglReleaseThread();
213
      EGL14.eglTerminate(mEGLDisplay);
214
      }
215

  
216
    mEGLDisplay = EGL14.EGL_NO_DISPLAY;
217
    mEGLContext = EGL14.EGL_NO_CONTEXT;
218
    mEGLConfig = null;
219
    }
220

  
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222
  @Override
223
  protected void finalize() throws Throwable
224
    {
225
    try
226
      {
227
      if (mEGLDisplay != EGL14.EGL_NO_DISPLAY)
228
        {
229
        // We're limited here -- finalizers don't run on the thread that holds
230
        // the EGL state, so if a surface or context is still current on another
231
        // thread we can't fully release it here.  Exceptions thrown from here
232
        // are quietly discarded.  Complain in the log file.
233
        Log.w(TAG, "WARNING: EglCore was not explicitly released -- state may be leaked");
234
        release();
235
        }
236
      }
237
    finally
238
      {
239
      super.finalize();
240
      }
241
    }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

  
245
  public void releaseSurface(EGLSurface eglSurface)
246
    {
247
    EGL14.eglDestroySurface(mEGLDisplay, eglSurface);
248
    }
249

  
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

  
252
  public EGLSurface createWindowSurface(Object surface)
253
    {
254
    if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture))
255
      {
256
      throw new RuntimeException("invalid surface: " + surface);
257
      }
258

  
259
    int[] surfaceAttribs = { EGL14.EGL_NONE };
260
    EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0);
261
    checkEglError("eglCreateWindowSurface");
262

  
263
    if (eglSurface == null)
264
      {
265
      throw new RuntimeException("surface was null");
266
      }
267
    return eglSurface;
268
    }
269

  
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

  
272
  public void makeCurrent(EGLSurface eglSurface)
273
    {
274
    if (mEGLDisplay == EGL14.EGL_NO_DISPLAY)
275
      {
276
      Log.d(TAG, "NOTE: makeCurrent w/o display");
277
      }
278
    if (!EGL14.eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext))
279
      {
280
      throw new RuntimeException("eglMakeCurrent failed");
281
      }
282
    }
283

  
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

  
286
  public void makeNothingCurrent()
287
    {
288
    if (!EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT))
289
      {
290
      throw new RuntimeException("eglMakeCurrent failed");
291
      }
292
    }
293

  
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

  
296
  public int getGlVersion()
297
    {
298
    return mGlVersion;
299
    }
300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
  public boolean swapBuffers(EGLSurface eglSurface)
304
    {
305
    return EGL14.eglSwapBuffers(mEGLDisplay, eglSurface);
306
    }
307

  
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309

  
310
  private void checkEglError(String msg)
311
    {
312
    int error;
313

  
314
    if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS)
315
      {
316
      throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error));
317
      }
318
    }
319
  }
src/main/java/org/distorted/examples/plainmonalisa/PlainMonaLisaActivity.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.plainmonalisa;
21

  
22
import org.distorted.library.main.Distorted;
23

  
24
import android.app.Activity;
25
import android.os.Bundle;
26

  
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

  
29
public class PlainMonaLisaActivity extends Activity
30
{
31
    private PlainMonaLisaSurfaceView mView;
32

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34
    
35
    @Override
36
    protected void onCreate(Bundle icicle) 
37
      {
38
      super.onCreate(icicle);
39
      mView = new PlainMonaLisaSurfaceView(this);
40
      setContentView(mView);
41
      }
42

  
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44
    
45
    @Override
46
    protected void onPause() 
47
      {
48
      mView.onPause();
49
      Distorted.onPause();
50
      super.onPause();
51
      }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54
    
55
    @Override
56
    protected void onResume() 
57
      {
58
      super.onResume();
59
      mView.onResume();
60
      }
61
    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
    
64
    @Override
65
    protected void onDestroy() 
66
      {
67
      Distorted.onDestroy();  
68
      super.onDestroy();
69
      }
70
    
71
}
src/main/java/org/distorted/examples/plainmonalisa/PlainMonaLisaSurfaceView.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.plainmonalisa;
21

  
22
import android.content.Context;
23
import android.view.Choreographer;
24
import android.view.SurfaceView;
25
import android.view.SurfaceHolder;
26
import android.util.Log;
27

  
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

  
30
class PlainMonaLisaSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Choreographer.FrameCallback
31
  {
32
  private static final String TAG = "MonaLisaSurface";
33
  private RenderThread mRenderThread;
34
  private static volatile boolean mPaused = true;
35

  
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

  
38
  public PlainMonaLisaSurfaceView(Context context)
39
    {
40
    super(context);
41
    getHolder().addCallback(this);
42
    }
43

  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

  
46
  @Override
47
  public void surfaceCreated(SurfaceHolder holder)
48
    {
49
    Log.d(TAG, "surfaceCreated holder=" + holder);
50

  
51
    mRenderThread = new RenderThread(holder, this);
52
    mRenderThread.setName("GL render");
53
    mRenderThread.start();
54
    mRenderThread.waitUntilReady();
55

  
56
    RenderHandler rh = mRenderThread.getHandler();
57

  
58
    if (rh != null)
59
      {
60
      rh.sendSurfaceCreated();
61
      }
62

  
63
    Choreographer.getInstance().postFrameCallback(this);
64
    }
65

  
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

  
68
  @Override
69
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
70
    {
71
    Log.d(TAG, "surfaceChanged fmt=" + format + " size=" + width + "x" + height +" holder=" + holder);
72

  
73
    RenderHandler rh = mRenderThread.getHandler();
74

  
75
    if (rh != null)
76
      {
77
      rh.sendSurfaceChanged(format, width, height);
78
      }
79
    }
80

  
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

  
83
  @Override
84
  public void surfaceDestroyed(SurfaceHolder holder)
85
    {
86
    Log.d(TAG, "surfaceDestroyed holder=" + holder);
87

  
88
    // We need to wait for the render thread to shut down before continuing because we
89
    // don't want the Surface to disappear out from under it mid-render.  The frame
90
    // notifications will have been stopped back in onPause(), but there might have
91
    // been one in progress.
92

  
93
    RenderHandler rh = mRenderThread.getHandler();
94

  
95
    if (rh != null)
96
      {
97
      rh.sendShutdown();
98

  
99
      try
100
        {
101
        mRenderThread.join();
102
        }
103
      catch (InterruptedException ie)
104
        {
105
        throw new RuntimeException("join was interrupted", ie);
106
        }
107
      }
108
    mRenderThread = null;
109

  
110
    Log.d(TAG, "surfaceDestroyed complete");
111
    }
112

  
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

  
115
  public void onPause()
116
    {
117
    mPaused = true;
118
    RenderThread.setResourcesCreated();
119

  
120
    Log.d(TAG, "onPause unhooking choreographer");
121
    Choreographer.getInstance().removeFrameCallback(this);
122
    }
123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

  
126
  public void onResume()
127
    {
128
    mPaused = false;
129

  
130
    if (mRenderThread != null)
131
      {
132
      Log.d(TAG, "onResume re-hooking choreographer");
133
      Choreographer.getInstance().postFrameCallback(this);
134
      }
135
    }
136

  
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

  
139
  public static boolean isPaused()
140
    {
141
    return mPaused;
142
    }
143

  
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

  
146
  @Override
147
  public void doFrame(long frameTimeNanos)
148
    {
149
    RenderHandler rh = mRenderThread.getHandler();
150

  
151
    if (rh != null)
152
      {
153
      Choreographer.getInstance().postFrameCallback(this);
154
      rh.sendDoFrame(frameTimeNanos);
155
      }
156
    }
157
  }
158

  
159

  
src/main/java/org/distorted/examples/plainmonalisa/RenderHandler.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.plainmonalisa;
21

  
22
import android.os.Handler;
23
import android.os.Message;
24
import android.util.Log;
25

  
26
import java.lang.ref.WeakReference;
27

  
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29
// Used for messages sent from the UI thread to the render thread.
30

  
31
class RenderHandler extends Handler
32
  {
33
  private static final String TAG = "RenderHandler";
34

  
35
  private static final int MSG_SURFACE_CREATED = 0;
36
  private static final int MSG_SURFACE_CHANGED = 1;
37
  private static final int MSG_DO_FRAME = 2;
38
  private static final int MSG_SHUTDOWN = 4;
39

  
40
  private WeakReference<RenderThread> mWeakRenderThread;
41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

  
44
  RenderHandler(RenderThread rt)
45
    {
46
    mWeakRenderThread = new WeakReference<>(rt);
47
    }
48

  
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

  
51
  void sendSurfaceCreated()
52
    {
53
    sendMessage(obtainMessage(RenderHandler.MSG_SURFACE_CREATED));
54
    }
55

  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

  
58
  void sendSurfaceChanged(int format, int width, int height)
59
    {
60
    sendMessage(obtainMessage(RenderHandler.MSG_SURFACE_CHANGED, width, height));
61
    }
62

  
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

  
65
  void sendDoFrame(long frameTimeNanos)
66
    {
67
    sendMessage(obtainMessage(RenderHandler.MSG_DO_FRAME, (int) (frameTimeNanos >> 32), (int) frameTimeNanos));
68
    }
69

  
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

  
72
  void sendShutdown()
73
    {
74
    sendMessage(obtainMessage(RenderHandler.MSG_SHUTDOWN));
75
    }
76

  
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78
  @Override  // runs on RenderThread
79
  public void handleMessage(Message msg)
80
    {
81
    int what = msg.what;
82

  
83
    RenderThread renderThread = mWeakRenderThread.get();
84

  
85
    if (renderThread == null)
86
      {
87
      Log.w(TAG, "RenderHandler.handleMessage: weak ref is null");
88
      return;
89
      }
90

  
91
    switch (what)
92
      {
93
      case MSG_SURFACE_CREATED: renderThread.surfaceCreated();
94
                                break;
95
      case MSG_SURFACE_CHANGED: renderThread.surfaceChanged(msg.arg1, msg.arg2);
96
                                break;
97
      case MSG_DO_FRAME:        long timestamp = (((long) msg.arg1) << 32) | (((long) msg.arg2) & 0xffffffffL);
98
                                renderThread.doFrame(timestamp);
99
                                break;
100
      case MSG_SHUTDOWN:        renderThread.shutdown();
101
                                break;
102
      default:                  throw new RuntimeException("unknown message " + what);
103
      }
104
    }
105
  }
106

  
107
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.plainmonalisa;
21

  
22
import android.graphics.Bitmap;
23
import android.graphics.BitmapFactory;
24
import android.opengl.EGL14;
25
import android.opengl.EGLSurface;
26
import android.opengl.GLES31;
27
import android.os.Looper;
28
import android.util.Log;
29
import android.view.Surface;
30
import android.view.SurfaceHolder;
31
import android.view.SurfaceView;
32

  
33
import org.distorted.library.effect.MatrixEffectMove;
34
import org.distorted.library.effect.MatrixEffectScale;
35
import org.distorted.library.effect.VertexEffectDistort;
36
import org.distorted.library.main.Distorted;
37
import org.distorted.library.main.DistortedEffects;
38
import org.distorted.library.main.DistortedScreen;
39
import org.distorted.library.mesh.MeshFlat;
40
import org.distorted.library.main.DistortedTexture;
41
import org.distorted.library.type.Dynamic3D;
42
import org.distorted.library.type.Static3D;
43
import org.distorted.library.type.Static4D;
44
import org.distorted.examples.R;
45

  
46
import java.io.IOException;
47
import java.io.InputStream;
48

  
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

  
51
class RenderThread extends Thread
52
  {
53
  private static final String TAG = "RenderThread";
54

  
55
  // Object must be created on render thread to get correct Looper, but is used from
56
  // UI thread, so we need to declare it volatile to ensure the UI thread sees a fully
57
  // constructed object.
58
  private volatile RenderHandler mHandler;
59

  
60
  // Used to wait for the thread to start.
61
  private final Object mStartLock = new Object();
62
  private boolean mReady = false;
63
  private volatile SurfaceHolder mSurfaceHolder;  // may be updated by UI thread
64
  private EglCore eglCore;
65
  private EGLSurface eglSurface;
66

  
67
  private DistortedEffects mEffects;
68
  private DistortedTexture mTexture;
69
  private MeshFlat mMesh;
70
  private DistortedScreen mScreen;
71
  private int bmpHeight, bmpWidth;
72
  private SurfaceView mView;
73
  private static boolean resourcesCreated = false;
74
  private Static3D mMove, mScale;
75

  
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

  
78
  RenderThread(SurfaceHolder holder, SurfaceView view)
79
    {
80
    mSurfaceHolder = holder;
81
    mView = view;
82

  
83
    Static3D pLeft = new Static3D( 90, 108, 0);
84
    Static3D pRight= new Static3D(176, 111, 0);
85

  
86
    Static4D rLeft = new Static4D(-10, 10, 0,25);
87
    Static4D rRight= new Static4D( 10,  5, 0,25);
88

  
89
    Dynamic3D dLeft = new Dynamic3D(1000,0.0f);
90
    Dynamic3D dRight= new Dynamic3D(1000,0.0f);
91

  
92
    dLeft.add( new Static3D(  0,  0, 0) );
93
    dLeft.add( new Static3D(-20, 20, 0) );
94

  
95
    dRight.add( new Static3D(  0,  0, 0) );
96
    dRight.add( new Static3D( 20, 10, 0) );
97

  
98
    mEffects = new DistortedEffects();
99
    mEffects.apply( new VertexEffectDistort(dLeft , pLeft , rLeft ) );
100
    mEffects.apply( new VertexEffectDistort(dRight, pRight, rRight) );
101

  
102
    mMove = new Static3D(0,0,0);
103
    mScale= new Static3D(1,1,1);
104
    mEffects.apply(new MatrixEffectMove(mMove));
105
    mEffects.apply(new MatrixEffectScale(mScale));
106

  
107
    mScreen = new DistortedScreen();
108
    }
109

  
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

  
112
  static void setResourcesCreated()
113
    {
114
    resourcesCreated = false;
115
    }
116

  
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

  
119
  private static void checkGlError(String op)
120
    {
121
    int error = GLES31.glGetError();
122

  
123
    if (error != GLES31.GL_NO_ERROR)
124
      {
125
      String msg = op + ": glError 0x" + Integer.toHexString(error);
126
      Log.e(TAG, msg);
127
//    throw new RuntimeException(msg);
128
      }
129
    }
130

  
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

  
133
  @Override
134
  public void run()
135
    {
136
    Looper.prepare();
137
    mHandler = new RenderHandler(this);
138
    eglCore = new EglCore(null, EglCore.FLAG_RECORDABLE | EglCore.FLAG_TRY_GLES3);
139

  
140
    synchronized (mStartLock)
141
      {
142
      mReady = true;
143
      mStartLock.notify();    // signal waitUntilReady()
144
      }
145

  
146
    Looper.loop();
147
    Log.d(TAG, "looper quit");
148

  
149
    checkGlError("releaseGl start");
150

  
151
    if (eglSurface != null)
152
      {
153
      eglCore.releaseSurface(eglSurface);
154
      eglSurface = EGL14.EGL_NO_SURFACE;
155
      }
156

  
157
    checkGlError("releaseGl done");
158

  
159
    eglCore.makeNothingCurrent();
160
    eglCore.release();
161

  
162
    synchronized (mStartLock)
163
      {
164
      mReady = false;
165
      }
166
    }
167

  
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

  
170
  void waitUntilReady()
171
    {
172
    synchronized (mStartLock)
173
      {
174
      while (!mReady)
175
        {
176
        try
177
          {
178
          mStartLock.wait();
179
          }
180
        catch (InterruptedException ie) {  }
181
        }
182
      }
183
    }
184

  
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

  
187
  void shutdown()
188
    {
189
    Log.d(TAG, "shutdown");
190
    Looper.myLooper().quit();
191
    }
192

  
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

  
195
  RenderHandler getHandler()
196
    {
197
    return mHandler;
198
    }
199

  
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

  
202
  void surfaceCreated()
203
    {
204
    Log.d(TAG, "surfaceCreated");
205

  
206
    Surface surface = mSurfaceHolder.getSurface();
207

  
208
    eglSurface = eglCore.createWindowSurface(surface);
209
    eglCore.makeCurrent(eglSurface);
210

  
211
    createResources();
212
    }
213

  
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

  
216
  void surfaceChanged(int width, int height)
217
    {
218
    Log.d(TAG, "surfaceChanged " + width + "x" + height);
219

  
220
    if( (float)bmpHeight/bmpWidth > (float)height/width )
221
      {
222
      int w = (height*bmpWidth)/bmpHeight;
223
      float factor = (float)height/bmpHeight;
224

  
225
      mMove.set((width-w)/2,0,0);
226
      mScale.set( factor,factor,factor );
227
      }
228
    else
229
      {
230
      int h = (width*bmpHeight)/bmpWidth;
231
      float factor = (float)width/bmpWidth;
232

  
233
      mMove.set(0,(height-h)/2,0);
234
      mScale.set( factor,factor,factor );
235
      }
236

  
237
    mScreen.resize(width, height);
238
    }
239

  
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

  
242
  private void createResources()
243
    {
244
    resourcesCreated = true;
245

  
246
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.monalisa);
247
    Bitmap bmp;
248

  
249
    try
250
      {
251
      bmp = BitmapFactory.decodeStream(is);
252
      }
253
    finally
254
      {
255
      try
256
        {
257
        is.close();
258
        }
259
      catch(IOException io) {}
260
      }
261

  
262
    bmpHeight = bmp.getHeight();
263
    bmpWidth  = bmp.getWidth();
264

  
265
    if( mTexture==null ) mTexture = new DistortedTexture(bmpWidth,bmpHeight);
266
    mTexture.setTexture(bmp);
267

  
268
    if( mMesh==null ) mMesh = new MeshFlat(9,9*bmpHeight/bmpWidth);
269

  
270
    mScreen.detachAll();
271
    mScreen.attach(mTexture,mEffects,mMesh);
272

  
273
    VertexEffectDistort.enable();
274

  
275
    try
276
      {
277
      Distorted.onCreate(mView.getContext());
278
      }
279
    catch(Exception ex)
280
      {
281
      Log.e("PlainMonaLisa", ex.getMessage() );
282
      }
283
    }
284

  
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

  
287
  void doFrame(long frameTimeNs)
288
    {
289
    // We can still get here after onPaused - ignore such calls.
290
    if( PlainMonaLisaSurfaceView.isPaused() )
291
      {
292
      android.util.Log.e("Thread", "Got here after onPaused- ignoring frame draw call!!");
293
      return;
294
      }
295

  
296
    // This will happen if we just briefly went into the background (press 'POWER')
297
    // Then surfaceCreated/changed is not called
298
    if( !resourcesCreated )
299
      {
300
      Log.e("Thread", "resources not created!!");
301
      createResources();
302
      }
303

  
304
    eglCore.makeCurrent(eglSurface);
305
    mScreen.render( frameTimeNs/1000000 );  // 1 nanosecond = 1 millisecond / 10^-6
306
    eglCore.swapBuffers(eglSurface);
307
    }
308

  
309
  }
src/main/java/org/distorted/examples/save/SaveRenderer.java
30 30

  
31 31
import org.distorted.examples.R;
32 32

  
33
import org.distorted.library.effect.MatrixEffectMove;
34 33
import org.distorted.library.effect.MatrixEffectScale;
35 34
import org.distorted.library.effect.VertexEffectSink;
36 35
import org.distorted.library.main.Distorted;
......
61 60
  private MeshFlat mMesh;
62 61
  private DistortedScreen mScreen;
63 62
  private Static1D s0;
64
  private Static3D mScaleFactor, mScaleMain, mMove;
63
  private Static3D mScaleFactor, mScaleMain;
65 64

  
66 65
  private float mScale;
67 66
  private int bmpHeight, bmpWidth;
......
90 89

  
91 90
    mScale = 1.0f;
92 91
    mScaleFactor = new Static3D(mScale,mScale,1.0f);
93
    mMove = new Static3D(0,0,0);
94 92
    mScaleMain = new Static3D(1,1,1);
95 93

  
96 94
    mEffects = new DistortedEffects();
97 95
    mEffects.apply( new VertexEffectSink(diSink, pLeft , sinkRegion) );
98 96
    mEffects.apply( new VertexEffectSink(diSink, pRight, sinkRegion) );
99
    mEffects.apply( new MatrixEffectMove(mMove));
100 97
    mEffects.apply( new MatrixEffectScale(mScaleMain));
101 98
    mEffects.apply( new MatrixEffectScale(mScaleFactor));
102 99

  
......
155 152
    {
156 153
    if( isSaving )  // render to an offscreen buffer and read pixels
157 154
      {
158
      mMove.set(0,0,0);
159 155
      mScaleMain.set(1,1,1);
160 156
      mOffscreen.render(System.currentTimeMillis());
161 157
      applyMatrixEffects(scrWidth,scrHeight);
......
194 190

  
195 191
  private void applyMatrixEffects(int width, int height)
196 192
    {
197
    if( (float)bmpHeight/bmpWidth > (float)height/width )
198
      {
199
      int w = (height*bmpWidth)/bmpHeight;
200
      float factor = (float)height/bmpHeight;
201

  
202
      mMove.set((width-w)/2,0,0);
203
      mScaleMain.set(factor,factor,factor);
204
      }
205
    else
206
      {
207
      int h = (width*bmpHeight)/bmpWidth;
208
      float factor = (float)width/bmpWidth;
209

  
210
      mMove.set(0,(height-h)/2,0);
211
      mScaleMain.set(factor,factor,factor);
212
      }
193
    float horiRatio = (float)width / mTexture.getWidth();
194
    float vertRatio = (float)height/ mTexture.getHeight();
195
    float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
196
    mScaleMain.set(factor,factor,factor);
213 197
    }
214 198

  
215 199
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/examples/surfaceview/EglCore.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

  
20
package org.distorted.examples.surfaceview;
21

  
22
import android.graphics.SurfaceTexture;
23
import android.opengl.EGL14;
24
import android.opengl.EGLConfig;
25
import android.opengl.EGLContext;
26
import android.opengl.EGLDisplay;
27
import android.opengl.EGLExt;
28
import android.opengl.EGLSurface;
29
import android.os.Build;
30
import android.util.Log;
31
import android.view.Surface;
32

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

  
35
public final class EglCore
36
  {
37
  private static final String TAG = "EglCore";
38

  
39
  public static final int FLAG_RECORDABLE = 0x01;           // Surface must be recordable.  This discourages EGL from using a
40
                                                            // pixel format that cannot be converted efficiently to something 
41
                                                            // usable by the video encoder.
42
  public static final int FLAG_TRY_GLES3 = 0x02;            // Ask for GLES3, fall back to GLES2 if not available.
43

  
44
  private static final int EGL_RECORDABLE_ANDROID = 0x3142; // Android-specific extension
45

  
46
  private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
47
  private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
48
  private EGLConfig mEGLConfig = null;
49
  private int mGlVersion = -1;
50

  
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

  
53
  public EglCore()
54
    {
55
    this(null, 0);
56
    }
57

  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

  
60
  public EglCore(EGLContext sharedContext, int flags)
61
    {
62
    if (mEGLDisplay != EGL14.EGL_NO_DISPLAY)
63
      {
64
      throw new RuntimeException("EGL already set up");
65
      }
66

  
67
    if (sharedContext == null)
68
      {
69
      sharedContext = EGL14.EGL_NO_CONTEXT;
70
      }
71

  
72
    mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
73

  
74
    if (mEGLDisplay == EGL14.EGL_NO_DISPLAY)
75
      {
76
      throw new RuntimeException("unable to get EGL14 display");
77
      }
78

  
79
    int[] version = new int[2];
80

  
81
    if (!EGL14.eglInitialize(mEGLDisplay, version, 0, version, 1))
82
      {
83
      mEGLDisplay = null;
84
      throw new RuntimeException("unable to initialize EGL14");
85
      }
86

  
87
    // Try to get a GLES3 context, if requested.
88
    if ((flags & FLAG_TRY_GLES3) != 0)
89
      {
90
      //Log.d(TAG, "Trying GLES 3");
91
      EGLConfig config = getConfig(flags, 3);
92

  
93
      if (config != null)
94
        {
95
        int[] attrib3_list =  { EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE };
96
        EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib3_list, 0);
97

  
98
        if (EGL14.eglGetError() == EGL14.EGL_SUCCESS)
99
          {
100
          //Log.d(TAG, "Got GLES 3 config");
101
          mEGLConfig = config;
102
          mEGLContext = context;
103
          mGlVersion = 3;
104
          }
105
        }
106
      }
107

  
108
    if (mEGLContext == EGL14.EGL_NO_CONTEXT)
109
      {  // GLES 2 only, or GLES 3 attempt failed
110
         //Log.d(TAG, "Trying GLES 2");
111
      EGLConfig config = getConfig(flags, 2);
112

  
113
      if (config == null)
114
        {
115
        throw new RuntimeException("Unable to find a suitable EGLConfig");
116
        }
117
      int[] attrib2_list = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE };
118
      EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib2_list, 0);
119
      checkEglError("eglCreateContext");
120
      mEGLConfig = config;
121
      mEGLContext = context;
122
      mGlVersion = 2;
123
      }
124

  
125
    // Confirm with query.
126
    int[] values = new int[1];
127
    EGL14.eglQueryContext(mEGLDisplay, mEGLContext, EGL14.EGL_CONTEXT_CLIENT_VERSION, values, 0);
128

  
129
    Log.d(TAG, "EGLContext created, client version " + values[0]);
130
    }
131

  
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

  
134
  private EGLConfig getConfig(int flags, int version)
135
    {
136
    int renderableType = EGL14.EGL_OPENGL_ES2_BIT;
137

  
138
    if (version >= 3)
139
      {
140
      renderableType |= EGLExt.EGL_OPENGL_ES3_BIT_KHR;
141
      }
142

  
143
    // The actual surface is generally RGBA or RGBX, so situationally omitting alpha
144
    // doesn't really help.  It can also lead to a huge performance hit on glReadPixels()
145
    // when reading into a GL_RGBA buffer.
146

  
147
    int [] normalAttribList =
148
                {
149
                EGL14.EGL_RED_SIZE, 8,
150
                EGL14.EGL_GREEN_SIZE, 8,
151
                EGL14.EGL_BLUE_SIZE, 8,
152
                EGL14.EGL_ALPHA_SIZE, 8,
153
                EGL14.EGL_RENDERABLE_TYPE, renderableType,
154
                EGL14.EGL_NONE, 0,      // placeholder for recordable [@-3]
155
                EGL14.EGL_NONE
156
                };
157

  
158
    if ((flags & FLAG_RECORDABLE) != 0)
159
      {
160
      normalAttribList[normalAttribList.length - 3] = EGL_RECORDABLE_ANDROID;
161
      normalAttribList[normalAttribList.length - 2] = 1;
162
      }
163

  
164
    int [] emulatorAttribList =
165
                {
166
                EGL14.EGL_RED_SIZE, 8,
167
                EGL14.EGL_GREEN_SIZE, 8,
168
                EGL14.EGL_BLUE_SIZE, 8,
169
                EGL14.EGL_ALPHA_SIZE, 8,
170
                EGL14.EGL_DEPTH_SIZE, 16,
171
                EGL14.EGL_STENCIL_SIZE, 0,
172
                EGL14.EGL_NONE
173
                };
174

  
175
    boolean isEmulator=
176
               Build.FINGERPRINT.startsWith("generic")
177
            || Build.FINGERPRINT.startsWith("unknown")
178
            || Build.MODEL.contains("google_sdk")
179
            || Build.MODEL.contains("Emulator")
180
            || Build.MODEL.contains("Android SDK built for x86")
181
            || Build.MANUFACTURER.contains("Genymotion")
182
            || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
183
            || "google_sdk".equals(Build.PRODUCT);
184

  
185
    int [] attribList = (isEmulator ? emulatorAttribList:normalAttribList);
186

  
187
    if( isEmulator )
188
      {
189
      Log.w(TAG, "Using emulator config!" );
190
      }
191

  
192
    EGLConfig[] configs = new EGLConfig[1];
193
    int[] numConfigs = new int[1];
194

  
195
    if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0))
196
      {
197
      Log.w(TAG, "unable to find RGB8888 / " + version + " EGLConfig");
198
      return null;
199
      }
200

  
201
    return configs[0];
202
    }
203

  
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

  
206
  public void release()
207
    {
208
    if (mEGLDisplay != EGL14.EGL_NO_DISPLAY)
209
      {
210
      EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
211
      EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
212
      EGL14.eglReleaseThread();
213
      EGL14.eglTerminate(mEGLDisplay);
214
      }
215

  
216
    mEGLDisplay = EGL14.EGL_NO_DISPLAY;
217
    mEGLContext = EGL14.EGL_NO_CONTEXT;
218
    mEGLConfig = null;
219
    }
220

  
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222
  @Override
223
  protected void finalize() throws Throwable
224
    {
225
    try
226
      {
227
      if (mEGLDisplay != EGL14.EGL_NO_DISPLAY)
228
        {
229
        // We're limited here -- finalizers don't run on the thread that holds
230
        // the EGL state, so if a surface or context is still current on another
231
        // thread we can't fully release it here.  Exceptions thrown from here
232
        // are quietly discarded.  Complain in the log file.
233
        Log.w(TAG, "WARNING: EglCore was not explicitly released -- state may be leaked");
234
        release();
235
        }
236
      }
237
    finally
238
      {
239
      super.finalize();
240
      }
241
    }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

  
245
  public void releaseSurface(EGLSurface eglSurface)
246
    {
247
    EGL14.eglDestroySurface(mEGLDisplay, eglSurface);
248
    }
249

  
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

  
252
  public EGLSurface createWindowSurface(Object surface)
253
    {
254
    if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture))
255
      {
256
      throw new RuntimeException("invalid surface: " + surface);
257
      }
258

  
259
    int[] surfaceAttribs = { EGL14.EGL_NONE };
260
    EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0);
261
    checkEglError("eglCreateWindowSurface");
262

  
263
    if (eglSurface == null)
264
      {
265
      throw new RuntimeException("surface was null");
266
      }
267
    return eglSurface;
268
    }
269

  
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

  
272
  public void makeCurrent(EGLSurface eglSurface)
273
    {
274
    if (mEGLDisplay == EGL14.EGL_NO_DISPLAY)
275
      {
276
      Log.d(TAG, "NOTE: makeCurrent w/o display");
277
      }
278
    if (!EGL14.eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext))
279
      {
280
      throw new RuntimeException("eglMakeCurrent failed");
281
      }
282
    }
283

  
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

  
286
  public void makeNothingCurrent()
287
    {
288
    if (!EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT))
289
      {
290
      throw new RuntimeException("eglMakeCurrent failed");
291
      }
292
    }
293

  
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

  
296
  public int getGlVersion()
297
    {
298
    return mGlVersion;
299
    }
300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
  public boolean swapBuffers(EGLSurface eglSurface)
304
    {
305
    return EGL14.eglSwapBuffers(mEGLDisplay, eglSurface);
306
    }
307

  
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309

  
310
  private void checkEglError(String msg)
311
    {
312
    int error;
313

  
314
    if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS)
315
      {
316
      throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error));
317
      }
318
    }
319
  }
src/main/java/org/distorted/examples/surfaceview/RenderHandler.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff