Project

General

Profile

« Previous | Next » 

Revision 635a3fdb

Added by Leszek Koltunski 3 days ago

Rename .java to .kt

View differences:

src/main/java/org/distorted/library/main/InternalBuffer.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2018 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
import android.opengl.GLES30;
24

  
25
import java.nio.Buffer;
26
import java.nio.ByteBuffer;
27
import java.nio.ByteOrder;
28
import java.nio.FloatBuffer;
29
import java.nio.IntBuffer;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
/**
33
 * Implements OpenGL buffer object such as GL_ARRAY_BUFFER or GL_TRANSFORM_FEEDBACK_BUFFER.
34
 * Main point: deal with Android lifecycle and recreate the buffer on loss of OpenGL context.
35
 * <p>
36
 * Not part of public API, do not document (public only because has to be used in Meshes)
37
 *
38
 * @y.exclude
39
 */
40
public class InternalBuffer extends InternalObject
41
  {
42
  private static final int DONE     = 0;
43
  private static final int RECREATE = 1;
44
  private static final int UPDATE   = 2;
45

  
46
  private int mStatus, mSize;
47
  private final int[] mIndex;
48
  private final int mTarget, mUsage;
49
  private Buffer mBuffer;
50

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

  
53
  public InternalBuffer()
54
    {
55
    super(InternalObject.TYPE_USER, InternalObject.STORAGE_PRIVATE );
56

  
57
    mIndex  = new int[1];
58
    mTarget = GLES30.GL_UNIFORM_BUFFER;
59
    mUsage  = GLES30.GL_STATIC_DRAW;
60
    mBuffer = null;
61
    mSize   = 0;
62
    mStatus = RECREATE;
63
    }
64

  
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

  
67
  public InternalBuffer(int target, int usage)
68
    {
69
    super(InternalObject.TYPE_USER, InternalObject.STORAGE_PRIVATE );
70

  
71
    mIndex  = new int[1];
72
    mTarget = target;
73
    mUsage  = usage;
74
    mBuffer = null;
75
    mSize   = 0;
76
    mStatus = RECREATE;
77
    }
78

  
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80
// must be called from a thread holding OpenGL Context.
81

  
82
  public int createImmediatelyFloat(int size, float[] buffer)
83
    {
84
    if( (mStatus & RECREATE) != 0 )
85
      {
86
      mSize= size;
87

  
88
      if( buffer!=null )
89
        {
90
        FloatBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asFloatBuffer();
91
        buf.put(buffer).position(0);
92
        mBuffer = buf;
93
        }
94
      else
95
        {
96
        mBuffer = null;
97
        }
98

  
99
      GLES30.glGenBuffers( 1, mIndex, 0);
100
      GLES30.glBindBuffer( mTarget, mIndex[0]);
101
      GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
102
      GLES30.glBindBuffer( mTarget, 0);
103

  
104
      markWasCreatedImmediately();
105
      }
106
    else if( (mStatus & UPDATE) != 0 )
107
      {
108
      updateFloat(buffer);
109
      }
110

  
111
    mStatus = DONE;
112

  
113
    return mIndex[0];
114
    }
115

  
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
// must be called from a thread holding OpenGL Context.
118

  
119
  public int createImmediatelyInt(int size, int[] buffer)
120
    {
121
    if( (mStatus & RECREATE) != 0 )
122
      {
123
      mSize= size;
124

  
125
      if( buffer!=null )
126
        {
127
        IntBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asIntBuffer();
128
        buf.put(buffer).position(0);
129
        mBuffer = buf;
130
        }
131
      else
132
        {
133
        mBuffer = null;
134
        }
135

  
136
      GLES30.glGenBuffers( 1, mIndex, 0);
137
      GLES30.glBindBuffer( mTarget,  mIndex[0]);
138
      GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
139
      GLES30.glBindBuffer( mTarget,  0);
140

  
141
      markWasCreatedImmediately();
142
      }
143
    else if( (mStatus & UPDATE) != 0  )
144
      {
145
      updateInt(buffer);
146
      }
147

  
148
    mStatus = DONE;
149

  
150
    return mIndex[0];
151
    }
152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
// buffer non-null!!
155

  
156
  public void updateFloat(float[] buffer)
157
    {
158
    ((FloatBuffer)mBuffer).put(buffer).position(0);
159

  
160
    GLES30.glBindBuffer( mTarget, mIndex[0]);
161
    GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
162
    GLES30.glBindBuffer( mTarget, 0);
163

  
164
    mStatus &= (~UPDATE);
165
    }
166

  
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
// buffer non-null!!
169

  
170
  public void updateInt(int[] buffer)
171
    {
172
    ((IntBuffer)mBuffer).put(buffer).position(0);
173

  
174
    GLES30.glBindBuffer( mTarget, mIndex[0]);
175
    GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
176
    GLES30.glBindBuffer( mTarget, 0);
177

  
178
    mStatus &= (~UPDATE);
179
    }
180

  
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

  
183
  public void invalidate()
184
    {
185
    mStatus |= UPDATE;
186
    }
187

  
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
// Intentionally empty, no need to do anything here since it will be done in createImmediatelyXXX().
190
// In fact, recreating a Mesh's mVBO1 here - rather than in createImmediatelyFloat - was the reason
191
// of the 'disappearing cube after the mesh has changed from nice to simple' bug. I don't quite
192
// understand why TBH.
193

  
194
  void create()
195
    {
196

  
197
    }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
// must be called from a thread holding OpenGL Context
201

  
202
  void delete()
203
    {
204
    GLES30.glDeleteBuffers(1, mIndex, 0);
205
    mStatus |= RECREATE;
206
    removeFromDone();
207
    }
208

  
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

  
211
  public void recreate()
212
    {
213
    mStatus |= RECREATE;
214
    }
215

  
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217
// debugging only
218

  
219
  String printDetails()
220
    {
221
    return getClass().getSimpleName();
222
    }
223
  }
src/main/java/org/distorted/library/main/InternalBuffer.kt
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2018 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
import android.opengl.GLES30;
24

  
25
import java.nio.Buffer;
26
import java.nio.ByteBuffer;
27
import java.nio.ByteOrder;
28
import java.nio.FloatBuffer;
29
import java.nio.IntBuffer;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
/**
33
 * Implements OpenGL buffer object such as GL_ARRAY_BUFFER or GL_TRANSFORM_FEEDBACK_BUFFER.
34
 * Main point: deal with Android lifecycle and recreate the buffer on loss of OpenGL context.
35
 * <p>
36
 * Not part of public API, do not document (public only because has to be used in Meshes)
37
 *
38
 * @y.exclude
39
 */
40
public class InternalBuffer extends InternalObject
41
  {
42
  private static final int DONE     = 0;
43
  private static final int RECREATE = 1;
44
  private static final int UPDATE   = 2;
45

  
46
  private int mStatus, mSize;
47
  private final int[] mIndex;
48
  private final int mTarget, mUsage;
49
  private Buffer mBuffer;
50

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

  
53
  public InternalBuffer()
54
    {
55
    super(InternalObject.TYPE_USER, InternalObject.STORAGE_PRIVATE );
56

  
57
    mIndex  = new int[1];
58
    mTarget = GLES30.GL_UNIFORM_BUFFER;
59
    mUsage  = GLES30.GL_STATIC_DRAW;
60
    mBuffer = null;
61
    mSize   = 0;
62
    mStatus = RECREATE;
63
    }
64

  
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

  
67
  public InternalBuffer(int target, int usage)
68
    {
69
    super(InternalObject.TYPE_USER, InternalObject.STORAGE_PRIVATE );
70

  
71
    mIndex  = new int[1];
72
    mTarget = target;
73
    mUsage  = usage;
74
    mBuffer = null;
75
    mSize   = 0;
76
    mStatus = RECREATE;
77
    }
78

  
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80
// must be called from a thread holding OpenGL Context.
81

  
82
  public int createImmediatelyFloat(int size, float[] buffer)
83
    {
84
    if( (mStatus & RECREATE) != 0 )
85
      {
86
      mSize= size;
87

  
88
      if( buffer!=null )
89
        {
90
        FloatBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asFloatBuffer();
91
        buf.put(buffer).position(0);
92
        mBuffer = buf;
93
        }
94
      else
95
        {
96
        mBuffer = null;
97
        }
98

  
99
      GLES30.glGenBuffers( 1, mIndex, 0);
100
      GLES30.glBindBuffer( mTarget, mIndex[0]);
101
      GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
102
      GLES30.glBindBuffer( mTarget, 0);
103

  
104
      markWasCreatedImmediately();
105
      }
106
    else if( (mStatus & UPDATE) != 0 )
107
      {
108
      updateFloat(buffer);
109
      }
110

  
111
    mStatus = DONE;
112

  
113
    return mIndex[0];
114
    }
115

  
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
// must be called from a thread holding OpenGL Context.
118

  
119
  public int createImmediatelyInt(int size, int[] buffer)
120
    {
121
    if( (mStatus & RECREATE) != 0 )
122
      {
123
      mSize= size;
124

  
125
      if( buffer!=null )
126
        {
127
        IntBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asIntBuffer();
128
        buf.put(buffer).position(0);
129
        mBuffer = buf;
130
        }
131
      else
132
        {
133
        mBuffer = null;
134
        }
135

  
136
      GLES30.glGenBuffers( 1, mIndex, 0);
137
      GLES30.glBindBuffer( mTarget,  mIndex[0]);
138
      GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
139
      GLES30.glBindBuffer( mTarget,  0);
140

  
141
      markWasCreatedImmediately();
142
      }
143
    else if( (mStatus & UPDATE) != 0  )
144
      {
145
      updateInt(buffer);
146
      }
147

  
148
    mStatus = DONE;
149

  
150
    return mIndex[0];
151
    }
152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
// buffer non-null!!
155

  
156
  public void updateFloat(float[] buffer)
157
    {
158
    ((FloatBuffer)mBuffer).put(buffer).position(0);
159

  
160
    GLES30.glBindBuffer( mTarget, mIndex[0]);
161
    GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
162
    GLES30.glBindBuffer( mTarget, 0);
163

  
164
    mStatus &= (~UPDATE);
165
    }
166

  
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
// buffer non-null!!
169

  
170
  public void updateInt(int[] buffer)
171
    {
172
    ((IntBuffer)mBuffer).put(buffer).position(0);
173

  
174
    GLES30.glBindBuffer( mTarget, mIndex[0]);
175
    GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
176
    GLES30.glBindBuffer( mTarget, 0);
177

  
178
    mStatus &= (~UPDATE);
179
    }
180

  
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

  
183
  public void invalidate()
184
    {
185
    mStatus |= UPDATE;
186
    }
187

  
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
// Intentionally empty, no need to do anything here since it will be done in createImmediatelyXXX().
190
// In fact, recreating a Mesh's mVBO1 here - rather than in createImmediatelyFloat - was the reason
191
// of the 'disappearing cube after the mesh has changed from nice to simple' bug. I don't quite
192
// understand why TBH.
193

  
194
  void create()
195
    {
196

  
197
    }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
// must be called from a thread holding OpenGL Context
201

  
202
  void delete()
203
    {
204
    GLES30.glDeleteBuffers(1, mIndex, 0);
205
    mStatus |= RECREATE;
206
    removeFromDone();
207
    }
208

  
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

  
211
  public void recreate()
212
    {
213
    mStatus |= RECREATE;
214
    }
215

  
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217
// debugging only
218

  
219
  String printDetails()
220
    {
221
    return getClass().getSimpleName();
222
    }
223
  }
src/main/java/org/distorted/library/main/InternalChildrenList.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21

  
22
package org.distorted.library.main;
23

  
24
import org.distorted.library.mesh.MeshBase;
25

  
26
import java.util.ArrayList;
27

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

  
30
class InternalChildrenList implements InternalMaster.Slave
31
  {
32
  private static final int ATTACH = 0;
33
  private static final int DETACH = 1;
34
  private static final int DETALL = 2;
35
  private static final int SORT   = 3;
36

  
37
  private static class Job
38
    {
39
    int type;
40
    DistortedNode node;
41

  
42
    Job(int t, DistortedNode n)
43
      {
44
      type = t;
45
      node = n;
46
      }
47
    }
48

  
49
  private final ArrayList<Job> mJobs;
50
  private final InternalChildrenList.Parent mParent;
51
  private ArrayList<DistortedNode> mChildren;
52
  private int mNumChildren;
53

  
54
  public interface Parent
55
    {
56
    void adjustIsomorphism();
57
    }
58

  
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

  
61
  InternalChildrenList(InternalChildrenList.Parent parent)
62
    {
63
    mParent = parent;
64
    mJobs = new ArrayList<>();
65
    mChildren = null;
66
    mNumChildren = 0;
67
    }
68

  
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

  
71
  int getNumChildren()
72
    {
73
    return mNumChildren;
74
    }
75

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

  
78
  DistortedNode getChild(int index)
79
    {
80
    return mChildren.get(index);
81
    }
82

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

  
85
  void rearrangeByBuckets(int index,long bucket)
86
    {
87
    DistortedNode child = mChildren.remove(index);
88
    int i;
89

  
90
    for(i=0; i<index; i++)
91
      {
92
      if( mChildren.get(i).getBucket() > bucket ) break;
93
      }
94

  
95
    mChildren.add(i,child);
96
    }
97

  
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// Can make this logarithmic but the typical number of children is very small anyway.
100
//
101
// We want to keep same buckets next to each other, while avoiding changes in order of the children
102
// (if possible!)
103
// 2022/10/25: removed keeping bucket 0 (i.e. non-postprocessed children) always in the front -
104
// we don't need it (given the fixes to renderChildren() )
105

  
106
  private void addSortingByBuckets(DistortedNode newChild)
107
    {
108
    int i;
109
    long bucket = newChild.getBucket();
110
    boolean thisSame,lastSame = false;
111

  
112
    for(i=0; i<mNumChildren; i++)
113
      {
114
      thisSame= (mChildren.get(i).getBucket()==bucket);
115
      if( lastSame && !thisSame ) break;
116
      lastSame = thisSame;
117
      }
118

  
119
    mChildren.add(i,newChild);
120
    mNumChildren++;
121
    }
122

  
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

  
125
  void attach(DistortedNode node)
126
    {
127
    node.resetLastTime();
128
    mJobs.add(new Job(ATTACH,node));
129
    InternalMaster.newSlave(this);
130
    }
131

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

  
134
  DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
135
    {
136
    DistortedNode node = new DistortedNode(surface,effects,mesh);
137
    mJobs.add(new Job(ATTACH,node));
138
    InternalMaster.newSlave(this);
139
    return node;
140
    }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

  
144
  void detach(DistortedNode node)
145
    {
146
    mJobs.add(new Job(DETACH,node));
147
    InternalMaster.newSlave(this);
148
    }
149

  
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

  
152
  void detach(DistortedEffects effects)
153
    {
154
    long id = effects.getID();
155
    DistortedNode node;
156
    boolean detached = false;
157

  
158
    for(int i=0; i<mNumChildren; i++)
159
      {
160
      node = mChildren.get(i);
161

  
162
      if( node.getEffects().getID()==id )
163
        {
164
        detached = true;
165
        mJobs.add(new Job(DETACH,node));
166
        InternalMaster.newSlave(this);
167
        break;
168
        }
169
      }
170

  
171
    if( !detached )
172
      {
173
      // if we failed to detach any, it still might be the case that
174
      // there's an ATTACH job that we need to cancel.
175
      int num = mJobs.size();
176
      Job job;
177

  
178
      for(int i=0; i<num; i++)
179
        {
180
        job = mJobs.get(i);
181

  
182
        if( job.type==ATTACH && job.node.getEffects()==effects )
183
          {
184
          mJobs.remove(i);
185
          break;
186
          }
187
        }
188
      }
189
    }
190

  
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

  
193
  void detachAll()
194
    {
195
    mJobs.add(new Job(DETALL,null));
196
    InternalMaster.newSlave(this);
197
    }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
/**
201
 * This is not really part of the public API. Has to be public only because it is a part of the
202
 * DistortedSlave interface, which should really be a class that we extend here instead but
203
 * Java has no multiple inheritance.
204
 *
205
 * @y.exclude
206
 */
207
  public void doWork()
208
    {
209
    int num = mJobs.size();
210

  
211
    if( num>0 )
212
      {
213
      Job job;
214
      int numChanges=0;
215

  
216
      for(int i=0; i<num; i++)
217
        {
218
        job = mJobs.remove(0);
219

  
220
        switch(job.type)
221
          {
222
          case ATTACH: numChanges++;
223
                       if( mChildren==null ) mChildren = new ArrayList<>(2);
224
                       job.node.setParent(mParent);
225
                       addSortingByBuckets(job.node);
226
                       break;
227
          case DETACH: numChanges++;
228
                       if( mNumChildren>0 && mChildren.remove(job.node) )
229
                         {
230
                         job.node.setParent(null);
231
                         mNumChildren--;
232
                         }
233
                       break;
234
          case DETALL: numChanges++;
235
                       if( mNumChildren>0 )
236
                         {
237
                         DistortedNode tmp;
238

  
239
                         for(int j=mNumChildren-1; j>=0; j--)
240
                           {
241
                           tmp = mChildren.remove(j);
242
                           tmp.setParent(null);
243
                           }
244

  
245
                         mNumChildren = 0;
246
                         }
247
                       break;
248
          case SORT  : mChildren.remove(job.node);
249
                       addSortingByBuckets(job.node);
250
                       break;
251
          }
252
        }
253
      if( numChanges>0 ) mParent.adjustIsomorphism();
254
      }
255
    }
256
  }
257

  
src/main/java/org/distorted/library/main/InternalChildrenList.kt
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21

  
22
package org.distorted.library.main;
23

  
24
import org.distorted.library.mesh.MeshBase;
25

  
26
import java.util.ArrayList;
27

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

  
30
class InternalChildrenList implements InternalMaster.Slave
31
  {
32
  private static final int ATTACH = 0;
33
  private static final int DETACH = 1;
34
  private static final int DETALL = 2;
35
  private static final int SORT   = 3;
36

  
37
  private static class Job
38
    {
39
    int type;
40
    DistortedNode node;
41

  
42
    Job(int t, DistortedNode n)
43
      {
44
      type = t;
45
      node = n;
46
      }
47
    }
48

  
49
  private final ArrayList<Job> mJobs;
50
  private final InternalChildrenList.Parent mParent;
51
  private ArrayList<DistortedNode> mChildren;
52
  private int mNumChildren;
53

  
54
  public interface Parent
55
    {
56
    void adjustIsomorphism();
57
    }
58

  
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

  
61
  InternalChildrenList(InternalChildrenList.Parent parent)
62
    {
63
    mParent = parent;
64
    mJobs = new ArrayList<>();
65
    mChildren = null;
66
    mNumChildren = 0;
67
    }
68

  
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

  
71
  int getNumChildren()
72
    {
73
    return mNumChildren;
74
    }
75

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

  
78
  DistortedNode getChild(int index)
79
    {
80
    return mChildren.get(index);
81
    }
82

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

  
85
  void rearrangeByBuckets(int index,long bucket)
86
    {
87
    DistortedNode child = mChildren.remove(index);
88
    int i;
89

  
90
    for(i=0; i<index; i++)
91
      {
92
      if( mChildren.get(i).getBucket() > bucket ) break;
93
      }
94

  
95
    mChildren.add(i,child);
96
    }
97

  
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// Can make this logarithmic but the typical number of children is very small anyway.
100
//
101
// We want to keep same buckets next to each other, while avoiding changes in order of the children
102
// (if possible!)
103
// 2022/10/25: removed keeping bucket 0 (i.e. non-postprocessed children) always in the front -
104
// we don't need it (given the fixes to renderChildren() )
105

  
106
  private void addSortingByBuckets(DistortedNode newChild)
107
    {
108
    int i;
109
    long bucket = newChild.getBucket();
110
    boolean thisSame,lastSame = false;
111

  
112
    for(i=0; i<mNumChildren; i++)
113
      {
114
      thisSame= (mChildren.get(i).getBucket()==bucket);
115
      if( lastSame && !thisSame ) break;
116
      lastSame = thisSame;
117
      }
118

  
119
    mChildren.add(i,newChild);
120
    mNumChildren++;
121
    }
122

  
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

  
125
  void attach(DistortedNode node)
126
    {
127
    node.resetLastTime();
128
    mJobs.add(new Job(ATTACH,node));
129
    InternalMaster.newSlave(this);
130
    }
131

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

  
134
  DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
135
    {
136
    DistortedNode node = new DistortedNode(surface,effects,mesh);
137
    mJobs.add(new Job(ATTACH,node));
138
    InternalMaster.newSlave(this);
139
    return node;
140
    }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

  
144
  void detach(DistortedNode node)
145
    {
146
    mJobs.add(new Job(DETACH,node));
147
    InternalMaster.newSlave(this);
148
    }
149

  
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

  
152
  void detach(DistortedEffects effects)
153
    {
154
    long id = effects.getID();
155
    DistortedNode node;
156
    boolean detached = false;
157

  
158
    for(int i=0; i<mNumChildren; i++)
159
      {
160
      node = mChildren.get(i);
161

  
162
      if( node.getEffects().getID()==id )
163
        {
164
        detached = true;
165
        mJobs.add(new Job(DETACH,node));
166
        InternalMaster.newSlave(this);
167
        break;
168
        }
169
      }
170

  
171
    if( !detached )
172
      {
173
      // if we failed to detach any, it still might be the case that
174
      // there's an ATTACH job that we need to cancel.
175
      int num = mJobs.size();
176
      Job job;
177

  
178
      for(int i=0; i<num; i++)
179
        {
180
        job = mJobs.get(i);
181

  
182
        if( job.type==ATTACH && job.node.getEffects()==effects )
183
          {
184
          mJobs.remove(i);
185
          break;
186
          }
187
        }
188
      }
189
    }
190

  
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

  
193
  void detachAll()
194
    {
195
    mJobs.add(new Job(DETALL,null));
196
    InternalMaster.newSlave(this);
197
    }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
/**
201
 * This is not really part of the public API. Has to be public only because it is a part of the
202
 * DistortedSlave interface, which should really be a class that we extend here instead but
203
 * Java has no multiple inheritance.
204
 *
205
 * @y.exclude
206
 */
207
  public void doWork()
208
    {
209
    int num = mJobs.size();
210

  
211
    if( num>0 )
212
      {
213
      Job job;
214
      int numChanges=0;
215

  
216
      for(int i=0; i<num; i++)
217
        {
218
        job = mJobs.remove(0);
219

  
220
        switch(job.type)
221
          {
222
          case ATTACH: numChanges++;
223
                       if( mChildren==null ) mChildren = new ArrayList<>(2);
224
                       job.node.setParent(mParent);
225
                       addSortingByBuckets(job.node);
226
                       break;
227
          case DETACH: numChanges++;
228
                       if( mNumChildren>0 && mChildren.remove(job.node) )
229
                         {
230
                         job.node.setParent(null);
231
                         mNumChildren--;
232
                         }
233
                       break;
234
          case DETALL: numChanges++;
235
                       if( mNumChildren>0 )
236
                         {
237
                         DistortedNode tmp;
238

  
239
                         for(int j=mNumChildren-1; j>=0; j--)
240
                           {
241
                           tmp = mChildren.remove(j);
242
                           tmp.setParent(null);
243
                           }
244

  
245
                         mNumChildren = 0;
246
                         }
247
                       break;
248
          case SORT  : mChildren.remove(job.node);
249
                       addSortingByBuckets(job.node);
250
                       break;
251
          }
252
        }
253
      if( numChanges>0 ) mParent.adjustIsomorphism();
254
      }
255
    }
256
  }
257

  
src/main/java/org/distorted/library/main/InternalMaster.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
import java.util.ArrayList;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
/**
27
 * This static class handles assigning jobs to other classes. It does it once, at the beginning of
28
 * each frame.
29
 * <p>
30
 * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
31
 *
32
 * @y.exclude
33
 */
34
public class InternalMaster
35
  {
36
  /**
37
   * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
38
   *
39
   * @y.exclude
40
   */
41
  public interface Slave
42
    {
43
    void doWork();
44
    }
45

  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  private InternalMaster()
49
    {
50

  
51
    }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
  static boolean toDo()
56
    {
57
    Slave slave;
58
    ArrayList<Slave> list = InternalStackFrameList.getSet();
59
    int numSlaves = list.size();
60

  
61
    try
62
      {
63
      for(int i=0; i<numSlaves; i++)
64
        {
65
        slave = list.remove(0);
66
        if( slave!=null ) slave.doWork();
67
        }
68
      }
69
    catch(IndexOutOfBoundsException ie)
70
      {
71
      // onDestroy must have been called, ignore
72
      }
73

  
74
    return numSlaves>0;
75
    }
76

  
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

  
79
  public static void newSlave(Slave s)
80
    {
81
    ArrayList<Slave> list = InternalStackFrameList.getSet();
82
    int num = list.size();
83
    boolean found = false;
84
    Slave tmp;
85

  
86
    try
87
      {
88
      for(int i=0; i<num; i++)
89
        {
90
        tmp = list.get(i);
91

  
92
        if( tmp==s )
93
          {
94
          found = true;
95
          break;
96
          }
97
        }
98
      }
99
    catch(IndexOutOfBoundsException ie)
100
      {
101
      // onDestroy must have been called, ignore
102
      }
103

  
104
    if( !found ) list.add(s);
105
    }
106
  }
src/main/java/org/distorted/library/main/InternalMaster.kt
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
import java.util.ArrayList;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
/**
27
 * This static class handles assigning jobs to other classes. It does it once, at the beginning of
28
 * each frame.
29
 * <p>
30
 * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
31
 *
32
 * @y.exclude
33
 */
34
public class InternalMaster
35
  {
36
  /**
37
   * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
38
   *
39
   * @y.exclude
40
   */
41
  public interface Slave
42
    {
43
    void doWork();
44
    }
45

  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  private InternalMaster()
49
    {
50

  
51
    }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
  static boolean toDo()
56
    {
57
    Slave slave;
58
    ArrayList<Slave> list = InternalStackFrameList.getSet();
59
    int numSlaves = list.size();
60

  
61
    try
62
      {
63
      for(int i=0; i<numSlaves; i++)
64
        {
65
        slave = list.remove(0);
66
        if( slave!=null ) slave.doWork();
67
        }
68
      }
69
    catch(IndexOutOfBoundsException ie)
70
      {
71
      // onDestroy must have been called, ignore
72
      }
73

  
74
    return numSlaves>0;
75
    }
76

  
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

  
79
  public static void newSlave(Slave s)
80
    {
81
    ArrayList<Slave> list = InternalStackFrameList.getSet();
82
    int num = list.size();
83
    boolean found = false;
84
    Slave tmp;
85

  
86
    try
87
      {
88
      for(int i=0; i<num; i++)
89
        {
90
        tmp = list.get(i);
91

  
92
        if( tmp==s )
93
          {
94
          found = true;
95
          break;
96
          }
97
        }
98
      }
99
    catch(IndexOutOfBoundsException ie)
100
      {
101
      // onDestroy must have been called, ignore
102
      }
103

  
104
    if( !found ) list.add(s);
105
    }
106
  }
src/main/java/org/distorted/library/main/InternalNodeData.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
import java.util.ArrayList;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
/**
27
 * This is a member of DistortedNode. Makes sure two isomorphic Nodes only get rendered once.
28
 */
29
class InternalNodeData
30
  {
31
  private final ArrayList<Long> mKey;
32
  private int numPointingNodes;
33
  private long currTime;
34

  
35
  final long ID;
36
  DistortedFramebuffer mFBO;
37

  
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

  
40
  InternalNodeData(long id, ArrayList<Long> k)
41
    {
42
    ID              = id;
43
    mKey            = k;
44
    numPointingNodes= 1;
45
    currTime        =-1;
46
    mFBO            = null;
47
    }
48

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

  
51
  static InternalNodeData returnData(ArrayList<Long> list)
52
    {
53
    InternalNodeData data = InternalStackFrameList.getMapID(list);
54

  
55
    if( data!=null )
56
      {
57
      data.numPointingNodes++;
58
      }
59
    else
60
      {
61
      data = InternalStackFrameList.putNewDataToMap(list);
62
      }
63

  
64
    return data;
65
    }
66

  
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

  
69
  boolean removeData()
70
    {
71
    if( --numPointingNodes==0 )
72
      {
73
      InternalStackFrameList.removeKeyFromMap(mKey);
74

  
75
        return mFBO != null;
76
      }
77

  
78
    return false;
79
    }
80

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

  
83
  boolean notRenderedYetAtThisTime(long time)
84
    {
85
    if( currTime!=time )
86
      {
87
      currTime = time;
88
      return true;
89
      }
90

  
91
    return false;
92
    }
93
  }
src/main/java/org/distorted/library/main/InternalNodeData.kt
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
import java.util.ArrayList;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
/**
27
 * This is a member of DistortedNode. Makes sure two isomorphic Nodes only get rendered once.
28
 */
29
class InternalNodeData
30
  {
31
  private final ArrayList<Long> mKey;
32
  private int numPointingNodes;
33
  private long currTime;
34

  
35
  final long ID;
36
  DistortedFramebuffer mFBO;
37

  
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

  
40
  InternalNodeData(long id, ArrayList<Long> k)
41
    {
42
    ID              = id;
43
    mKey            = k;
44
    numPointingNodes= 1;
45
    currTime        =-1;
46
    mFBO            = null;
47
    }
48

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

  
51
  static InternalNodeData returnData(ArrayList<Long> list)
52
    {
53
    InternalNodeData data = InternalStackFrameList.getMapID(list);
54

  
55
    if( data!=null )
56
      {
57
      data.numPointingNodes++;
58
      }
59
    else
60
      {
61
      data = InternalStackFrameList.putNewDataToMap(list);
62
      }
63

  
64
    return data;
65
    }
66

  
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

  
69
  boolean removeData()
70
    {
71
    if( --numPointingNodes==0 )
72
      {
73
      InternalStackFrameList.removeKeyFromMap(mKey);
74

  
75
        return mFBO != null;
76
      }
77

  
78
    return false;
79
    }
80

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

  
83
  boolean notRenderedYetAtThisTime(long time)
84
    {
85
    if( currTime!=time )
86
      {
87
      currTime = time;
88
      return true;
89
      }
90

  
91
    return false;
92
    }
93
  }
src/main/java/org/distorted/library/main/InternalObject.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.main;
22

  
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24
/**
25
 * Any Object which gets uploaded to GPU memory and thus needs to be re-created (transparently to
26
 * applications!) whenever we lose OpenGL context.
27
 * <p>
28
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
29
 * Objects for deletion, and delete all marked Objects later at a convenient time (that's
30
 * because we can only delete from a thread that holds the OpenGL context so here we provide a
31
 * framework where one is able to mark for deletion at any time and actual deletion takes place
32
 * on the next render).
33
*/
34
abstract class InternalObject
35
{
36
  static final int FAILED_TO_CREATE = 1;
37
  static final int NOT_CREATED_YET  = 2;
38
  static final int DONT_CREATE      = 3;
39
  static final int CREATED          = 4;
40

  
41
  static final int TYPE_USER = 0;
42
  static final int TYPE_TREE = 1;
43
  static final int TYPE_SYST = 2;
44

  
45
  static final int STORAGE_COMMON  = 0;
46
  static final int STORAGE_PRIVATE = 1;
47

  
48
  static final int JOB_CREATE = 0;
49
  static final int JOB_DELETE = 1;
50

  
51
  private final long mID;
52
  private final int mType;
53
  private final int mStorage;
54

  
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

  
57
  abstract void create();
58
  abstract void delete();
59
  abstract void recreate();
60
  abstract String printDetails();
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

  
64
  void print(String msg)
65
    {
66
    String str = "ID:"+mID;
67

  
68
    switch(mType)
69
      {
70
      case TYPE_SYST: str+=" SYSTEM "; break;
71
      case TYPE_USER: str+=" USER   "; break;
72
      case TYPE_TREE: str+=" TREE   "; break;
73
      default       : str+=" ERROR? ";
74
      }
75

  
76
    DistortedLibrary.logMessage("InternalObject: "+str+printDetails()+msg);
77
    }
78

  
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

  
81
  InternalObject(int type, int storage)
82
    {
83
    mType    = type;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff