Skip to content

Conversation

@1scaR1
Copy link
Contributor

@1scaR1 1scaR1 commented Mar 31, 2016

  • remove calling of very heavy function gl.GetParameter
  • clear depth & stencil buffer by gl.clear
  • use stencilOp gl.REPLACE on before draw stencil

This patch improves performance of stencil clipping in web GL Render. It passes all clipping tests.

Here performance compare in scene with ccui.ScrollView and 5 ccui.Layouts with clipping enabled in it(In Google Chrome browser, Core i7 Processor, GeForce 750M graphics):

  • Before(first Task Manager of Chrome for game tab, second CPU profiler):

2016-03-31 12 08 13
2016-03-31 12 08 58

  • After(first Task Manager of Chrome for game tab, second CPU profiler):

2016-03-31 12 13 13
2016-03-31 12 13 43

1scaR1 added 2 commits March 31, 2016 12:05
-remove calling of where heavy function gl.GetParameter
-clear depth & stencil buffer by gl.clear
-use stencil g.REPLACE on before draw stencil
@pandamicro
Copy link
Contributor

Thank you ! I will test it with more mobile devices.

@dabingnn
Copy link
Contributor

dabingnn commented Apr 7, 2016

@1scaR1 Thanks.

My proposal is that we can replace _drawFullScreenQuadClearStencil by using glClear and stencil/color buffer mask, which is more straightforward. I don't know the performance between these two methods.

For removing cached _currentStencilXXXX, I did not understand your idea very clearly. How could we make the render state restore back safely? In my opinion, if our user call openGL functions stencilOP/stencilFunc manually, this code is not safe.

@1scaR1
Copy link
Contributor Author

1scaR1 commented Apr 7, 2016

@dabingnn,
1.Removing _drawFullScreenQuadClearStencil is only for clear code purpose.
2. The main reason, why caching of stencil function is useless now is that:
If user wants to use stencilOp/stencilFunc manually, he must inspect code of Layout/ClippingNode render cmd's, because it uses depth masks and user must carefully track collisions with engine code. It's very hard to use gl functions manually now.

So, in my opinion, there are two ways to solve this:

1.Warn users about using of gl stencil functions in clipping nodes
2.Make ClippingNode more flexible : add functions to set params of gl stencil operations, and user will use it as a wrapper for direct calls to WebGL and it will not destruct logic of clipping.(I can implement it in this PR).

What do you think about it?

@pandamicro
Copy link
Contributor

Thank you guys for your feedbacks. A small note, in Cocos2d-html5, we have never encourage user to use gl functions, our rendering process is not so flexible, unfortunately.

@dabingnn
Copy link
Contributor

dabingnn commented Apr 7, 2016

@pandamicro
If we suppress these usage, I think we can remove cached state for stencil code.

Let's confirm if we allow user to do this:
user may use a clipping node, add some nodes as the content, which may derived from cc.Node and call gl functions for its drawing, so glStencilXXX function maybe called. How do we solve this?

1.Warn users about using of gl stencil functions in clipping nodes

this solution will not works well.

2.Make ClippingNode more flexible : ....

@1scaR1 I did not get your idea, did you mean wrap those cached codes?

@1scaR1
Copy link
Contributor Author

1scaR1 commented Apr 7, 2016

@dabingnn,
In cocos2d-html5 we can not simple override visit function to use one gl functions, we must create RenderCmd's derived from cc.Node.XXXRenverCmd(Canvas an WebGL).
If user will use WebGL functions in his render cmd's, he must watch if they would't break the engine logic, for example:
User adds his custom node with gl stencil functions to ClippingNode, then the render stack will be:
_onBeforeVisitStencil(Here we have stencilMask 1) // Current state is saved
// draw stencil
..
_onAfterDrawStencil
//Here user's node code somewhere deeper in stack, where he uses stencilMask 1 too.
//I think, he will have some mess on screen.
...
_onAfterVisitStencil //Only now previous state is restored

I offer to add functions to ClippingNode like setStenctilFunc, setStecilOp that will affect it's render cmd, properly call WebGl functions and work correctly with stencil masks.
User will use it or derive from it to make his own clipping preferences for his game.

@pandamicro
Copy link
Contributor

I offer to add functions to ClippingNode like setStenctilFunc, setStecilOp that will affect it's render cmd and work correctly with stencil masks.

I think user can manage it when they extend our rendering process, adding two more APIs doesn't mean they will know how to use.

I will merge this PR because the performance can benefit a lot from it, and clipping node is especially useful in UI system. As the rendering process isn't in the official API set, the ability of extending it may suffer a little, but I think it worth. Thank you for your contribution. @1scaR1

@pandamicro pandamicro merged commit 7283fde into cocos2d:develop Apr 7, 2016
@1scaR1 1scaR1 mentioned this pull request Apr 8, 2016
@1scaR1 1scaR1 deleted the webgl_clipping branch April 8, 2016 13:54
@pandamicro
Copy link
Contributor

@1scaR1 I found an issue of multiple layout usage, my scene looks like this.

1

So the problem is that layouts are also clipping contents in previous layouts

@1scaR1
Copy link
Contributor Author

1scaR1 commented Apr 12, 2016

I think , I,be fixed it in #3260. Issue was with restoring of clipping state after drawing of layout

@pandamicro
Copy link
Contributor

Yes, sorry, I was using a branch not fully updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants