Revision 586b5fa1
Added by Leszek Koltunski over 6 years ago
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 | ||
---|---|---|
78 | 78 |
*/ |
79 | 79 |
public static final int CLONE_CHILDREN= 0x20; |
80 | 80 |
|
81 |
/** |
|
82 |
* Work around bugs in ARM Mali driver by, instead to a single FBO, rendering to a circular queue |
|
83 |
* of FBO_QUEUE_SIZE FBOs. (otherwise we sometimes get a 'full pipeline flush' and the end result |
|
84 |
* might be missing part of the Objects) |
|
85 |
*/ |
|
86 |
public static final int FBO_QUEUE_SIZE = 4; |
|
87 |
|
|
81 | 88 |
private static boolean mInitialized=false; |
82 | 89 |
|
83 | 90 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
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 | ||
---|---|---|
179 | 179 |
|
180 | 180 |
for (int j=0; j<EffectQuality.LENGTH; j++) |
181 | 181 |
{ |
182 |
mBuffer[j] = new DistortedFramebuffer(2, BOTH_DEPTH_STENCIL, TYPE_SYST, (int) (width * mipmap), (int) (height * mipmap));
|
|
182 |
mBuffer[j] = new DistortedFramebuffer(Distorted.FBO_QUEUE_SIZE,2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
|
|
183 | 183 |
mBuffer[j].mMipmap = mipmap; |
184 | 184 |
mBuffer[j].mNear = near; // copy mNear as well (for blitting- see PostprocessEffect.apply() ) |
185 | 185 |
mBuffer[j].glClearColor(1.0f, 1.0f, 1.0f, 0.0f); |
... | ... | |
198 | 198 |
|
199 | 199 |
for (int j=0; j<EffectQuality.LENGTH; j++) |
200 | 200 |
{ |
201 |
mBuffer[j].setAsOutput(); |
|
202 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[1], 0); |
|
203 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT); |
|
204 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[0], 0); |
|
205 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT); |
|
201 |
for(int k=0; k<Distorted.FBO_QUEUE_SIZE; k++) |
|
202 |
{ |
|
203 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBuffer[j].mFBOH[k]); |
|
204 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k+1], 0); |
|
205 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT); |
|
206 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k ], 0); |
|
207 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT); |
|
208 |
} |
|
206 | 209 |
} |
210 |
|
|
211 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
207 | 212 |
} |
208 | 213 |
|
209 | 214 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
270 | 275 |
private int oitBuild(long time, DistortedOutputSurface buffer, int fbo) |
271 | 276 |
{ |
272 | 277 |
GLES31.glViewport(0, 0, mWidth, mHeight); |
273 |
setAsOutput(time,fbo); |
|
278 |
setAsOutputFBO(time,fbo);
|
|
274 | 279 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE0); |
275 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
|
|
280 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]);
|
|
276 | 281 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE1); |
277 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
|
|
282 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[fbo]);
|
|
278 | 283 |
|
279 | 284 |
DistortedRenderState.colorDepthStencilOn(); |
280 | 285 |
DistortedRenderState.enableDepthTest(); |
... | ... | |
322 | 327 |
|
323 | 328 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
324 | 329 |
|
325 |
private static void clearBuffer(DistortedOutputSurface buffer) |
|
330 |
private static void clearBuffer(DistortedOutputSurface buffer, int fbo)
|
|
326 | 331 |
{ |
327 | 332 |
GLES31.glStencilMask(0xff); |
328 | 333 |
GLES31.glDepthMask(true); |
... | ... | |
331 | 336 |
GLES31.glClearDepthf(1.0f); |
332 | 337 |
GLES31.glClearStencil(0); |
333 | 338 |
|
334 |
buffer.setAsOutput();
|
|
335 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[buffer.mNumColors-1], 0);
|
|
339 |
buffer.setAsOutputFBO(fbo);
|
|
340 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo+1], 0);
|
|
336 | 341 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT); |
342 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo ], 0); |
|
343 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT); |
|
337 | 344 |
|
338 | 345 |
for(int i=buffer.mNumColors-2; i>=0; i--) |
339 | 346 |
{ |
... | ... | |
374 | 381 |
|
375 | 382 |
if( currBucket==0 ) |
376 | 383 |
{ |
377 |
setAsOutput(time,fbo); |
|
384 |
setAsOutputFBO(time,fbo);
|
|
378 | 385 |
numRenders += child1.draw(time,this); |
379 | 386 |
} |
380 | 387 |
else |
... | ... | |
393 | 400 |
for(int j=bucketChange; j<i; j++) |
394 | 401 |
{ |
395 | 402 |
child2 = children.get(j); |
403 |
mBuffer[internalQuality].setAsOutputFBO(fbo); |
|
396 | 404 |
numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],lastQueue); |
397 | 405 |
} |
398 | 406 |
|
399 |
numRenders += lastQueue.postprocess(mBuffer); |
|
407 |
numRenders += lastQueue.postprocess(mBuffer,fbo);
|
|
400 | 408 |
numRenders += oitBuild(time,mBuffer[quality],fbo); |
401 | 409 |
GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT); |
402 |
clearBuffer(mBuffer[quality]); |
|
403 |
|
|
410 |
clearBuffer(mBuffer[quality],fbo); |
|
404 | 411 |
} |
405 | 412 |
|
406 | 413 |
internalQuality = currQueue.getInternalQuality(); |
... | ... | |
408 | 415 |
bucketChange = i; |
409 | 416 |
} |
410 | 417 |
|
411 |
mBuffer[quality].setAsOutput(time);
|
|
418 |
mBuffer[quality].setAsOutputFBO(time,fbo);
|
|
412 | 419 |
child1.drawNoBlend(time,mBuffer[quality]); |
413 | 420 |
|
414 | 421 |
if( i==numChildren-1 ) |
... | ... | |
416 | 423 |
for(int j=bucketChange; j<numChildren; j++) |
417 | 424 |
{ |
418 | 425 |
child2 = children.get(j); |
426 |
mBuffer[internalQuality].setAsOutputFBO(fbo); |
|
419 | 427 |
numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],currQueue); |
420 | 428 |
} |
421 | 429 |
|
422 |
numRenders += currQueue.postprocess(mBuffer); |
|
430 |
numRenders += currQueue.postprocess(mBuffer,fbo);
|
|
423 | 431 |
numRenders += oitBuild(time,mBuffer[quality],fbo); |
424 | 432 |
GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT); |
425 | 433 |
numRenders += oitRender(time); // merge the OIT linked list |
426 |
clearBuffer(mBuffer[quality]); |
|
434 |
clearBuffer(mBuffer[quality],fbo);
|
|
427 | 435 |
} |
428 | 436 |
} // end else (postprocessed child) |
429 | 437 |
|
... | ... | |
465 | 473 |
|
466 | 474 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
467 | 475 |
|
468 |
private void setAsOutput(long time, int fbo) |
|
476 |
private void setAsOutputFBO(long time, int fbo)
|
|
469 | 477 |
{ |
470 | 478 |
if( fbo>=0 && fbo<mNumFBOs ) |
471 | 479 |
{ |
... | ... | |
479 | 487 |
} |
480 | 488 |
else |
481 | 489 |
{ |
482 |
android.util.Log.e("surface", "error in setAsOutput, fbo="+fbo); |
|
490 |
android.util.Log.e("surface", "error in setAsOutput1, fbo="+fbo); |
|
491 |
} |
|
492 |
} |
|
493 |
|
|
494 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
495 |
/** |
|
496 |
* Not part of the Public API. |
|
497 |
* |
|
498 |
* @y.exclude |
|
499 |
*/ |
|
500 |
public void setAsOutputFBO(int fbo) |
|
501 |
{ |
|
502 |
if( fbo>=0 && fbo<mNumFBOs ) |
|
503 |
{ |
|
504 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]); |
|
505 |
} |
|
506 |
else |
|
507 |
{ |
|
508 |
android.util.Log.e("surface", "error in setAsOutput2, fbo="+fbo); |
|
483 | 509 |
} |
484 | 510 |
} |
485 | 511 |
|
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
Port another commit from master.
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.