From f8dc8f0b380175d4e548543e0bbca935c0a79302 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Wed, 15 Jan 2014 14:35:26 -0800 Subject: [PATCH] Renderer performance fixes QuadCommand no longer stores a copy of the quads. Instead it just stores a reference and the MV matrix. Later, the Renderer when it copies the Quads to the queue, it will convert the Quads to world coordinates --- CHANGELOG | 1 + cocos/2d/renderer/CCQuadCommand.cpp | 58 +++-------------------------- cocos/2d/renderer/CCQuadCommand.h | 15 +++++--- cocos/2d/renderer/CCRenderer.cpp | 47 ++++++++++++++++++++++- cocos/2d/renderer/CCRenderer.h | 3 ++ 5 files changed, 64 insertions(+), 60 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4e7311b166..3b3b55d33e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ cocos2d-x-3.0final ?.? ? [FIX] ControlSlider doesn't support to set selected thumb sprite. [FIX] ControlButton doesn't support to set scale ratio of touchdown state. [FIX] Particles: Crash was triggered if there is not `textureFileName`section in particle plist file. + [FIX] Renderer: QuadCommand::init() does not copy the Quads, it only store a reference making the code faster [FIX] Tests: TestCpp works with CMake on Windows. [FIX] Tests: Sprites Performance Test has 3 new tests [FIX] TextureCache: getTextureForKey and removeTextureForKey work as expected diff --git a/cocos/2d/renderer/CCQuadCommand.cpp b/cocos/2d/renderer/CCQuadCommand.cpp index b69fd075d3..f60446871c 100644 --- a/cocos/2d/renderer/CCQuadCommand.cpp +++ b/cocos/2d/renderer/CCQuadCommand.cpp @@ -34,12 +34,11 @@ QuadCommand::QuadCommand() ,_depth(0) ,_textureID(0) ,_blendType(BlendFunc::DISABLE) -,_quadCount(0) -,_capacity(0) +,_quadsCount(0) { _type = RenderCommand::Type::QUAD_COMMAND; _shader = nullptr; - _quad = nullptr; + _quads = nullptr; } void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, ssize_t quadCount, const kmMat4 &mv) @@ -48,63 +47,16 @@ void QuadCommand::init(int viewport, int32_t depth, GLuint textureID, GLProgram* _depth = depth; _textureID = textureID; _blendType = blendType; - _quadCount = quadCount; _shader = shader; - if(quadCount > _capacity ) { - //TODO find a better way to manage quads, current way will result in memory be wasted -// _quad = (V3F_C4B_T2F_Quad*)malloc(sizeof(V3F_C4B_T2F_Quad) * quadCount); - _quad = (V3F_C4B_T2F_Quad*) realloc(_quad, sizeof(*quad) * quadCount ); - _capacity = quadCount; - } + _quadsCount = quadCount; + _quads = quad; - _quadCount = quadCount; - memcpy(_quad, quad, sizeof(V3F_C4B_T2F_Quad) * quadCount); - - for(int i=0; ibl.vertices.x; - vec1.y = q->bl.vertices.y; - vec1.z = q->bl.vertices.z; - kmVec3Transform(&out1, &vec1, &mv); - q->bl.vertices.x = out1.x; - q->bl.vertices.y = out1.y; - q->bl.vertices.z = out1.z; - - kmVec3 vec2, out2; - vec2.x = q->br.vertices.x; - vec2.y = q->br.vertices.y; - vec2.z = q->br.vertices.z; - kmVec3Transform(&out2, &vec2, &mv); - q->br.vertices.x = out2.x; - q->br.vertices.y = out2.y; - q->br.vertices.z = out2.z; - - kmVec3 vec3, out3; - vec3.x = q->tr.vertices.x; - vec3.y = q->tr.vertices.y; - vec3.z = q->tr.vertices.z; - kmVec3Transform(&out3, &vec3, &mv); - q->tr.vertices.x = out3.x; - q->tr.vertices.y = out3.y; - q->tr.vertices.z = out3.z; - - kmVec3 vec4, out4; - vec4.x = q->tl.vertices.x; - vec4.y = q->tl.vertices.y; - vec4.z = q->tl.vertices.z; - kmVec3Transform(&out4, &vec4, &mv); - q->tl.vertices.x = out4.x; - q->tl.vertices.y = out4.y; - q->tl.vertices.z = out4.z; - } + _mv = mv; } QuadCommand::~QuadCommand() { - free(_quad); } int64_t QuadCommand::generateID() diff --git a/cocos/2d/renderer/CCQuadCommand.h b/cocos/2d/renderer/CCQuadCommand.h index 411dc4913b..b21999ea58 100644 --- a/cocos/2d/renderer/CCQuadCommand.h +++ b/cocos/2d/renderer/CCQuadCommand.h @@ -41,7 +41,7 @@ public: QuadCommand(); ~QuadCommand(); - void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quad, ssize_t quadCount, + void init(int viewport, int32_t depth, GLuint texutreID, GLProgram* shader, BlendFunc blendType, V3F_C4B_T2F_Quad* quads, ssize_t quadCount, const kmMat4& mv); // +----------+----------+-----+-----------------------------------+ @@ -60,13 +60,15 @@ public: inline GLuint getTextureID() const { return _textureID; } - inline V3F_C4B_T2F_Quad* getQuad() const { return _quad; } + inline V3F_C4B_T2F_Quad* getQuads() const { return _quads; } - inline ssize_t getQuadCount() const { return _quadCount; } + inline ssize_t getQuadCount() const { return _quadsCount; } inline GLProgram* getShader() const { return _shader; } inline BlendFunc getBlendType() const { return _blendType; } + + inline const kmMat4& getModelView() const { return _mv; } protected: int32_t _materialID; @@ -85,9 +87,10 @@ protected: BlendFunc _blendType; - V3F_C4B_T2F_Quad* _quad; - ssize_t _quadCount; - ssize_t _capacity; + V3F_C4B_T2F_Quad* _quads; + ssize_t _quadsCount; + + kmMat4 _mv; }; NS_CC_END diff --git a/cocos/2d/renderer/CCRenderer.cpp b/cocos/2d/renderer/CCRenderer.cpp index 2763f71ef6..5c97dfdae4 100644 --- a/cocos/2d/renderer/CCRenderer.cpp +++ b/cocos/2d/renderer/CCRenderer.cpp @@ -256,7 +256,9 @@ void Renderer::render() _lastCommand ++; } - memcpy(_quads + _numQuads, cmd->getQuad(), sizeof(V3F_C4B_T2F_Quad) * cmdQuadCount); + memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmdQuadCount); + convertToWorldCoordiantes(_quads + _numQuads, cmdQuadCount, cmd->getModelView()); + _numQuads += cmdQuadCount; } else if(commandType == RenderCommand::Type::CUSTOM_COMMAND) @@ -319,6 +321,49 @@ void Renderer::render() _lastMaterialID = 0; } +void Renderer::convertToWorldCoordiantes(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const kmMat4& modelView) +{ + for(ssize_t i=0; ibl.vertices.x; + vec1.y = q->bl.vertices.y; + vec1.z = q->bl.vertices.z; + kmVec3Transform(&out1, &vec1, &modelView); + q->bl.vertices.x = out1.x; + q->bl.vertices.y = out1.y; + q->bl.vertices.z = out1.z; + + kmVec3 vec2, out2; + vec2.x = q->br.vertices.x; + vec2.y = q->br.vertices.y; + vec2.z = q->br.vertices.z; + kmVec3Transform(&out2, &vec2, &modelView); + q->br.vertices.x = out2.x; + q->br.vertices.y = out2.y; + q->br.vertices.z = out2.z; + + kmVec3 vec3, out3; + vec3.x = q->tr.vertices.x; + vec3.y = q->tr.vertices.y; + vec3.z = q->tr.vertices.z; + kmVec3Transform(&out3, &vec3, &modelView); + q->tr.vertices.x = out3.x; + q->tr.vertices.y = out3.y; + q->tr.vertices.z = out3.z; + + kmVec3 vec4, out4; + vec4.x = q->tl.vertices.x; + vec4.y = q->tl.vertices.y; + vec4.z = q->tl.vertices.z; + kmVec3Transform(&out4, &vec4, &modelView); + q->tl.vertices.x = out4.x; + q->tl.vertices.y = out4.y; + q->tl.vertices.z = out4.z; + } +} + void Renderer::drawBatchedQuads() { //TODO we can improve the draw performance by insert material switching command before hand. diff --git a/cocos/2d/renderer/CCRenderer.h b/cocos/2d/renderer/CCRenderer.h index e732547130..c2dcdccc6f 100644 --- a/cocos/2d/renderer/CCRenderer.h +++ b/cocos/2d/renderer/CCRenderer.h @@ -75,9 +75,12 @@ protected: void mapBuffers(); void drawBatchedQuads(); + //Draw the previews queued quads and flush previous context void flush(); + void convertToWorldCoordiantes(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const kmMat4& modelView); + std::stack _commandGroupStack; std::stack _renderStack;