Project

General

Profile

« Previous | Next » 

Revision f4d6114c

Added by Leszek Koltunski almost 6 years ago

I spoke too soon, the ARM Mali flashing is of course not fixed yet. The previous commit fixed Triblur, but the bug is still reproducible elsewhere (only in the 'postprocessed' apps though).

This commit introduces a circular queue in case of the postprocessing FBOs - with little success though.

View differences:

src/main/java/org/distorted/library/effect/PostprocessEffect.java
139 139
 *
140 140
 * @y.exclude
141 141
 */
142
  public abstract int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers);
142
  public abstract int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers, int fbo);
143 143

  
144 144
///////////////////////////////////////////////////////////////////////////////////////////////////
145 145
/**
src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
140 140
 *
141 141
 * @y.exclude
142 142
 */
143
  public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers)
143
  public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers, int fbo)
144 144
    {
145 145
    if( mProgram1 ==null)
146 146
      {
......
159 159

  
160 160
    DistortedFramebuffer buffer = (DistortedFramebuffer)buffers[mQualityLevel];
161 161

  
162
    buffer.setAsOutput();
162
    buffer.setAsOutputFBO(fbo);
163 163

  
164 164
    float w= buffer.getWidth();
165 165
    float h= buffer.getHeight();
......
182 182
    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrW;
183 183

  
184 184
    mProgram1.useProgram();
185
    buffer.bindForOutput(1);
186
    buffer.setAsInput(0);
185
    buffer.bindForOutput(2*fbo+1);
186
    buffer.setAsInput(2*fbo);
187 187

  
188 188
    GLES31.glColorMask(true,true,true,true);
189 189
    GLES31.glClearColor(1.0f,1.0f,1.0f,0.0f);
......
203 203
    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrH;
204 204

  
205 205
    mProgram2.useProgram();
206
    buffer.bindForOutput(0);
207
    buffer.setAsInput(1);
206
    buffer.bindForOutput(2*fbo);
207
    buffer.setAsInput(2*fbo+1);
208 208

  
209 209
    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
210 210

  
src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
144 144
 *
145 145
 * @y.exclude
146 146
 */
147
  public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers)
147
  public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers, int fbo)
148 148
    {
149 149
    if( mProgram1 ==null)
150 150
      {
......
180 180
    int offset = radius + radius*radius/4;
181 181
    radius = (radius+1)/2;
182 182

  
183
    outBuffer.setAsOutput();
183
    outBuffer.setAsOutputFBO(fbo);
184 184
    GLES31.glViewport(0, 0, (int)w, (int)h);
185 185

  
186 186
    // horizontal glow
187 187
    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrW;
188 188

  
189 189
    mProgram1.useProgram();
190
    outBuffer.bindForOutput(1);
191
    inBuffer.setAsInput(0);
190
    outBuffer.bindForOutput(2*fbo+1);
191
    inBuffer.setAsInput(2*fbo);
192 192

  
193 193
    GLES31.glColorMask(true,true,true,true);
194 194
    GLES31.glClearColor(1.0f,1.0f,1.0f,0.0f);
......
209 209
    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrH;
210 210

  
211 211
    mProgram2.useProgram();
212
    outBuffer.bindForOutput(0);
213
    outBuffer.setAsInput(1);
212
    outBuffer.bindForOutput(2*fbo);
213
    outBuffer.setAsInput(2*fbo+1);
214 214

  
215 215
    GLES31.glUniform1f ( mProgram2.mUniform[0] , n );
216 216
    GLES31.glUniform2f ( mProgram2.mUniform[1] , corrW, corrH );
src/main/java/org/distorted/library/main/Distorted.java
77 77
   */
78 78
  public static final int CLONE_CHILDREN= 0x20;
79 79

  
80
  /**
81
   * Work around bugs in ARM Mali driver by, instead to a single FBO, rendering to a circular queue
82
   * of FBO_QUEUE_SIZE FBOs. (otherwise we sometimes get a 'full pipeline flush' and the end result
83
   * might be missing part of the Objects)
84
   */
85
  public static final int FBO_QUEUE_SIZE = 4;
86

  
80 87
  private static boolean mInitialized=false;
81 88

  
82 89
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/main/DistortedFramebuffer.java
276 276
 */
277 277
  public boolean setAsInput(int texture)
278 278
    {
279
    if( texture>=0 && texture<mNumColors && mColorH[texture]>0 )
279
    if( texture>=0 && texture<mNumFBOs*mNumColors && mColorH[texture]>0 )
280 280
      {
281 281
      GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
282 282
      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[texture]);
......
290 290

  
291 291
  public void bindForOutput(int texture)
292 292
    {
293
    if( texture>=0 && texture<mNumColors && mColorH[texture]>0 )
293
    if( texture>=0 && texture<mNumFBOs*mNumColors && mColorH[texture]>0 )
294 294
      {
295 295
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[texture], 0);
296 296
      }
src/main/java/org/distorted/library/main/DistortedNode.java
264 264

  
265 265
    if( input.setAsInput() )
266 266
      {
267
      surface.setAsOutput();
268 267
      DistortedRenderState.setUpStencilMark();
269 268
      mEffects.drawPriv(mSurface.getWidth() /2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime, queue.getHalo()*surface.mMipmap);
270 269
      DistortedRenderState.unsetUpStencilMark();
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
180 180

  
181 181
    for(int j=0; j<EffectQuality.LENGTH; j++)
182 182
      {
183
      mBuffer[j] = new DistortedFramebuffer(2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
183
      mBuffer[j] = new DistortedFramebuffer(Distorted.FBO_QUEUE_SIZE,2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
184 184
      mBuffer[j].mMipmap = mipmap;
185 185
      mBuffer[j].mNear   = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
186 186
      mBuffer[j].glClearColor(1.0f,1.0f,1.0f,0.0f);
......
199 199

  
200 200
    for(int j=0; j<EffectQuality.LENGTH; j++)
201 201
      {
202
      mBuffer[j].setAsOutput();
203
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[1], 0);
204
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
205
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[0], 0);
206
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
202
      for(int k=0; k<Distorted.FBO_QUEUE_SIZE; k++)
203
        {
204
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBuffer[j].mFBOH[k]);
205
        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k+1], 0);
206
        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT);
207
        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k  ], 0);
208
        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
209
        }
207 210
      }
211

  
212
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
208 213
    }
209 214

  
210 215
///////////////////////////////////////////////////////////////////////////////////////////////////
......
267 272
  private int blitWithDepth(long currTime, DistortedOutputSurface buffer,int fbo)
268 273
    {
269 274
    GLES31.glViewport(0, 0, mWidth, mHeight);
270
    setAsOutput(currTime,fbo);
275
    setAsOutputFBO(currTime,fbo);
271 276
    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
272
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
277
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]);
273 278
    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
274
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
279
    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[fbo]);
275 280

  
276 281
    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
277 282
    GLES31.glStencilMask(0x00);
......
290 295
    GLES31.glClearDepthf(1.0f);
291 296
    GLES31.glClearStencil(0);
292 297

  
293
    buffer.setAsOutput();
294
    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[1], 0);
298
    buffer.setAsOutputFBO(fbo);
299
    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo+1], 0);
295 300
    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
296
    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[0], 0);
301
    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo  ], 0);
297 302
    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
298 303

  
299 304
    return 1;
......
331 336

  
332 337
      if( currBucket==0 )
333 338
        {
334
        setAsOutput(time,fbo);
339
        setAsOutputFBO(time,fbo);
335 340
        numRenders += child1.draw(time,this);
336 341
        }
337 342
      else
......
349 354
            for(int j=bucketChange; j<i; j++)
350 355
              {
351 356
              child2 = children.get(j);
357
              mBuffer[internalQuality].setAsOutputFBO(fbo);
352 358
              numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],lastQueue);
353 359
              }
354 360

  
355
            numRenders += lastQueue.postprocess(mBuffer);
361
            numRenders += lastQueue.postprocess(mBuffer,fbo);
356 362
            numRenders += blitWithDepth(time, mBuffer[quality],fbo);
357 363

  
358
            mBuffer[quality].setAsOutputAndClear(time);
364
            mBuffer[quality].setAsOutputAndClear(time,fbo);
359 365
            }
360 366

  
361 367
          internalQuality = currQueue.getInternalQuality();
......
363 369
          bucketChange    = i;
364 370
          }
365 371

  
366
        mBuffer[quality].setAsOutput(time);
372
        mBuffer[quality].setAsOutputFBO(time,fbo);
367 373
        child1.drawNoBlend(time,mBuffer[quality]);
368 374

  
369 375
        if( i==numChildren-1 )
......
371 377
          for(int j=bucketChange; j<numChildren; j++)
372 378
            {
373 379
            child2 = children.get(j);
380
            mBuffer[internalQuality].setAsOutputFBO(fbo);
374 381
            numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],currQueue);
375 382
            }
376 383

  
377
          numRenders += currQueue.postprocess(mBuffer);
384
          numRenders += currQueue.postprocess(mBuffer,fbo);
378 385
          numRenders += blitWithDepth(time, mBuffer[quality],fbo);
379 386
          }
380 387
        } // end postprocessed child case
......
422 429
 * Useful for drawing to the postprocessing buffer, which must sometimes be cleared multiple times
423 430
 * per frame.
424 431
 */
425

  
426
  private void setAsOutputAndClear(long time)
432
  private void setAsOutputAndClear(long time,int fbo)
427 433
    {
428
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
434
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]);
429 435

  
430
    mTime[0] = time;    // have to do this otherwise on the next setAsOutput() we would clear
436
    mTime[fbo] = time;    // have to do this otherwise on the next setAsOutput() we would clear
431 437
    DistortedRenderState.colorDepthStencilOn();
432 438
    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
433 439
    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
......
436 442

  
437 443
///////////////////////////////////////////////////////////////////////////////////////////////////
438 444

  
439
  private void setAsOutput(long time, int fbo)
445
  private void setAsOutputFBO(long time, int fbo)
440 446
    {
441 447
    if( fbo>=0 && fbo<mNumFBOs )
442 448
      {
......
450 456
      }
451 457
    else
452 458
      {
453
      android.util.Log.e("surface", "error in setAsOutput, fbo="+fbo);
459
      android.util.Log.e("surface", "error in setAsOutput1, fbo="+fbo);
460
      }
461
    }
462

  
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464
/**
465
 * Not part of the Public API.
466
 *
467
 * @y.exclude
468
 */
469
  public void setAsOutputFBO(int fbo)
470
    {
471
    if( fbo>=0 && fbo<mNumFBOs )
472
      {
473
      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]);
474
      }
475
    else
476
      {
477
      android.util.Log.e("surface", "error in setAsOutput2, fbo="+fbo);
454 478
      }
455 479
    }
456 480

  
src/main/java/org/distorted/library/main/DistortedScreen.java
56 56
  ///// END DEBUGGING //////////////////////////
57 57

  
58 58
  private int mCurrFBO;
59
  private static final int NUM_FBO = 3;
60 59

  
61 60
///////////////////////////////////////////////////////////////////////////////////////////////////
62 61
// PUBLIC API
......
68 67
 */
69 68
  public DistortedScreen()
70 69
    {
71
    super(NUM_FBO,1,BOTH_DEPTH_STENCIL, TYPE_SYST, 1,1);
70
    super(Distorted.FBO_QUEUE_SIZE,1,BOTH_DEPTH_STENCIL, TYPE_SYST, 1,1);
72 71
    mShowFPS = false;
73 72
    mCurrFBO = 0;
74 73
    }
......
122 121
      }
123 122

  
124 123
    mCurrFBO++;
125
    if( mCurrFBO>=NUM_FBO ) mCurrFBO=0;
124
    if( mCurrFBO>=Distorted.FBO_QUEUE_SIZE ) mCurrFBO=0;
126 125

  
127 126
    return numrender+1;
128 127
    }
src/main/java/org/distorted/library/main/EffectQueuePostprocess.java
100 100

  
101 101
///////////////////////////////////////////////////////////////////////////////////////////////////
102 102

  
103
  int postprocess(DistortedOutputSurface[] buffers)
103
  int postprocess(DistortedOutputSurface[] buffers, int fbo)
104 104
    {
105 105
    int numRenders = 0;
106 106

  
......
108 108

  
109 109
    for(int i=0; i<mNumEffects; i++)
110 110
      {
111
      numRenders += ((PostprocessEffect)mEffects[i]).apply(mUniforms,NUM_UNIFORMS*i, buffers);
111
      numRenders += ((PostprocessEffect)mEffects[i]).apply(mUniforms,NUM_UNIFORMS*i, buffers, fbo);
112 112
      }
113 113

  
114 114
    GLES31.glEnable(GLES31.GL_BLEND);

Also available in: Unified diff