Project

General

Profile

« Previous | Next » 

Revision 8ebbc730

Added by Leszek Koltunski almost 6 years ago

Port a commit from the master branch.

Finally properly fix the flashing on ARM Mali T880 GPU.

The flashing is caused by a 'full pipeline flush' (see DarkPhoton, https://www.opengl.org/discussion_boards/showthread.php/200754-Flashes-on-ARM-Mali?p=1291679&viewfull=1#post1291679 ). In order to combat it, first introduce the possibility that a single DistortedOutputSurface is backed up by more than one FBO. Then make DistortedScreen be derived from DistortedFramebuffer (which itself is derived from DistortedOutputSurface) and make it contain 3 FBOs, render to them in a circular queue fashion, and blit from a given FBO to the system FBO. The 'more than 1 intermediate FBO' queue prevents the pipeline flush.

Still some TODOs in DistortedFramebuffer remain (properly check for Framebuffer completness!)

View differences:

src/main/java/org/distorted/library/main/DistortedOutputSurface.java
72 72
  // Global buffers used for postprocessing.
73 73
  private static DistortedOutputSurface[] mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH];
74 74

  
75
  private long mTime;
76 75
  private float mFOV;
77 76
  float mDistance, mNear;
78 77
  float[] mProjectionMatrix;
79 78

  
80 79
  int mDepthStencilCreated;
81 80
  int mDepthStencil;
82
  int[] mDepthStencilH = new int[1];
83
  int[] mFBOH          = new int[1];
81
  int[] mDepthStencilH;
82
  int[] mFBOH;
83
  private long[] mTime;
84 84

  
85 85
  private float mClearR, mClearG, mClearB, mClearA;
86 86
  private float mClearDepth;
......
95 95

  
96 96
///////////////////////////////////////////////////////////////////////////////////////////////////
97 97

  
98
  DistortedOutputSurface(int width, int height, int createColor, int numcolors, int depthStencil, int fbo, int type)
98
  DistortedOutputSurface(int width, int height, int createColor, int numfbos, int numcolors, int depthStencil, int fbo, int type)
99 99
    {
100
    super(width,height,createColor,numcolors,type);
100
    super(width,height,createColor,numfbos,numcolors,type);
101

  
102
    mDepthStencilH = new int[numfbos];
103
    mFBOH          = new int[numfbos];
104

  
105
    mTime = new long[numfbos];
106
    for(int i=0; i<mNumFBOs;i++) mTime[i]=0;
101 107

  
102 108
    mRealWidth = width;
103 109
    mRealHeight= height;
......
113 119
    mFBOH[0]         = fbo;
114 120
    mDepthStencilH[0]= 0;
115 121

  
116
    mTime = 0;
117

  
118 122
    mClearR = 0.0f;
119 123
    mClearG = 0.0f;
120 124
    mClearB = 0.0f;
......
263 267

  
264 268
///////////////////////////////////////////////////////////////////////////////////////////////////
265 269

  
266
  private int oitBuild(DistortedOutputSurface buffer)
270
  private int oitBuild(long time, DistortedOutputSurface buffer, int fbo)
267 271
    {
268 272
    GLES31.glViewport(0, 0, mWidth, mHeight);
269
    setAsOutput();
273
    setAsOutput(time,fbo);
270 274
    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
271 275
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
272 276
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
......
355 359
// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing
356 360
// to a whole buffer (lastQueue.postprocess) and merge it (this.oitBuild).
357 361

  
358
  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children)
362
  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children, int fbo)
359 363
    {
360 364
    int quality=0, internalQuality = 0, numRenders = 0, bucketChange = 0;
361 365
    DistortedNode child1, child2;
......
370 374

  
371 375
      if( currBucket==0 )
372 376
        {
373
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
374
        numRenders += child1.draw(time, this);
377
        setAsOutput(time,fbo);
378
        numRenders += child1.draw(time,this);
375 379
        }
376 380
      else
377 381
        {
......
393 397
              }
394 398

  
395 399
            numRenders += lastQueue.postprocess(mBuffer);
396
            numRenders += oitBuild(mBuffer[quality]);
400
            numRenders += oitBuild(time,mBuffer[quality],fbo);
397 401
            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
398 402
            clearBuffer(mBuffer[quality]);
403

  
399 404
            }
400 405

  
401 406
          internalQuality = currQueue.getInternalQuality();
......
415 420
            }
416 421

  
417 422
          numRenders += currQueue.postprocess(mBuffer);
418
          numRenders += oitBuild(mBuffer[quality]);
423
          numRenders += oitBuild(time,mBuffer[quality],fbo);
419 424
          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
420 425
          numRenders += oitRender(time);  // merge the OIT linked list
421 426
          clearBuffer(mBuffer[quality]);
......
458 463
    return (float)mHeight/mRealHeight;
459 464
    }
460 465

  
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

  
468
  private void setAsOutput(long time, int fbo)
469
    {
470
    if( fbo>=0 && fbo<mNumFBOs )
471
      {
472
      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]);
473

  
474
      if (mTime[fbo] != time)
475
        {
476
        mTime[fbo] = time;
477
        clear();
478
        }
479
      }
480
    else
481
      {
482
      android.util.Log.e("surface", "error in setAsOutput, fbo="+fbo);
483
      }
484
    }
485

  
461 486
///////////////////////////////////////////////////////////////////////////////////////////////////
462 487
// PUBLIC API
463 488
///////////////////////////////////////////////////////////////////////////////////////////////////
464 489
/**
465
 * Draws all the attached children to this OutputSurface.
490
 * Draws all the attached children to this OutputSurface's 0th FBO.
466 491
 * <p>
467 492
 * Must be called from a thread holding OpenGL Context.
468 493
 *
......
470 495
 * @return Number of objects rendered.
471 496
 */
472 497
  public int render(long time)
498
    {
499
    return render(time,0);
500
    }
501

  
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503
/**
504
 * Draws all the attached children to this OutputSurface.
505
 * <p>
506
 * Must be called from a thread holding OpenGL Context.
507
 *
508
 * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
509
 * @param fbo The surface can have many FBOs backing it up - render this to FBO number 'fbo'.
510
 * @return Number of objects rendered.
511
 */
512
  public int render(long time, int fbo)
473 513
    {
474 514
    // change tree topology (attach and detach children)
475 515
/*
......
512 552
      numRenders += mChildren.get(i).renderRecursive(time);
513 553
      }
514 554

  
515
    setAsOutput(time);
516
    numRenders += renderChildren(time,mNumChildren,mChildren);
555
    numRenders += renderChildren(time,mNumChildren,mChildren,fbo);
517 556

  
518 557
    return numRenders;
519 558
    }
......
531 570
    {
532 571
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
533 572

  
534
    if( mTime!=time )
573
    if( mTime[0]!=time )
535 574
      {
536
      mTime = time;
575
      mTime[0] = time;
537 576
      clear();
538 577
      }
539 578
    }

Also available in: Unified diff