Revert "#improve node sort performance by std::sort + long long (_localZOrder) for 64-bit" (#16260)

This commit is contained in:
minggo 2016-07-29 10:58:31 +08:00 committed by GitHub
parent adf9e80bd7
commit 88eb533f9d
4 changed files with 15 additions and 57 deletions

View File

@ -57,17 +57,9 @@ NS_CC_BEGIN
bool nodeComparisonLess(Node* n1, Node* n2) bool nodeComparisonLess(Node* n1, Node* n2)
{ {
#if defined(_M_X64) || defined(_LP64) || defined(__x86_64) || defined(_WIN64) return( n1->getLocalZOrder() < n2->getLocalZOrder() );
return (n1->_localZOrder.value < n2->_localZOrder.value);
#else
return n1->_localZOrder.detail.z < n2->_localZOrder.detail.z ||
(n1->_localZOrder.detail.z == n2->_localZOrder.detail.z && n1->_localZOrder.detail.a < n2->_localZOrder.detail.a);
#endif
} }
// FIXME:: Yes, nodes might have a sort problem once every 30 days if the game runs at 60 FPS and each frame sprites are reordered.
unsigned int Node::s_globalOrderOfArrival = 0;
// MARK: Constructor, Destructor, Init // MARK: Constructor, Destructor, Init
Node::Node() Node::Node()
@ -92,6 +84,7 @@ Node::Node()
, _transformUpdated(true) , _transformUpdated(true)
// children (lazy allocs) // children (lazy allocs)
// lazy alloc // lazy alloc
, _localZOrder(0)
, _globalZOrder(0) , _globalZOrder(0)
, _parent(nullptr) , _parent(nullptr)
// "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true
@ -122,8 +115,6 @@ Node::Node()
, _physicsBody(nullptr) , _physicsBody(nullptr)
#endif #endif
{ {
_localZOrder.value = 0;
// set default scheduler and actionManager // set default scheduler and actionManager
_director = Director::getInstance(); _director = Director::getInstance();
_actionManager = _director->getActionManager(); _actionManager = _director->getActionManager();
@ -263,10 +254,10 @@ void Node::setSkewY(float skewY)
void Node::setLocalZOrder(int z) void Node::setLocalZOrder(int z)
{ {
if (getLocalZOrder() == z) if (_localZOrder == z)
return; return;
_setLocalZOrder(z); _localZOrder = z;
if (_parent) if (_parent)
{ {
_parent->reorderChild(this, z); _parent->reorderChild(this, z);
@ -279,12 +270,7 @@ void Node::setLocalZOrder(int z)
/// used internally to alter the zOrder variable. DON'T call this method manually /// used internally to alter the zOrder variable. DON'T call this method manually
void Node::_setLocalZOrder(int z) void Node::_setLocalZOrder(int z)
{ {
_localZOrder.detail.z = z; _localZOrder = z;
}
void Node::updateOrderOfArrival()
{
_localZOrder.detail.a = s_globalOrderOfArrival++;
} }
void Node::setGlobalZOrder(float globalZOrder) void Node::setGlobalZOrder(float globalZOrder)
@ -964,8 +950,6 @@ void Node::addChildHelper(Node* child, int localZOrder, int tag, const std::stri
child->setParent(this); child->setParent(this);
child->setCameraMask(getCameraMask()); child->setCameraMask(getCameraMask());
child->updateOrderOfArrival();
if( _running ) if( _running )
{ {
child->onEnter(); child->onEnter();
@ -996,7 +980,7 @@ void Node::addChild(Node *child, int zOrder)
void Node::addChild(Node *child) void Node::addChild(Node *child)
{ {
CCASSERT( child != nullptr, "Argument must be non-nil"); CCASSERT( child != nullptr, "Argument must be non-nil");
this->addChild(child, child->_localZOrder.detail.z, child->_name); this->addChild(child, child->_localZOrder, child->_name);
} }
void Node::removeFromParent() void Node::removeFromParent()
@ -1143,22 +1127,21 @@ void Node::insertChild(Node* child, int z)
_transformUpdated = true; _transformUpdated = true;
_reorderChildDirty = true; _reorderChildDirty = true;
_children.pushBack(child); _children.pushBack(child);
child->_setLocalZOrder(z); child->_localZOrder = z;
} }
void Node::reorderChild(Node *child, int zOrder) void Node::reorderChild(Node *child, int zOrder)
{ {
CCASSERT( child != nullptr, "Child must be non-nil"); CCASSERT( child != nullptr, "Child must be non-nil");
_reorderChildDirty = true; _reorderChildDirty = true;
child->updateOrderOfArrival(); child->_localZOrder = zOrder;
child->_setLocalZOrder(zOrder);
} }
void Node::sortAllChildren() void Node::sortAllChildren()
{ {
if (_reorderChildDirty) if (_reorderChildDirty)
{ {
std::sort(std::begin(_children), std::end(_children), nodeComparisonLess); std::stable_sort(std::begin(_children), std::end(_children), nodeComparisonLess);
_reorderChildDirty = false; _reorderChildDirty = false;
} }
} }
@ -1251,7 +1234,7 @@ void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t paren
{ {
auto node = _children.at(i); auto node = _children.at(i);
if (node && node->_localZOrder.detail.z < 0) if (node && node->_localZOrder < 0)
node->visit(renderer, _modelViewTransform, flags); node->visit(renderer, _modelViewTransform, flags);
else else
break; break;

View File

@ -29,7 +29,6 @@
#ifndef __CCNODE_H__ #ifndef __CCNODE_H__
#define __CCNODE_H__ #define __CCNODE_H__
#include <cstdint>
#include "base/ccMacros.h" #include "base/ccMacros.h"
#include "base/CCVector.h" #include "base/CCVector.h"
#include "base/CCProtocols.h" #include "base/CCProtocols.h"
@ -109,7 +108,6 @@ class EventListener;
class CC_DLL Node : public Ref class CC_DLL Node : public Ref
{ {
friend bool nodeComparisonLess(Node* n1, Node* n2);
public: public:
/** Default tag used for all the nodes */ /** Default tag used for all the nodes */
static const int INVALID_TAG = -1; static const int INVALID_TAG = -1;
@ -170,18 +168,6 @@ public:
*/ */
CC_DEPRECATED_ATTRIBUTE virtual void _setLocalZOrder(int z); CC_DEPRECATED_ATTRIBUTE virtual void _setLocalZOrder(int z);
/** !!! ONLY FOR INTERNAL USE
* Sets the arrival order when this node has a same ZOrder with other children.
*
* A node which called addChild subsequently will take a larger arrival order,
* If two children have the same Z order, the child with larger arrival order will be drawn later.
*
* @warning This method is used internally for localZOrder sorting, don't change this manually
*
* @param orderOfArrival The arrival order.
*/
void updateOrderOfArrival();
/** /**
* Gets the local Z order of this node. * Gets the local Z order of this node.
* *
@ -189,7 +175,7 @@ public:
* *
* @return The local (relative to its siblings) Z order. * @return The local (relative to its siblings) Z order.
*/ */
virtual int getLocalZOrder() const { return _localZOrder.detail.z; } virtual int getLocalZOrder() const { return _localZOrder; }
CC_DEPRECATED_ATTRIBUTE virtual int getZOrder() const { return getLocalZOrder(); } CC_DEPRECATED_ATTRIBUTE virtual int getZOrder() const { return getLocalZOrder(); }
/** /**
@ -1895,17 +1881,9 @@ protected:
mutable bool _additionalTransformDirty; ///< transform dirty ? mutable bool _additionalTransformDirty; ///< transform dirty ?
bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame bool _transformUpdated; ///< Whether or not the Transform object was updated since the last frame
union { int _localZOrder; ///< Local order (relative to its siblings) used to sort the node
struct {
std::int32_t z; // The original localZOrder
std::uint32_t a; // Order Of Arrival, for avoid sort problem with unstable_sort algorithm.
} detail;
std::int64_t value; // The value to be used in sort
} _localZOrder; ///< Local order (relative to its siblings) used to sort the node
float _globalZOrder; ///< Global order used to sort the node float _globalZOrder; ///< Global order used to sort the node
static unsigned int s_globalOrderOfArrival;
Vector<Node*> _children; ///< array of children nodes Vector<Node*> _children; ///< array of children nodes
Node *_parent; ///< weak reference to parent node Node *_parent; ///< weak reference to parent node
Director* _director; //cached director pointer to improve rendering performance Director* _director; //cached director pointer to improve rendering performance

View File

@ -103,8 +103,6 @@ void ProtectedNode::addProtectedChild(Node *child, int zOrder, int tag)
child->setParent(this); child->setParent(this);
child->updateOrderOfArrival();
if( _running ) if( _running )
{ {
child->onEnter(); child->onEnter();
@ -254,7 +252,7 @@ void ProtectedNode::insertProtectedChild(cocos2d::Node *child, int z)
void ProtectedNode::sortAllProtectedChildren() void ProtectedNode::sortAllProtectedChildren()
{ {
if( _reorderProtectedChildDirty ) { if( _reorderProtectedChildDirty ) {
std::sort( std::begin(_protectedChildren), std::end(_protectedChildren), nodeComparisonLess ); std::stable_sort( std::begin(_protectedChildren), std::end(_protectedChildren), nodeComparisonLess );
_reorderProtectedChildDirty = false; _reorderProtectedChildDirty = false;
} }
} }
@ -263,7 +261,6 @@ void ProtectedNode::reorderProtectedChild(cocos2d::Node *child, int localZOrder)
{ {
CCASSERT( child != nullptr, "Child must be non-nil"); CCASSERT( child != nullptr, "Child must be non-nil");
_reorderProtectedChildDirty = true; _reorderProtectedChildDirty = true;
child->updateOrderOfArrival();
child->setLocalZOrder(localZOrder); child->setLocalZOrder(localZOrder);
} }

View File

@ -143,7 +143,7 @@ void Bone::setBoneData(BoneData *boneData)
} }
_name = _boneData->name; _name = _boneData->name;
_setLocalZOrder(_boneData->zOrder); _localZOrder = _boneData->zOrder;
_displayManager->initDisplayList(boneData); _displayManager->initDisplayList(boneData);
} }
@ -377,7 +377,7 @@ Tween *Bone::getTween()
void Bone::setLocalZOrder(int zOrder) void Bone::setLocalZOrder(int zOrder)
{ {
if (getLocalZOrder() != zOrder) if (_localZOrder != zOrder)
Node::setLocalZOrder(zOrder); Node::setLocalZOrder(zOrder);
} }