Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize the performance of zIndex when there are a large number of nodes. #5701

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions EngineErrorMap.md
Expand Up @@ -2715,3 +2715,7 @@ LabelAtlas '%s' cannot be loaded, raw texture does not exist.
### 9101

LabelAtlas '%s' cannot be loaded, fnt data does not exist.

### 9102

Program not support highp precision, will change to mediump.
47 changes: 19 additions & 28 deletions cocos2d/core/CCNode.js
Expand Up @@ -814,9 +814,11 @@ let NodeDefines = {
* !#en
* Group of node.<br/>
* Which Group this node belongs to will resolve that this node's collision components can collide with which other collision componentns.<br/>
* When adding a child node to a father node, child node's group will be set same as father node's group.<br/>
* !#zh
* 节点的分组。<br/>
* 节点的分组将关系到节点的碰撞组件可以与哪些碰撞组件相碰撞。<br/>
* 子节点在被加入到父节点时 group 会与父节点同步。<br/>
* @property group
* @type {String}
*/
Expand Down Expand Up @@ -1459,13 +1461,7 @@ let NodeDefines = {
this._localZOrder = (this._localZOrder & 0x0000ffff) | (value << 16);
this.emit(EventType.SIBLING_ORDER_CHANGED);

if (this._parent) {
this._onSiblingIndexChanged();
}
}

if (CC_JSB && CC_NATIVERENDERER) {
this._proxy.updateZOrder();
holycanvas marked this conversation as resolved.
Show resolved Hide resolved
this._onSiblingIndexChanged();
}
}
},
Expand Down Expand Up @@ -1537,14 +1533,9 @@ let NodeDefines = {

_onSiblingIndexChanged () {
// update rendering scene graph, sort them by arrivalOrder
var parent = this._parent;
var siblings = parent._children;
var i = 0, len = siblings.length, sibling;
for (; i < len; i++) {
sibling = siblings[i];
sibling._updateOrderOfArrival();
if (this._parent) {
this._parent._delaySort();
}
jareguo marked this conversation as resolved.
Show resolved Hide resolved
parent._delaySort();
},

_onPreDestroy () {
Expand Down Expand Up @@ -3475,16 +3466,7 @@ let NodeDefines = {
_updateOrderOfArrival () {
var arrivalOrder = this._parent ? ++this._parent._childArrivalOrder : 0;
this._localZOrder = (this._localZOrder & 0xffff0000) | arrivalOrder;
// redistribute
if (arrivalOrder === 0x0000ffff) {
var siblings = this._parent._children;

siblings.forEach(function (node, index) {
node._localZOrder = (node._localZOrder & 0xffff0000) | (index + 1);
});

this._parent._childArrivalOrder = siblings.length;
}

this.emit(EventType.SIBLING_ORDER_CHANGED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前调用到 _updateOrderOfArrival 的地方好像都不需要触发这个事件了。主要是 sortAllChildren、_onHierarchyChanged(也会调用 sortAllChildren)、_onBatchCreated(场景加载过程中不需要触发事件)。所以建议在 sortAllChildren 的过程中再触发 SIBLING_ORDER_CHANGED

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

赞同

},

Expand Down Expand Up @@ -3549,16 +3531,25 @@ let NodeDefines = {
*/
sortAllChildren () {
if (this._reorderChildDirty) {

this._reorderChildDirty = false;

// delay update arrivalOrder before sort children
var _children = this._children, child;
this._parent && (this._parent._childArrivalOrder = 1);
for (let i = 0, len = _children.length; i < len; i++) {
child = _children[i];
child._updateOrderOfArrival();
}

// Optimize reordering event code to fix problems with setting zindex
// https://github.com/cocos-creator/2d-tasks/issues/1186
eventManager._setDirtyForNode(this);

this._reorderChildDirty = false;
var _children = this._children;
if (_children.length > 1) {
// insertion sort
var len = _children.length, i, j, child;
for (i = 1; i < len; i++) {
var j, child;
for (let i = 1, len = _children.length; i < len; i++) {
child = _children[i];
j = i - 1;

Expand Down
2 changes: 1 addition & 1 deletion cocos2d/core/assets/material/material-pool.js
Expand Up @@ -39,7 +39,7 @@ class MaterialPool extends Pool {
}

put (mat) {
if (!this.enabled) {
if (!this.enabled || !mat._owner) {
return;
}

Expand Down
2 changes: 2 additions & 0 deletions cocos2d/core/node-activator.js
Expand Up @@ -187,7 +187,9 @@ var NodeActivator = cc.Class({
--originCount;
}
}

node._childArrivalOrder = node._children.length;

// activate children recursively
for (let i = 0, len = node._children.length; i < len; ++i) {
let child = node._children[i];
Expand Down
6 changes: 5 additions & 1 deletion cocos2d/core/platform/CCSys.js
Expand Up @@ -822,7 +822,11 @@ function initSys () {
osMainVersion = parseInt(osVersion) || 0;
}
// refer to https://github.com/cocos-creator/engine/pull/5542 , thanks for contribition from @krapnikkk
else if (/(iPhone|iPad|iPod|MacIntel)/.exec(nav.platform)) {
// ipad OS 13 safari identifies itself as "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)"
// so use maxTouchPoints to check whether it's desktop safari or not.
// reference: https://stackoverflow.com/questions/58019463/how-to-detect-device-name-in-safari-on-ios-13-while-it-doesnt-show-the-correct
// FIXME: should remove it when touch-enabled macs are available
else if (/(iPhone|iPad|iPod)/.exec(nav.platform) || (nav.platform === 'MacIntel' && nav.maxTouchPoints && nav.maxTouchPoints > 1)) {
iOS = true;
osVersion = '';
osMainVersion = 0;
Expand Down
28 changes: 28 additions & 0 deletions cocos2d/renderer/core/program-lib.js
Expand Up @@ -63,6 +63,10 @@ function _unrollLoops(string) {
return string.replace(pattern, replace);
}

function _replaceHighp(string) {
return string.replace(/\bhighp\b/g, 'mediump');
}

export default class ProgramLib {
/**
* @param {gfx.Device} device
Expand All @@ -73,6 +77,8 @@ export default class ProgramLib {
// register templates
this._templates = {};
this._cache = {};

this._checkPrecision();
}

clear () {
Expand Down Expand Up @@ -228,8 +234,15 @@ export default class ProgramLib {
let customDef = _generateDefines(defineList);
let vert = _replaceMacroNums(tmpl.vert, defineList);
vert = customDef + _unrollLoops(vert);
if (!this._highpSupported) {
vert = _replaceHighp(vert);
}

let frag = _replaceMacroNums(tmpl.frag, defineList);
frag = customDef + _unrollLoops(frag);
if (!this._highpSupported) {
frag = _replaceHighp(frag);
}

program = new gfx.Program(this._device, {
vert,
Expand Down Expand Up @@ -266,4 +279,19 @@ export default class ProgramLib {
}
}
}

_checkPrecision () {
let gl = this._device._gl;
let highpSupported = false;
if (gl.getShaderPrecisionFormat) {
let vertHighp = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT);
let fragHighp = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT);
highpSupported = (vertHighp && vertHighp.precision > 0) &&
(fragHighp && fragHighp.precision > 0);
}
if (!highpSupported) {
cc.warnID(9102);
}
this._highpSupported = highpSupported;
}
}