Revision 2dbed690
Added by Leszek Koltunski almost 6 years ago
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
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.