Skip to content

Commit 320b9b4

Browse files
Mee-guminggo
authored andcommitted
Feature/sprite optimized (#19998)
Optimize sprite creation speed
1 parent 00f07a5 commit 320b9b4

23 files changed

+986
-427
lines changed

cocos/2d/CCLabel.cpp

Lines changed: 34 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -596,24 +596,27 @@ static Texture2D* _getTexture(Label* label)
596596
void Label::setVertexLayout(PipelineDescriptor& pipelineDescriptor)
597597
{
598598
auto& layout = pipelineDescriptor.vertexLayout;
599-
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
600-
auto iter = attributeInfo.find("a_position");
601-
if(iter != attributeInfo.end())
602-
{
603-
layout.setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
604-
}
605-
iter = attributeInfo.find("a_texCoord");
606-
if(iter != attributeInfo.end())
607-
{
608-
layout.setAttribute("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
609-
}
610-
iter = attributeInfo.find("a_color");
611-
if(iter != attributeInfo.end())
612-
{
613-
layout.setAttribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
614-
}
599+
///a_position
600+
layout.setAttribute(backend::ATTRIBUTE_NAME_POSITION,
601+
_programState->getAttributeLocation(backend::Attribute::POSITION),
602+
backend::VertexFormat::FLOAT3,
603+
0,
604+
false);
605+
606+
///a_texCoord
607+
layout.setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
608+
_programState->getAttributeLocation(backend::Attribute::TEXCOORD),
609+
backend::VertexFormat::FLOAT2,
610+
offsetof(V3F_C4B_T2F, texCoords),
611+
false);
612+
613+
///a_color
614+
layout.setAttribute(backend::ATTRIBUTE_NAME_COLOR,
615+
_programState->getAttributeLocation(backend::Attribute::COLOR),
616+
backend::VertexFormat::UBYTE4,
617+
offsetof(V3F_C4B_T2F, colors),
618+
true);
615619
layout.setLayout(sizeof(V3F_C4B_T2F));
616-
617620
}
618621

619622
void Label::setProgramState(backend::ProgramState *programState)
@@ -637,21 +640,13 @@ void Label::setProgramState(backend::ProgramState *programState)
637640

638641
void Label::updateShaderProgram()
639642
{
640-
const char* vert = nullptr;
641-
const char* frag = nullptr;
642-
643+
auto programType = backend::ProgramType::POSITION_TEXTURE_COLOR;
643644
if (_currentLabelType == LabelType::BMFONT || _currentLabelType == LabelType::CHARMAP)
644645
{
645646
auto texture = _getTexture(this);
646647
if(texture && texture->getAlphaTextureName())
647648
{
648-
vert = positionTextureColor_vert;
649-
frag = etc1_frag;
650-
}
651-
else
652-
{
653-
vert = positionTextureColor_vert;
654-
frag = positionTextureColor_frag;
649+
programType = backend::ProgramType::ETC1;
655650
}
656651
}
657652
else
@@ -661,40 +656,30 @@ void Label::updateShaderProgram()
661656
case cocos2d::LabelEffect::NORMAL:
662657
if (_useDistanceField)
663658
{
664-
vert = positionTextureColor_vert;
665-
frag = label_distanceNormal_frag;
659+
programType = backend::ProgramType::LABEL_DISTANCE_NORMAL;
666660
}
667661
else if (_useA8Shader)
668662
{
669-
vert = positionTextureColor_vert;
670-
frag = label_normal_frag;
663+
programType = backend::ProgramType::LABEL_NORMAL;
671664
}
672665
else
673666
{
674667
auto texture = _getTexture(this);
675668
if(texture && texture->getAlphaTextureName())
676669
{
677-
vert = positionTextureColor_vert;
678-
frag = etc1_frag;
679-
}
680-
else
681-
{
682-
vert = positionTextureColor_vert;
683-
frag = positionTextureColor_frag;
670+
programType = backend::ProgramType::ETC1;
684671
}
685672
}
686673
break;
687674
case cocos2d::LabelEffect::OUTLINE:
688675
{
689-
vert = positionTextureColor_vert;
690-
frag = labelOutline_frag;
676+
programType = backend::ProgramType::LABLE_OUTLINE;
691677
}
692678
break;
693679
case cocos2d::LabelEffect::GLOW:
694680
if (_useDistanceField)
695681
{
696-
vert = positionTextureColor_vert;
697-
frag = labelDistanceFieldGlow_frag;
682+
programType = backend::ProgramType::LABLE_DISTANCEFIELD_GLOW;
698683
}
699684
break;
700685
default:
@@ -703,7 +688,7 @@ void Label::updateShaderProgram()
703688
}
704689

705690
CC_SAFE_RELEASE(_programState);
706-
_programState = new backend::ProgramState(vert, frag);
691+
_programState = new backend::ProgramState(programType);
707692

708693
updateUniformLocations();
709694

@@ -740,12 +725,12 @@ void Label::updateBatchCommand(Label::BatchCommand &batch)
740725

741726
void Label::updateUniformLocations()
742727
{
743-
_mvpMatrixLocation = _programState->getUniformLocation("u_MVPMatrix");
744-
_textureLocation = _programState->getUniformLocation("u_texture");
745-
_alphaTextureLocation = _programState->getUniformLocation("u_texture1");
746-
_textColorLocation = _programState->getUniformLocation("u_textColor");
747-
_effectColorLocation = _programState->getUniformLocation("u_effectColor");
748-
_effectTypeLocation = _programState->getUniformLocation("u_effectType");
728+
_mvpMatrixLocation = _programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
729+
_textureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE);
730+
_alphaTextureLocation = _programState->getUniformLocation(backend::Uniform::TEXTURE1);
731+
_textColorLocation = _programState->getUniformLocation(backend::Uniform::TEXT_COLOR);
732+
_effectColorLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_COLOR);
733+
_effectTypeLocation = _programState->getUniformLocation(backend::Uniform::EFFECT_TYPE);
749734
}
750735

751736
void Label::setFontAtlas(FontAtlas* atlas,bool distanceFieldEnabled /* = false */, bool useA8Shader /* = false */)

cocos/2d/CCSprite.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -353,22 +353,25 @@ void Sprite::setVertexLayout()
353353
{
354354
//set vertexLayout according to V3F_C4B_T2F structure
355355
auto& vertexLayout = _trianglesCommand.getPipelineDescriptor().vertexLayout;
356-
const auto& attributeInfo = _programState->getProgram()->getActiveAttributes();
357-
auto iter = attributeInfo.find("a_position");
358-
if(iter != attributeInfo.end())
359-
{
360-
vertexLayout.setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT3, 0, false);
361-
}
362-
iter = attributeInfo.find("a_texCoord");
363-
if(iter != attributeInfo.end())
364-
{
365-
vertexLayout.setAttribute("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, offsetof(V3F_C4B_T2F, texCoords), false);
366-
}
367-
iter = attributeInfo.find("a_color");
368-
if(iter != attributeInfo.end())
369-
{
370-
vertexLayout.setAttribute("a_color", iter->second.location, backend::VertexFormat::UBYTE4, offsetof(V3F_C4B_T2F, colors), true);
371-
}
356+
///a_position
357+
vertexLayout.setAttribute(backend::ATTRIBUTE_NAME_POSITION,
358+
_programState->getAttributeLocation(backend::Attribute::POSITION),
359+
backend::VertexFormat::FLOAT3,
360+
0,
361+
false);
362+
///a_texCoord
363+
vertexLayout.setAttribute(backend::ATTRIBUTE_NAME_TEXCOORD,
364+
_programState->getAttributeLocation(backend::Attribute::TEXCOORD),
365+
backend::VertexFormat::FLOAT2,
366+
offsetof(V3F_C4B_T2F, texCoords),
367+
false);
368+
369+
///a_color
370+
vertexLayout.setAttribute(backend::ATTRIBUTE_NAME_COLOR,
371+
_programState->getAttributeLocation(backend::Attribute::COLOR),
372+
backend::VertexFormat::UBYTE4,
373+
offsetof(V3F_C4B_T2F, colors),
374+
true);
372375
vertexLayout.setLayout(sizeof(V3F_C4B_T2F));
373376
}
374377

@@ -379,6 +382,17 @@ void Sprite::updateShaders(const char* vert, const char* frag)
379382
CC_SAFE_RELEASE_NULL(programState);
380383
}
381384

385+
void Sprite::setProgramState(backend::ProgramType type)
386+
{
387+
if(_programState != nullptr &&
388+
_programState->getProgram()->getProgramType() == type)
389+
return;
390+
391+
auto programState = new (std::nothrow) backend::ProgramState(type);
392+
setProgramState(programState);
393+
CC_SAFE_RELEASE_NULL(programState);
394+
}
395+
382396
void Sprite::setProgramState(backend::ProgramState *programState)
383397
{
384398
CCASSERT(programState, "argument should not be nullptr");
@@ -391,9 +405,9 @@ void Sprite::setProgramState(backend::ProgramState *programState)
391405
}
392406
pipelineDescriptor.programState = _programState;
393407

394-
_mvpMatrixLocation = pipelineDescriptor.programState->getUniformLocation("u_MVPMatrix");
395-
_textureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture");
396-
_alphaTextureLocation = pipelineDescriptor.programState->getUniformLocation("u_texture1");
408+
_mvpMatrixLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::MVP_MATRIX);
409+
_textureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE);
410+
_alphaTextureLocation = pipelineDescriptor.programState->getUniformLocation(backend::Uniform::TEXTURE1);
397411

398412
setVertexLayout();
399413
updateProgramState();
@@ -403,8 +417,8 @@ void Sprite::setProgramState(backend::ProgramState *programState)
403417
void Sprite::setTexture(Texture2D *texture)
404418
{
405419
auto isETC1 = texture && texture->getAlphaTextureName();
406-
updateShaders(positionTextureColor_vert, (isETC1) ? etc1_frag : positionTextureColor_frag);
407-
420+
setProgramState((isETC1) ? backend::ProgramType::ETC1 : backend::ProgramType::POSITION_TEXTURE_COLOR);
421+
408422
CCASSERT(! _batchNode || (texture && texture == _batchNode->getTexture()), "CCSprite: Batched sprites should use the same texture as the batchnode");
409423
// accept texture==nil as argument
410424
CCASSERT( !texture || dynamic_cast<Texture2D*>(texture), "setTexture expects a Texture2D. Invalid argument");

cocos/2d/CCSprite.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ CC_CONSTRUCTOR_ACCESS :
641641
void updateStretchFactor();
642642
void populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad);
643643
void setMVPMatrixUniform();
644-
644+
void setProgramState(backend::ProgramType type);
645645
//
646646
// Data used when the sprite is rendered using a SpriteSheet
647647
//

cocos/renderer/backend/Program.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ Program::Program(const std::string& vs, const std::string& fs)
3232
{
3333
}
3434

35+
void Program::setProgramType(ProgramType type)
36+
{
37+
_programType = type;
38+
}
39+
3540
CC_BACKEND_END

cocos/renderer/backend/Program.h

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,46 @@
3737
CC_BACKEND_BEGIN
3838

3939
class ShaderModule;
40+
4041
/**
4142
* @addtogroup _backend
4243
* @{
4344
*/
4445

46+
4547
/**
4648
* A program.
4749
*/
4850
class Program : public Ref
4951
{
5052
public:
5153
/**
52-
* Get vertex uniform infomation.
53-
* @return Vertex uniform information. Key is uniform name, Value is corresponding uniform info.
54+
* Get uniform location by name.
55+
* @param uniform Specifies the uniform name.
56+
* @return The uniform location.
5457
*/
55-
virtual const std::unordered_map<std::string, UniformInfo>& getVertexUniformInfos() const = 0;
58+
virtual UniformLocation getUniformLocation(const std::string& uniform) const = 0;
5659

5760
/**
58-
* Get fragment uniform information.
59-
* @return Fragment uniform information. Key is uniform name, Value is corresponding uniform info.
61+
* Get uniform location by engine built-in uniform enum name.
62+
* @param name Specifies the engine built-in uniform enum name.
63+
* @return The uniform location.
6064
*/
61-
virtual const std::unordered_map<std::string, UniformInfo>& getFragmentUniformInfos() const = 0;
62-
65+
virtual UniformLocation getUniformLocation(backend::Uniform name) const = 0;
66+
6367
/**
64-
* Get uniform location by name.
65-
* @param uniform Specifies the uniform name.
66-
* @return The uniform location.
68+
* Get attribute location by attribute name.
69+
* @param name Specifies the attribute name.
70+
* @return The attribute location.
6771
*/
68-
virtual UniformLocation getUniformLocation(const std::string& uniform) const = 0;
72+
virtual int getAttributeLocation(const std::string& name) const = 0;
73+
74+
/**
75+
* Get attribute location by engine built-in attribute enum name.
76+
* @param name Specifies the engine built-in attribute enum name.
77+
* @return The attribute location.
78+
*/
79+
virtual int getAttributeLocation(backend::Attribute name) const = 0;
6980

7081
/**
7182
* Get maximum vertex location.
@@ -97,6 +108,39 @@ class Program : public Ref
97108
*/
98109
const std::string& getFragmentShader() const { return _fragmentShader; }
99110

111+
/**
112+
* Get engine built-in program type.
113+
* @return The built-in program type.
114+
*/
115+
ProgramType getProgramType() const { return _programType; }
116+
117+
/**
118+
* Set engin built-in program type.
119+
* @param type Specifies the program type.
120+
*/
121+
void setProgramType(ProgramType type);
122+
123+
/**
124+
* Get uniform buffer size in bytes that can hold all the uniforms.
125+
* @param stage Specifies the shader stage. The symbolic constant can be either VERTEX or FRAGMENT.
126+
* @return The uniform buffer size in bytes.
127+
*/
128+
virtual std::size_t getUniformBufferSize(ShaderStage stage) const =0;
129+
130+
/**
131+
* Get a uniformInfo in given location from the specific shader stage.
132+
* @param stage Specifies the shader stage. The symbolic constant can be either VERTEX or FRAGMENT.
133+
* @param location Specifies the uniform locaion.
134+
* @return The uniformInfo.
135+
*/
136+
virtual const UniformInfo& getActiveUniformInfo(ShaderStage stage, int location) const = 0;
137+
138+
/**
139+
* Get all uniformInfos.
140+
* @return The uniformInfos.
141+
*/
142+
virtual const std::unordered_map<std::string, UniformInfo>& getAllActiveUniformInfo(ShaderStage stage) const = 0;
143+
100144
protected:
101145
/**
102146
* @param vs Specifes the vertex shader source.
@@ -106,22 +150,35 @@ class Program : public Ref
106150

107151
#if CC_ENABLE_CACHE_TEXTURE_DATA
108152
/**
109-
* Get the ture location after opengl program reload.
110-
* @param location Specifies original location before EGL context lost.
153+
* In case of EGL context lost, the engine will reload shaders. Thus location of uniform may changed.
154+
* The engine will maintain the relationship between the original uniform location and the current active uniform location.
155+
* @param location Specifies original location.
156+
* @return Current active uniform location.
157+
* @see `int getOriginalLocation(int location) const`
111158
*/
112159
virtual int getMappedLocation(int location) const = 0;
113160

161+
/**
162+
* In case of EGL context lost, the engine will reload shaders. Thus location of uniform may changed.
163+
* The engine will maintain the relationship between the original uniform location and the current active uniform location.
164+
* @param location Specifies the current active uniform location.
165+
* @return The original uniform location.
166+
* @see `int getMappedLocation(int location) const`
167+
*/
168+
virtual int getOriginalLocation(int location) const = 0;
169+
114170
/**
115171
* Get all uniform locations.
116172
* @return All uniform locations.
117173
*/
118-
virtual const std::unordered_map<std::string, UniformLocation> getAllUniformsLocation() const = 0;
174+
virtual const std::unordered_map<std::string, int> getAllUniformsLocation() const = 0;
119175
friend class ProgramState;
120176
friend class ProgramCache;
121177
#endif
122178

123179
std::string _vertexShader; ///< Vertex shader.
124180
std::string _fragmentShader; ///< Fragment shader.
181+
ProgramType _programType; ///< built-in program type.
125182
};
126183

127184
//end of _backend group

0 commit comments

Comments
 (0)