Project

General

Profile

« Previous | Next » 

Revision 11845a9e

Added by Leszek Koltunski about 5 years ago

Carve the 'children list' from DOutputSurface and DNode into a separate class of its own, DistortedChildrenList.

View differences:

src/main/java/org/distorted/library/main/DistortedNode.java
37 37
 * to sub-class 'NodeData'. Two identical sub-trees attached at different points of the main tree
38 38
 * will point to the same NodeData; only the first of this is rendered (mData.numRender!).
39 39
 */
40
public class DistortedNode implements DistortedMaster.Slave
40
public class DistortedNode implements DistortedChildrenList.Parent
41 41
  {
42
  private static final int ATTACH = 0;
43
  private static final int DETACH = 1;
44
  private static final int DETALL = 2;
45
  private static final int SORT   = 3;
46

  
47
  private class Job
48
    {
49
    int type;
50
    DistortedNode node;
51

  
52
    Job(int t, DistortedNode n)
53
      {
54
      type = t;
55
      node = n;
56
      }
57
    }
58

  
59
  private ArrayList<Job> mJobs = new ArrayList<>();
60

  
61
  private ArrayList<DistortedNode> mChildren;
62
  private int[] mNumChildren;  // ==mChildren.length(), but we only create mChildren if the first one gets added
63

  
64
  private boolean mRenderWayOIT;
65
  private DistortedNode mParent;
66
  private DistortedOutputSurface mSurfaceParent;
67 42
  private MeshBase mMesh;
68 43
  private DistortedEffects mEffects;
69 44
  private DistortedSurface mSurface;
70 45
  private DistortedRenderState mState;
71 46
  private DistortedNodeData mData;
47
  private DistortedChildrenList mChildren;
48
  private DistortedChildrenList.Parent mParent;
49

  
72 50
  private int mFboW, mFboH, mFboDepthStencil;
51
  private boolean mRenderWayOIT;
73 52

  
74 53
///////////////////////////////////////////////////////////////////////////////////////////////////
75 54

  
......
89 68
  private ArrayList<Long> generateIDList()
90 69
    {
91 70
    ArrayList<Long> ret = new ArrayList<>();
71
    int numChildren = mChildren.getNumChildren();
92 72

  
93
    if( mNumChildren[0]==0 )
73
    if( numChildren==0 )
94 74
      {
95 75
      // add a negative number so this leaf never gets confused with a internal node
96 76
      // with a single child that happens to have ID identical to some leaf's Effects ID.
......
100 80
      {
101 81
      DistortedNode node;
102 82
   
103
      for(int i=0; i<mNumChildren[0]; i++)
83
      for(int i=0; i<numChildren; i++)
104 84
        {
105
        node = mChildren.get(i);
85
        node = mChildren.getChild(i);
106 86
        ret.add(node.mData.ID);
107 87
        }
108 88

  
......
129 109
    }
130 110

  
131 111
///////////////////////////////////////////////////////////////////////////////////////////////////
132
// tree isomorphism algorithm
133

  
134
  private void adjustIsomorphism()
112
/**
113
 * This is not really part of the public API. Has to be public only because it is a part of the
114
 * DistortedChildrenList.Parent interface.
115
 *
116
 * @y.exclude
117
 */
118
  public void adjustIsomorphism()
135 119
    {
136 120
    DistortedNodeData newData = DistortedNodeData.returnData(generateIDList());
137 121
    boolean deleteOldFBO = mData.removeData();
138
    boolean createNewFBO = (mNumChildren[0]>0 && newData.mFBO==null);
122
    boolean createNewFBO = (mChildren.getNumChildren()>0 && newData.mFBO==null);
139 123

  
140 124
    if( deleteOldFBO && createNewFBO )
141 125
      {
......
148 132
      }
149 133
    else if( createNewFBO )
150 134
      {
151
      int width  = mFboW <= 0 ? mSurface.getWidth()  : mFboW;
152
      int height = mFboH <= 0 ? mSurface.getHeight() : mFboH;
153
      newData.mFBO = new DistortedFramebuffer(1,mFboDepthStencil, DistortedSurface.TYPE_TREE, width, height);
135
      newData.mFBO = allocateNewFBO();
154 136
      }
155 137

  
156 138
    mData = newData;
......
158 140
    if( mParent!=null ) mParent.adjustIsomorphism();
159 141
    }
160 142

  
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144
/**
145
 * This is not really part of the public API. Has to be public only because it is a part of the
146
 * DistortedChildrenList.Parent interface.
147
 *
148
 * @y.exclude
149
 */
150
  public DistortedChildrenList getChildren()
151
    {
152
    return mChildren;
153
    }
154

  
161 155
///////////////////////////////////////////////////////////////////////////////////////////////////
162 156
// return the total number of render calls issued
163 157

  
164 158
  int drawNoBlend(long currTime, DistortedOutputSurface surface)
165 159
    {
166
    DistortedSurface input = mNumChildren[0]==0 ? mSurface : mData.mFBO;
160
    DistortedSurface input = getInternalSurface();
167 161

  
168 162
    if( input.setAsInput() )
169 163
      {
......
182 176

  
183 177
  int drawOIT(long currTime, DistortedOutputSurface surface)
184 178
    {
185
    DistortedSurface input = mNumChildren[0]==0 ? mSurface : mData.mFBO;
179
    DistortedSurface input = getInternalSurface();
186 180

  
187 181
    if( input.setAsInput() )
188 182
      {
......
199 193

  
200 194
  int draw(long currTime, DistortedOutputSurface surface)
201 195
    {
202
    DistortedSurface input = mNumChildren[0]==0 ? mSurface : mData.mFBO;
196
    DistortedSurface input = getInternalSurface();
203 197

  
204 198
    if( input.setAsInput() )
205 199
      {
......
217 211
  int renderRecursive(long currTime)
218 212
    {
219 213
    int numRenders = 0;
214
    int numChildren = mChildren.getNumChildren();
220 215

  
221
    if( mNumChildren[0]>0 && mData.notRenderedYetAtThisTime(currTime) )
216
    if( numChildren>0 && mData.notRenderedYetAtThisTime(currTime) )
222 217
      {
223
      for (int i=0; i<mNumChildren[0]; i++)
224
        {
225
        numRenders += mChildren.get(i).renderRecursive(currTime);
226
        }
227

  
228
      if( mData.mFBO==null )
218
      for (int i=0; i<numChildren; i++)
229 219
        {
230
        int width  = mFboW <= 0 ? mSurface.getWidth()  : mFboW;
231
        int height = mFboH <= 0 ? mSurface.getHeight() : mFboH;
232
        mData.mFBO = new DistortedFramebuffer(1,mFboDepthStencil, DistortedSurface.TYPE_TREE, width, height);
220
        numRenders += mChildren.getChild(i).renderRecursive(currTime);
233 221
        }
234 222

  
223
      if( mData.mFBO==null ) mData.mFBO = allocateNewFBO();
235 224
      mData.mFBO.setAsOutput(currTime);
236 225

  
237 226
      if( mSurface.setAsInput() )
......
240 229
        DistortedEffects.blitPriv(mData.mFBO);
241 230
        }
242 231

  
243
      numRenders += mData.mFBO.renderChildren(currTime,mNumChildren[0],mChildren,0, mRenderWayOIT);
232
      numRenders += mData.mFBO.renderChildren(currTime,numChildren,mChildren,0, mRenderWayOIT);
244 233
      }
245 234

  
246 235
    return numRenders;
......
248 237

  
249 238
///////////////////////////////////////////////////////////////////////////////////////////////////
250 239

  
251
  void setSurfaceParent(DistortedOutputSurface dep)
240
  private DistortedFramebuffer allocateNewFBO()
252 241
    {
253
    mSurfaceParent = dep;
254
    mParent = null;
242
    int width  = mFboW <= 0 ? mSurface.getWidth()  : mFboW;
243
    int height = mFboH <= 0 ? mSurface.getHeight() : mFboH;
244
    return new DistortedFramebuffer(1,mFboDepthStencil, DistortedSurface.TYPE_TREE, width, height);
245
    }
246

  
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

  
249
  void setParent(DistortedChildrenList.Parent parent)
250
    {
251
    mParent = parent;
255 252
    }
256 253

  
257 254
///////////////////////////////////////////////////////////////////////////////////////////////////
......
260 257
    {
261 258
    if( mParent!=null )
262 259
      {
263
      mParent.mChildren.remove(this);
264
      DistortedMaster.addSortingByBuckets(mParent.mChildren,this);
265
      }
266
    else if( mSurfaceParent!=null )
267
      {
268
      ArrayList<DistortedNode> children = mSurfaceParent.getChildren();
269
      children.remove(this);
270
      DistortedMaster.addSortingByBuckets(children,this);
260
      DistortedChildrenList siblings = mParent.getChildren();
261
      siblings.removeChild(this);
262
      siblings.addSortingByBuckets(this);
271 263
      }
272 264
    }
273 265

  
......
294 286
    mEffects       = effects;
295 287
    mMesh          = mesh;
296 288
    mState         = new DistortedRenderState();
297
    mChildren      = null;
298
    mNumChildren   = new int[1];
289
    mChildren      = new DistortedChildrenList(this);
299 290
    mParent        = null;
300
    mSurfaceParent = null;
301 291
    mRenderWayOIT  = false;
302 292

  
303 293
    mFboW            = 0;  // i.e. take this from
......
324 314
    mMesh         = node.mMesh;
325 315
    mState        = new DistortedRenderState();
326 316
    mParent       = null;
327
    mSurfaceParent= null;
328 317
    mRenderWayOIT = false;
329 318

  
330 319
    mFboW            = node.mFboW;
......
357 346
        mSurface = new DistortedFramebuffer(1,depthStencil,DistortedSurface.TYPE_TREE,w,h);
358 347
        }
359 348
      }
349

  
360 350
    if( (flags & Distorted.CLONE_CHILDREN) != 0 )
361 351
      {
362
      if( node.mChildren==null )     // do NOT copy over the NULL!
363
        {
364
        node.mChildren = new ArrayList<>(2);
365
        }
366

  
367 352
      mChildren = node.mChildren;
368
      mNumChildren = node.mNumChildren;
369 353
      }
370 354
    else
371 355
      {
372
      mChildren = null;
373
      mNumChildren = new int[1];
356
      mChildren = new DistortedChildrenList(this);
374 357
      }
375 358

  
376 359
    mData = DistortedNodeData.returnData(generateIDList());
......
427 410
 */
428 411
  public void attach(DistortedNode node)
429 412
    {
430
    mJobs.add(new Job(ATTACH,node));
431
    DistortedMaster.newSlave(this);
413
    mChildren.attach(node);
432 414
    }
433 415

  
434 416
///////////////////////////////////////////////////////////////////////////////////////////////////
......
445 427
 */
446 428
  public DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
447 429
    {
448
    DistortedNode node = new DistortedNode(surface,effects,mesh);
449
    mJobs.add(new Job(ATTACH,node));
450
    DistortedMaster.newSlave(this);
451
    return node;
430
    return mChildren.attach(surface,effects,mesh);
452 431
    }
453 432

  
454 433
///////////////////////////////////////////////////////////////////////////////////////////////////
......
462 441
 */
463 442
  public void detach(DistortedNode node)
464 443
    {
465
    mJobs.add(new Job(DETACH,node));
466
    DistortedMaster.newSlave(this);
444
    mChildren.detach(node);
467 445
    }
468 446

  
469 447
///////////////////////////////////////////////////////////////////////////////////////////////////
......
480 458
 */
481 459
  public void detach(DistortedEffects effects)
482 460
    {
483
    long id = effects.getID();
484
    DistortedNode node;
485
    boolean detached = false;
486

  
487
    for(int i=0; i<mNumChildren[0]; i++)
488
      {
489
      node = mChildren.get(i);
490

  
491
      if( node.getEffects().getID()==id )
492
        {
493
        detached = true;
494
        mJobs.add(new Job(DETACH,node));
495
        DistortedMaster.newSlave(this);
496
        break;
497
        }
498
      }
499

  
500
    if( !detached )
501
      {
502
      // if we failed to detach any, it still might be the case that
503
      // there's an ATTACH job that we need to cancel.
504
      int num = mJobs.size();
505
      Job job;
506

  
507
      for(int i=0; i<num; i++)
508
        {
509
        job = mJobs.get(i);
510

  
511
        if( job.type==ATTACH && job.node.getEffects()==effects )
512
          {
513
          mJobs.remove(i);
514
          break;
515
          }
516
        }
517
      }
461
    mChildren.detach(effects);
518 462
    }
519 463

  
520 464
///////////////////////////////////////////////////////////////////////////////////////////////////
......
526 470
 */
527 471
  public void detachAll()
528 472
    {
529
    mJobs.add(new Job(DETALL,null));
530
    DistortedMaster.newSlave(this);
531
    }
532

  
533
///////////////////////////////////////////////////////////////////////////////////////////////////
534
/**
535
 * This is not really part of the public API. Has to be public only because it is a part of the
536
 * DistortedSlave interface, which should really be a class that we extend here instead but
537
 * Java has no multiple inheritance.
538
 *
539
 * @y.exclude
540
 */
541
  public void doWork()
542
    {
543
    int num = mJobs.size();
544

  
545
    if( num>0 )
546
      {
547
      Job job;
548
      int numChanges=0;
549

  
550
      for(int i=0; i<num; i++)
551
        {
552
        job = mJobs.remove(0);
553

  
554
        switch(job.type)
555
          {
556
          case ATTACH: numChanges++;
557
                       if( mChildren==null ) mChildren = new ArrayList<>(2);
558
                       job.node.mParent = this;
559
                       job.node.mSurfaceParent = null;
560
                       DistortedMaster.addSortingByBuckets(mChildren,job.node);
561
                       mNumChildren[0]++;
562
                       break;
563
          case DETACH: numChanges++;
564
                       if( mNumChildren[0]>0 && mChildren.remove(job.node) )
565
                         {
566
                         job.node.mParent = null;
567
                         job.node.mSurfaceParent = null;
568
                         mNumChildren[0]--;
569
                         }
570
                       break;
571
          case DETALL: numChanges++;
572
                       if( mNumChildren[0]>0 )
573
                         {
574
                         DistortedNode tmp;
575

  
576
                         for(int j=mNumChildren[0]-1; j>=0; j--)
577
                           {
578
                           tmp = mChildren.remove(j);
579
                           tmp.mParent = null;
580
                           tmp.mSurfaceParent = null;
581
                           }
582

  
583
                         mNumChildren[0] = 0;
584
                         }
585
                       break;
586
          case SORT  : mChildren.remove(job.node);
587
                       DistortedMaster.addSortingByBuckets(mChildren,job.node);
588
                       break;
589
          }
590
        }
591
      if( numChanges>0 ) adjustIsomorphism();
592
      }
473
    mChildren.detachAll();
593 474
    }
594 475

  
595 476
///////////////////////////////////////////////////////////////////////////////////////////////////
......
622 503
   */
623 504
  public DistortedSurface getInternalSurface()
624 505
    {
625
    return mNumChildren[0]==0 ? mSurface : mData.mFBO;
506
    return mChildren.getNumChildren()==0 ? mSurface : mData.mFBO;
626 507
    }
627 508

  
628 509
///////////////////////////////////////////////////////////////////////////////////////////////////

Also available in: Unified diff