mirror of https://github.com/axmolengine/axmol.git
Add a pool for GroupCommand rendering commands (#969)
* Committing genbindings changes * Use a pool of GroupCommand entries to avoid multiple entries of the same group in the render queue in certain scenarios * Ensure captureNode works as expected. * Set member variables to default values when init method is called on the GroupCommand * Explicitly reset the command state when retrieving a GroupCommand from the pool
This commit is contained in:
parent
ed4d2251df
commit
2e30b51ab7
|
@ -164,14 +164,14 @@ void CameraBackgroundDepthBrush::initBuffer()
|
|||
|
||||
void CameraBackgroundDepthBrush::drawBackground(Camera* /*camera*/)
|
||||
{
|
||||
auto* renderer = Director::getInstance()->getRenderer();
|
||||
// `clear screen` should be executed before other commands
|
||||
_groupCommand.init(-1.0f);
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
groupCommand->init(-1.0f);
|
||||
_customCommand.init(0.0f);
|
||||
|
||||
auto* renderer = Director::getInstance()->getRenderer();
|
||||
|
||||
renderer->addCommand(&_groupCommand);
|
||||
renderer->pushGroup(_groupCommand.getRenderQueueID());
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
|
||||
auto& blend = pipelineDescriptor.blendDescriptor;
|
||||
|
@ -337,8 +337,10 @@ CameraBackgroundSkyBoxBrush* CameraBackgroundSkyBoxBrush::create()
|
|||
|
||||
void CameraBackgroundSkyBoxBrush::drawBackground(Camera* camera)
|
||||
{
|
||||
auto* renderer = Director::getInstance()->getRenderer();
|
||||
// `clear screen` should be executed before other commands
|
||||
_groupCommand.init(-1.0f);
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
groupCommand->init(-1.0f);
|
||||
_customCommand.init(0.0f);
|
||||
|
||||
if (!_actived)
|
||||
|
@ -355,10 +357,9 @@ void CameraBackgroundSkyBoxBrush::drawBackground(Camera* camera)
|
|||
_programState->setUniform(_uniformColorLoc, &color, sizeof(color));
|
||||
_programState->setUniform(_uniformCameraRotLoc, cameraModelMat.m, sizeof(cameraModelMat.m));
|
||||
|
||||
auto* renderer = Director::getInstance()->getRenderer();
|
||||
|
||||
renderer->addCommand(&_groupCommand);
|
||||
renderer->pushGroup(_groupCommand.getRenderQueueID());
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
renderer->addCommand(&_customCommand);
|
||||
|
||||
|
|
|
@ -176,7 +176,6 @@ protected:
|
|||
float _depth;
|
||||
backend::UniformLocation _locDepth;
|
||||
CustomCommand _customCommand;
|
||||
GroupCommand _groupCommand;
|
||||
|
||||
bool _clearColor;
|
||||
std::vector<V3F_C4B_T2F> _vertices;
|
||||
|
@ -307,7 +306,6 @@ private:
|
|||
bool _textureValid;
|
||||
|
||||
CustomCommand _customCommand;
|
||||
GroupCommand _groupCommand;
|
||||
|
||||
backend::UniformLocation _uniformColorLoc;
|
||||
backend::UniformLocation _uniformCameraRotLoc;
|
||||
|
|
|
@ -147,10 +147,11 @@ void ClippingNode::visit(Renderer* renderer, const Mat4& parentTransform, uint32
|
|||
|
||||
// Add group command
|
||||
|
||||
_groupCommandStencil.init(_globalZOrder);
|
||||
renderer->addCommand(&_groupCommandStencil);
|
||||
auto* groupCommandStencil = renderer->getNextGroupCommand();
|
||||
groupCommandStencil->init(_globalZOrder);
|
||||
renderer->addCommand(groupCommandStencil);
|
||||
|
||||
renderer->pushGroup(_groupCommandStencil.getRenderQueueID());
|
||||
renderer->pushGroup(groupCommandStencil->getRenderQueueID());
|
||||
|
||||
// _beforeVisitCmd.init(_globalZOrder);
|
||||
// _beforeVisitCmd.func = AX_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencilStateManager);
|
||||
|
@ -180,10 +181,12 @@ void ClippingNode::visit(Renderer* renderer, const Mat4& parentTransform, uint32
|
|||
|
||||
// `_groupCommandChildren` is used as a barrier
|
||||
// to ensure commands above be executed before children nodes
|
||||
_groupCommandChildren.init(_globalZOrder);
|
||||
renderer->addCommand(&_groupCommandChildren);
|
||||
auto* groupCommandChildren = renderer->getNextGroupCommand();
|
||||
|
||||
renderer->pushGroup(_groupCommandChildren.getRenderQueueID());
|
||||
groupCommandChildren->init(_globalZOrder);
|
||||
renderer->addCommand(groupCommandChildren);
|
||||
|
||||
renderer->pushGroup(groupCommandChildren->getRenderQueueID());
|
||||
|
||||
if (!_children.empty())
|
||||
{
|
||||
|
|
|
@ -159,8 +159,6 @@ protected:
|
|||
Node* _stencil = nullptr;
|
||||
StencilStateManager* _stencilStateManager = nullptr;
|
||||
|
||||
GroupCommand _groupCommandStencil;
|
||||
GroupCommand _groupCommandChildren;
|
||||
//CallbackCommand _afterDrawStencilCmd;
|
||||
//CallbackCommand _afterVisitCmd;
|
||||
std::unordered_map<Node*, backend::ProgramState*> _originalStencilProgramState;
|
||||
|
|
|
@ -203,10 +203,10 @@ void GridBase::beforeDraw()
|
|||
// save projection
|
||||
Director* director = Director::getInstance();
|
||||
|
||||
auto renderer = director->getRenderer();
|
||||
|
||||
renderer->addCommand(&_groupCommand);
|
||||
renderer->pushGroup(_groupCommand.getRenderQueueID());
|
||||
auto* renderer = director->getRenderer();
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
auto beforeDrawCommandFunc = [=, this]() -> void {
|
||||
_directorProjection = director->getProjection();
|
||||
|
|
|
@ -153,7 +153,6 @@ protected:
|
|||
|
||||
Color4F _clearColor = {0, 0, 0, 0};
|
||||
|
||||
GroupCommand _groupCommand;
|
||||
CustomCommand _drawCommand;
|
||||
//CallbackCommand _beforeDrawCommand;
|
||||
//CallbackCommand _afterDrawCommand;
|
||||
|
|
|
@ -97,7 +97,6 @@ protected:
|
|||
|
||||
Node* _gridTarget = nullptr;
|
||||
GridBase* _nodeGrid = nullptr;
|
||||
GroupCommand _groupCommand;
|
||||
CustomCommand _gridBeginCommand;
|
||||
CustomCommand _gridEndCommand;
|
||||
|
||||
|
|
|
@ -611,11 +611,12 @@ void RenderTexture::begin()
|
|||
_director->multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, orthoMatrix);
|
||||
}
|
||||
|
||||
_groupCommand.init(_globalZOrder);
|
||||
|
||||
Renderer* renderer = _director->getRenderer();
|
||||
renderer->addCommand(&_groupCommand);
|
||||
renderer->pushGroup(_groupCommand.getRenderQueueID());
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
groupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
auto beginCommand = renderer->nextCallbackCommand();
|
||||
beginCommand->init(_globalZOrder);
|
||||
|
|
|
@ -413,7 +413,6 @@ protected:
|
|||
*/
|
||||
Sprite* _sprite = nullptr;
|
||||
|
||||
GroupCommand _groupCommand;
|
||||
//CallbackCommand _beginCommand;
|
||||
//CallbackCommand _endCommand;
|
||||
|
||||
|
|
|
@ -134,7 +134,8 @@ void captureNode(Node* startNode, std::function<void(RefPtr<Image>)> imageCallba
|
|||
|
||||
RenderTexture* finalRtx = nullptr;
|
||||
|
||||
auto rtx = RenderTexture::create(size.width, size.height, backend::PixelFormat::RGBA8, PixelFormat::D24S8);
|
||||
auto rtx =
|
||||
RenderTexture::create(size.width, size.height, backend::PixelFormat::RGBA8, PixelFormat::D24S8, false);
|
||||
// rtx->setKeepMatrix(true);
|
||||
Point savedPos = startNode->getPosition();
|
||||
Point anchor;
|
||||
|
@ -158,7 +159,7 @@ void captureNode(Node* startNode, std::function<void(RefPtr<Image>)> imageCallba
|
|||
sprite->setAnchorPoint(Point(0, 0));
|
||||
sprite->setFlippedY(true);
|
||||
finalRtx = RenderTexture::create(size.width * scale, size.height * scale, backend::PixelFormat::RGBA8,
|
||||
PixelFormat::D24S8);
|
||||
PixelFormat::D24S8, false);
|
||||
|
||||
sprite->setScale(scale); // or use finalRtx->setKeepMatrix(true);
|
||||
finalRtx->begin();
|
||||
|
|
|
@ -79,6 +79,16 @@ void GroupCommand::init(float globalOrder)
|
|||
_renderQueueID = manager->getGroupID();
|
||||
}
|
||||
|
||||
void GroupCommand::reset()
|
||||
{
|
||||
_globalOrder = 0.0f;
|
||||
_isTransparent = true;
|
||||
_skipBatching = false;
|
||||
_is3D = false;
|
||||
_depth = 0.0f;
|
||||
_isWireframe = false;
|
||||
}
|
||||
|
||||
GroupCommand::~GroupCommand()
|
||||
{
|
||||
Director::getInstance()->getRenderer()->getGroupCommandManager()->releaseGroupID(_renderQueueID);
|
||||
|
|
|
@ -75,6 +75,12 @@ public:
|
|||
/**called by renderer, get the group ID.*/
|
||||
int getRenderQueueID() const { return _renderQueueID; }
|
||||
|
||||
/**
|
||||
* @brief Reset the command state for reuse
|
||||
*
|
||||
*/
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
int _renderQueueID;
|
||||
};
|
||||
|
|
|
@ -176,12 +176,17 @@ Renderer::Renderer()
|
|||
Renderer::~Renderer()
|
||||
{
|
||||
_renderGroups.clear();
|
||||
_groupCommandManager->release();
|
||||
|
||||
for (auto&& clearCommand : _callbackCommandsPool)
|
||||
delete clearCommand;
|
||||
_callbackCommandsPool.clear();
|
||||
|
||||
for (auto&& clearCommand : _groupCommandPool)
|
||||
delete clearCommand;
|
||||
_groupCommandPool.clear();
|
||||
|
||||
_groupCommandManager->release();
|
||||
|
||||
free(_triBatchesToDraw);
|
||||
|
||||
AX_SAFE_RELEASE(_depthStencilState);
|
||||
|
@ -240,6 +245,20 @@ void Renderer::addCommand(RenderCommand* command, int renderQueueID)
|
|||
_renderGroups[renderQueueID].emplace_back(command);
|
||||
}
|
||||
|
||||
GroupCommand* Renderer::getNextGroupCommand()
|
||||
{
|
||||
if (_groupCommandPool.empty())
|
||||
{
|
||||
return new GroupCommand();
|
||||
}
|
||||
|
||||
auto* command = _groupCommandPool.back();
|
||||
_groupCommandPool.pop_back();
|
||||
command->reset();
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
void Renderer::pushGroup(int renderQueueID)
|
||||
{
|
||||
AXASSERT(!_isRendering, "Cannot change render queue while rendering");
|
||||
|
@ -321,6 +340,7 @@ void Renderer::processRenderCommand(RenderCommand* command)
|
|||
break;
|
||||
case RenderCommand::Type::GROUP_COMMAND:
|
||||
processGroupCommand(static_cast<GroupCommand*>(command));
|
||||
_groupCommandPool.emplace_back(static_cast<GroupCommand*>(command));
|
||||
break;
|
||||
case RenderCommand::Type::CUSTOM_COMMAND:
|
||||
flush();
|
||||
|
|
|
@ -155,6 +155,9 @@ public:
|
|||
/** Adds a `RenderComamnd` into the renderer specifying a particular render queue ID */
|
||||
void addCommand(RenderCommand* command, int renderQueueID);
|
||||
|
||||
/** Get a `GroupCommand` from a GroupCommand pool or creates a new command if the pool is empty */
|
||||
GroupCommand* getNextGroupCommand();
|
||||
|
||||
/** Pushes a group into the render queue */
|
||||
void pushGroup(int renderQueueID);
|
||||
|
||||
|
@ -507,6 +510,8 @@ protected:
|
|||
// the pool for callback commands
|
||||
std::vector<CallbackCommand*> _callbackCommandsPool;
|
||||
|
||||
std::vector<GroupCommand*> _groupCommandPool;
|
||||
|
||||
// for TrianglesCommand
|
||||
V3F_C4B_T2F _verts[VBO_SIZE];
|
||||
unsigned short _indices[INDEX_VBO_SIZE];
|
||||
|
|
|
@ -248,10 +248,10 @@ void Layout::stencilClippingVisit(Renderer* renderer, const Mat4& parentTransfor
|
|||
_director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
|
||||
// Add group command
|
||||
|
||||
_groupCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&_groupCommand);
|
||||
|
||||
renderer->pushGroup(_groupCommand.getRenderQueueID());
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
groupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
// _beforeVisitCmdStencil.init(_globalZOrder);
|
||||
// _beforeVisitCmdStencil.func = AX_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencilStateManager);
|
||||
|
@ -369,9 +369,10 @@ void Layout::scissorClippingVisit(Renderer* renderer, const Mat4& parentTransfor
|
|||
_director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||
_director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
|
||||
|
||||
_groupCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&_groupCommand);
|
||||
renderer->pushGroup(_groupCommand.getRenderQueueID());
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
groupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
auto beforeVisitCmdScissor = renderer->nextCallbackCommand();
|
||||
beforeVisitCmdScissor->init(_globalZOrder);
|
||||
|
|
|
@ -640,7 +640,6 @@ protected:
|
|||
// clipping
|
||||
StencilStateManager* _stencilStateManager;
|
||||
|
||||
GroupCommand _groupCommand;
|
||||
//CallbackCommand _beforeVisitCmdStencil;
|
||||
//CallbackCommand _afterDrawStencilCmd;
|
||||
//CallbackCommand _afterVisitCmdStencil;
|
||||
|
|
|
@ -43,10 +43,9 @@ BatchNode* BatchNode::create()
|
|||
AX_SAFE_DELETE(batchNode);
|
||||
return nullptr;
|
||||
}
|
||||
BatchNode::BatchNode() : _groupCommand(nullptr) {}
|
||||
BatchNode::BatchNode() /*: _groupCommand(nullptr)*/ {}
|
||||
BatchNode::~BatchNode()
|
||||
{
|
||||
AX_SAFE_DELETE(_groupCommand);
|
||||
}
|
||||
|
||||
bool BatchNode::init()
|
||||
|
@ -62,10 +61,6 @@ void BatchNode::addChild(Node* child, int zOrder, int tag)
|
|||
if (armature != nullptr)
|
||||
{
|
||||
armature->setBatchNode(this);
|
||||
if (_groupCommand == nullptr)
|
||||
{
|
||||
_groupCommand = new GroupCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,10 +71,6 @@ void BatchNode::addChild(ax::Node* child, int zOrder, std::string_view name)
|
|||
if (armature != nullptr)
|
||||
{
|
||||
armature->setBatchNode(this);
|
||||
if (_groupCommand == nullptr)
|
||||
{
|
||||
_groupCommand = new GroupCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,10 +151,11 @@ void BatchNode::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
|
|||
void BatchNode::generateGroupCommand()
|
||||
{
|
||||
Renderer* renderer = Director::getInstance()->getRenderer();
|
||||
_groupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(_groupCommand);
|
||||
auto* groupCommand = renderer->getNextGroupCommand();
|
||||
groupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(groupCommand);
|
||||
|
||||
renderer->pushGroup(_groupCommand->getRenderQueueID());
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
}
|
||||
|
||||
} // namespace cocostudio
|
||||
|
|
|
@ -69,7 +69,6 @@ public:
|
|||
protected:
|
||||
void generateGroupCommand();
|
||||
|
||||
ax::GroupCommand* _groupCommand;
|
||||
};
|
||||
|
||||
} // namespace cocostudio
|
||||
|
|
|
@ -386,11 +386,16 @@ void FUIContainer::visit(ax::Renderer * renderer, const ax::Mat4 & parentTransfo
|
|||
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
|
||||
|
||||
//Add group command
|
||||
|
||||
#if defined(AX_VERSION)
|
||||
auto* stencilGroupCommand = renderer->getNextGroupCommand();
|
||||
stencilGroupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(stencilGroupCommand);
|
||||
renderer->pushGroup(stencilGroupCommand->getRenderQueueID());
|
||||
#else
|
||||
_stencilClippingSupport->_groupCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&_stencilClippingSupport->_groupCommand);
|
||||
|
||||
renderer->pushGroup(_stencilClippingSupport->_groupCommand.getRenderQueueID());
|
||||
#endif
|
||||
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
_stencilClippingSupport->_stencilStateManager->onBeforeVisit(_globalZOrder);
|
||||
|
@ -476,11 +481,19 @@ void FUIContainer::visit(ax::Renderer * renderer, const ax::Mat4 & parentTransfo
|
|||
{
|
||||
_rectClippingSupport->_clippingRectDirty = true;
|
||||
}
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
#if defined(AX_VERSION)
|
||||
auto* rectClippingGroupCommand = renderer->getNextGroupCommand();
|
||||
rectClippingGroupCommand->init(_globalZOrder);
|
||||
renderer->addCommand(rectClippingGroupCommand);
|
||||
renderer->pushGroup(rectClippingGroupCommand->getRenderQueueID());
|
||||
#else
|
||||
# if COCOS2D_VERSION >= 0x00040000
|
||||
_rectClippingSupport->_groupCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&_rectClippingSupport->_groupCommand);
|
||||
renderer->pushGroup(_rectClippingSupport->_groupCommand.getRenderQueueID());
|
||||
# endif
|
||||
#endif
|
||||
|
||||
auto beforeVisitCmdScissor = renderer->nextCallbackCommand();
|
||||
beforeVisitCmdScissor->init(_globalZOrder);
|
||||
beforeVisitCmdScissor->func = AX_CALLBACK_0(FUIContainer::onBeforeVisitScissor, this);
|
||||
|
|
|
@ -21,7 +21,9 @@ public:
|
|||
bool _clippingRectDirty;
|
||||
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
#if !defined(AX_VERSION)
|
||||
ax::GroupCommand _groupCommand;
|
||||
#endif
|
||||
//ax::CallbackCommand _beforeVisitCmdScissor;
|
||||
//ax::CallbackCommand _afterVisitCmdScissor;
|
||||
#else
|
||||
|
@ -37,7 +39,9 @@ public:
|
|||
|
||||
ax::Node* _stencil;
|
||||
ax::StencilStateManager* _stencilStateManager;
|
||||
#if !defined(AX_VERSION)
|
||||
ax::GroupCommand _groupCommand;
|
||||
#endif
|
||||
#if COCOS2D_VERSION >= 0x00040000
|
||||
ax::backend::ProgramState* _originStencilProgram;
|
||||
//ax::CallbackCommand _beforeVisitCmd;
|
||||
|
|
|
@ -196,9 +196,6 @@ std::string NewSpriteTest::subtitle() const
|
|||
|
||||
class SpriteInGroupCommand : public Sprite
|
||||
{
|
||||
protected:
|
||||
GroupCommand _spriteWrapperCommand;
|
||||
|
||||
public:
|
||||
static SpriteInGroupCommand* create(std::string_view filename);
|
||||
|
||||
|
@ -216,9 +213,10 @@ SpriteInGroupCommand* SpriteInGroupCommand::create(std::string_view filename)
|
|||
void SpriteInGroupCommand::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
|
||||
{
|
||||
AXASSERT(renderer, "Render is null");
|
||||
_spriteWrapperCommand.init(_globalZOrder);
|
||||
renderer->addCommand(&_spriteWrapperCommand);
|
||||
renderer->pushGroup(_spriteWrapperCommand.getRenderQueueID());
|
||||
auto * spriteWrapperCommand = renderer->getNextGroupCommand();
|
||||
spriteWrapperCommand->init(_globalZOrder);
|
||||
renderer->addCommand(spriteWrapperCommand);
|
||||
renderer->pushGroup(spriteWrapperCommand->getRenderQueueID());
|
||||
Sprite::draw(renderer, transform, flags);
|
||||
renderer->popGroup();
|
||||
}
|
||||
|
@ -744,7 +742,7 @@ void CaptureNodeTest::onCaptured(Ref*)
|
|||
sp->setPosition(s.width / 2, s.height / 2);
|
||||
|
||||
// store to disk
|
||||
image->saveToFile(_filename);
|
||||
image->saveToFile(_filename, false);
|
||||
};
|
||||
|
||||
auto callbackFunction = std::bind(callback, std::placeholders::_1);
|
||||
|
|
Loading…
Reference in New Issue