Project

General

Profile

« Previous | Next » 

Revision 9d845904

Added by Leszek Koltunski almost 6 years ago

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 = null;
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;
......
260 264

  
261 265
///////////////////////////////////////////////////////////////////////////////////////////////////
262 266

  
263
  private int blitWithDepth(long currTime, DistortedOutputSurface buffer)
267
  private int blitWithDepth(long currTime, DistortedOutputSurface buffer,int fbo)
264 268
    {
265 269
    GLES31.glViewport(0, 0, mWidth, mHeight);
266
    setAsOutput(currTime);
270
    setAsOutput(currTime,fbo);
267 271
    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
268 272
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
269 273
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
......
312 316
// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing
313 317
// to a whole buffer (lastQueue.postprocess) and merge it (this.blitWithDepth).
314 318

  
315
  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children)
319
  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children, int fbo)
316 320
    {
317 321
    int quality=0, internalQuality = 0, numRenders = 0, bucketChange = 0;
318 322
    DistortedNode child1, child2;
......
327 331

  
328 332
      if( currBucket==0 )
329 333
        {
330
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
334
        setAsOutput(time,fbo);
331 335
        numRenders += child1.draw(time,this);
332 336
        }
333 337
      else
......
349 353
              }
350 354

  
351 355
            numRenders += lastQueue.postprocess(mBuffer);
352
            numRenders += blitWithDepth(time, mBuffer[quality]);
356
            numRenders += blitWithDepth(time, mBuffer[quality],fbo);
353 357

  
354 358
            mBuffer[quality].setAsOutputAndClear(time);
355 359
            }
......
371 375
            }
372 376

  
373 377
          numRenders += currQueue.postprocess(mBuffer);
374
          numRenders += blitWithDepth(time, mBuffer[quality]);
378
          numRenders += blitWithDepth(time, mBuffer[quality],fbo);
375 379
          }
376 380
        } // end postprocessed child case
377 381

  
......
423 427
    {
424 428
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
425 429

  
426
    mTime = time;    // have to do this otherwise on the next setAsOutput() we would clear
430
    mTime[0] = time;    // have to do this otherwise on the next setAsOutput() we would clear
427 431
    DistortedRenderState.colorDepthStencilOn();
428 432
    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
429 433
    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
430 434
    DistortedRenderState.colorDepthStencilRestore();
431 435
    }
432 436

  
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

  
439
  private void setAsOutput(long time, int fbo)
440
    {
441
    if( fbo>=0 && fbo<mNumFBOs )
442
      {
443
      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]);
444

  
445
      if (mTime[fbo] != time)
446
        {
447
        mTime[fbo] = time;
448
        clear();
449
        }
450
      }
451
    else
452
      {
453
      android.util.Log.e("surface", "error in setAsOutput, fbo="+fbo);
454
      }
455
    }
456

  
433 457
///////////////////////////////////////////////////////////////////////////////////////////////////
434 458
// PUBLIC API
435 459
///////////////////////////////////////////////////////////////////////////////////////////////////
460
/**
461
 * Draws all the attached children to this OutputSurface's 0th FBO.
462
 * <p>
463
 * Must be called from a thread holding OpenGL Context.
464
 *
465
 * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
466
 * @return Number of objects rendered.
467
 */
468
  public int render(long time)
469
    {
470
    return render(time,0);
471
    }
436 472

  
473
///////////////////////////////////////////////////////////////////////////////////////////////////
437 474
/**
438 475
 * Draws all the attached children to this OutputSurface.
439 476
 * <p>
440 477
 * Must be called from a thread holding OpenGL Context.
441 478
 *
442 479
 * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
480
 * @param fbo The surface can have many FBOs backing it up - render this to FBO number 'fbo'.
443 481
 * @return Number of objects rendered.
444 482
 */
445
  public int render(long time)
483
  public int render(long time, int fbo)
446 484
    {
447 485
    // change tree topology (attach and detach children)
448 486
/*
......
485 523
      numRenders += mChildren.get(i).renderRecursive(time);
486 524
      }
487 525

  
488
    setAsOutput(time);
489
    numRenders += renderChildren(time,mNumChildren,mChildren);
526
    numRenders += renderChildren(time,mNumChildren,mChildren,fbo);
490 527

  
491 528
    return numRenders;
492 529
    }
......
504 541
    {
505 542
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
506 543

  
507
    if( mTime!=time )
544
    if( mTime[0]!=time )
508 545
      {
509
      mTime = time;
546
      mTime[0] = time;
510 547
      clear();
511 548
      }
512 549
    }

Also available in: Unified diff