Project

General

Profile

« Previous | Next » 

Revision 2dbed690

Added by Leszek Koltunski almost 6 years ago

In an attempt to contain the flashes on Mali GPU, re-structure the post-processing FBOs from 1 FBO with 2 color attachments + combined depth-stencil to 2 separate FBOs sharing a depth-stencil texture.

Result: this appears to make the flashes slightly worse.

View differences:

src/main/java/org/distorted/library/main/DistortedOutputSurface.java
69 69

  
70 70
  private ArrayList<Job> mJobs = new ArrayList<>();
71 71

  
72
  // Global buffers used for postprocessing.
73
  private static DistortedOutputSurface[] mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH];
72
  // Global buffers used for postprocessing. MipmapLevels x PING_PONG of each for postprocessing ping-pong.
73
  private static final int PING_PONG = 2;
74
  private static DistortedOutputSurface[][] mBuffer = null;
74 75

  
75 76
  private long mTime;
76 77
  private float mFOV;
......
171 172

  
172 173
  private static void createPostprocessingBuffers(int width, int height, float near)
173 174
    {
175
    mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH][PING_PONG];
174 176
    float mipmap=1.0f;
175 177

  
176
    for (int j=0; j<EffectQuality.LENGTH; j++)
178
    for (int i=0; i<EffectQuality.LENGTH; i++)
177 179
      {
178
      mBuffer[j] = new DistortedFramebuffer(2, BOTH_DEPTH_STENCIL, TYPE_SYST, (int) (width * mipmap), (int) (height * mipmap));
179
      mBuffer[j].mMipmap = mipmap;
180
      mBuffer[j].mNear = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
181
      mBuffer[j].glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
180
      mBuffer[i][0] = new DistortedFramebuffer(1, BOTH_DEPTH_STENCIL, TYPE_SYST, (int) (width * mipmap), (int) (height * mipmap));
181
      mBuffer[i][0].mMipmap = mipmap;
182
      mBuffer[i][0].mNear = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
183
      mBuffer[i][0].glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
184

  
185
      for(int j=1; j<PING_PONG; j++)
186
        {
187
        mBuffer[i][j] = new DistortedFramebuffer(1, NO_DEPTH_NO_STENCIL, TYPE_SYST, (int) (width * mipmap), (int) (height * mipmap));
188
        mBuffer[i][j].mMipmap = mipmap;
189
        mBuffer[i][j].mNear = near;
190
        mBuffer[i][j].glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
191
        }
182 192

  
183 193
      mipmap *= EffectQuality.MULTIPLIER;
184 194
      }
185 195

  
186 196
    DistortedObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
187 197

  
198
    for (int i=0; i<EffectQuality.LENGTH; i++)
199
      {
200
      for(int j=1; j<PING_PONG; j++)
201
        {
202
        ( (DistortedFramebuffer)mBuffer[i][j]).copyDepthAndStencil( (DistortedFramebuffer)mBuffer[i][0] );
203
        }
204
      }
205

  
188 206
    GLES31.glStencilMask(0xff);
189 207
    GLES31.glDepthMask(true);
190 208
    GLES31.glColorMask(true, true, true, true);
......
192 210
    GLES31.glClearDepthf(1.0f);
193 211
    GLES31.glClearStencil(0);
194 212

  
195
    for (int j=0; j<EffectQuality.LENGTH; j++)
213
    for (int i=0; i<EffectQuality.LENGTH; i++)
196 214
      {
197
      mBuffer[j].setAsOutput();
198
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[1], 0);
215
      mBuffer[i][0].setAsOutput();
199 216
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT);
200
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[0], 0);
201
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
217

  
218
      for(int j=1; j<PING_PONG; j++)
219
        {
220
        mBuffer[i][j].setAsOutput();
221
        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
222
        }
202 223
      }
203 224
    }
204 225

  
......
206 227

  
207 228
  static synchronized void onDestroy()
208 229
    {
209
    for(int j=0; j<EffectQuality.LENGTH; j++)
230
    if( mBuffer!=null )
210 231
      {
211
      mBuffer[j] = null;
232
      for (int i=0; i<EffectQuality.LENGTH; i++)
233
        {
234
        for (int j=1; j<PING_PONG; j++)
235
          {
236
          mBuffer[i][j] = null;
237
          }
238
        }
239

  
240
      mBuffer = null;
212 241
      }
213 242
    }
214 243

  
......
220 249

  
221 250
  private static void clonePostprocessingViewport(DistortedOutputSurface from)
222 251
    {
223
    if( mBuffer[0].mWidth != from.mWidth || mBuffer[0].mHeight != from.mHeight )
252
    if( mBuffer[0][0].mWidth != from.mWidth || mBuffer[0][0].mHeight != from.mHeight )
224 253
      {
225 254
      DistortedOutputSurface surface;
226 255

  
227 256
      for(int i=0; i<EffectQuality.LENGTH; i++)
228 257
        {
229
        surface = mBuffer[i];
258
        for(int j=0; j<PING_PONG; j++)
259
          {
260
          surface = mBuffer[i][j];
230 261

  
231
        surface.mWidth  = (int)(from.mWidth *surface.mMipmap);
232
        surface.mHeight = (int)(from.mHeight*surface.mMipmap);
262
          surface.mWidth  = (int) (from.mWidth  * surface.mMipmap);
263
          surface.mHeight = (int) (from.mHeight * surface.mMipmap);
233 264

  
234
        surface.mNear   = from.mNear;  // Near plane is independent of the mipmap level
265
          surface.mNear = from.mNear;  // Near plane is independent of the mipmap level
235 266

  
236
        //android.util.Log.e("surface", "viewport "+i+" to ("+from.mWidth+"x"+from.mHeight+")");
267
          //android.util.Log.e("surface", "viewport "+i+" to ("+from.mWidth+"x"+from.mHeight+")");
237 268

  
238
        surface.createProjection();
269
          surface.createProjection();
239 270

  
240
        int maxw = surface.mWidth  > surface.mRealWidth  ? surface.mWidth  : surface.mRealWidth;
241
        int maxh = surface.mHeight > surface.mRealHeight ? surface.mHeight : surface.mRealHeight;
271
          int maxw = surface.mWidth  > surface.mRealWidth  ? surface.mWidth  : surface.mRealWidth;
272
          int maxh = surface.mHeight > surface.mRealHeight ? surface.mHeight : surface.mRealHeight;
242 273

  
243
        if (maxw > surface.mRealWidth || maxh > surface.mRealHeight)
244
          {
245
          surface.mRealWidth = maxw;
246
          surface.mRealHeight = maxh;
274
          if (maxw > surface.mRealWidth || maxh > surface.mRealHeight)
275
            {
276
            surface.mRealWidth = maxw;
277
            surface.mRealHeight = maxh;
247 278

  
248
          surface.recreate();
249
          surface.create();
279
            surface.recreate();
280
            surface.create();
281
            }
250 282
          }
251 283
        }
252 284
      }
......
288 320
    }
289 321

  
290 322
///////////////////////////////////////////////////////////////////////////////////////////////////
291
// two phases: 1. collapse the SSBO 2. blend the ssbo's color
323
// two phases: 1. collapse the SSBO 2. blend the SSBO's color
292 324

  
293 325
  private int oitRender(long currTime)
294 326
    {
......
318 350

  
319 351
///////////////////////////////////////////////////////////////////////////////////////////////////
320 352

  
321
  private static void clearBuffer(DistortedOutputSurface buffer)
353
  private static void clearPostprocessingBuffer(int quality)
322 354
    {
323 355
    GLES31.glStencilMask(0xff);
324 356
    GLES31.glDepthMask(true);
......
327 359
    GLES31.glClearDepthf(1.0f);
328 360
    GLES31.glClearStencil(0);
329 361

  
330
    buffer.setAsOutput();
331
    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[buffer.mNumColors-1], 0);
362
    mBuffer[quality][0].setAsOutput();
332 363
    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
333 364

  
334
    for(int i=buffer.mNumColors-2; i>=0; i--)
365
    for(int j=1; j<PING_PONG; j++)
335 366
      {
336
      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[i], 0);
367
      mBuffer[quality][j].setAsOutput();
337 368
      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
338 369
      }
339 370
    }
......
375 406
        }
376 407
      else
377 408
        {
378
        if( mBuffer[0]==null ) createPostprocessingBuffers(mWidth,mHeight,mNear);
409
        if( mBuffer==null ) createPostprocessingBuffers(mWidth,mHeight,mNear);
379 410

  
380 411
        if( lastBucket!=currBucket )
381 412
          {
......
389 420
            for(int j=bucketChange; j<i; j++)
390 421
              {
391 422
              child2 = children.get(j);
392
              numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],lastQueue);
423
              numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality][0],lastQueue);
393 424
              }
394 425

  
395 426
            numRenders += lastQueue.postprocess(mBuffer);
396
            numRenders += oitBuild(mBuffer[quality]);
427
            numRenders += oitBuild(mBuffer[quality][0]);
397 428
            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
398
            clearBuffer(mBuffer[quality]);
429
            clearPostprocessingBuffer(quality);
399 430
            }
400 431

  
401 432
          internalQuality = currQueue.getInternalQuality();
......
403 434
          bucketChange    = i;
404 435
          }
405 436

  
406
        mBuffer[quality].setAsOutput(time);
407
        child1.drawNoBlend(time,mBuffer[quality]);
437
        mBuffer[quality][0].setAsOutput(time);
438
        child1.drawNoBlend(time,mBuffer[quality][0]);
408 439

  
409 440
        if( i==numChildren-1 )
410 441
          {
411 442
          for(int j=bucketChange; j<numChildren; j++)
412 443
            {
413 444
            child2 = children.get(j);
414
            numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],currQueue);
445
            numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality][0],currQueue);
415 446
            }
416 447

  
417 448
          numRenders += currQueue.postprocess(mBuffer);
418
          numRenders += oitBuild(mBuffer[quality]);
449
          numRenders += oitBuild(mBuffer[quality][0]);
419 450
          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
420 451
          numRenders += oitRender(time);  // merge the OIT linked list
421
          clearBuffer(mBuffer[quality]);
452
          clearPostprocessingBuffer(quality);
422 453
          }
423 454
        } // end else (postprocessed child)
424 455

  

Also available in: Unified diff