Metal support alpha1 released

Hi,

I tried to to build cpp-tests on Android studio and got the issue:

Everything is fine in Visual Studio.

I installed Android Sdudio 3.4, Gradle version 5.3.1, Android Gradle plugin version 3.4.0. And now I have the following issue while compilation:

What Android version are you using?


I set API to 28 and could build project properly.
But another issue occured after launch project on my phone.
I would appreciate for advice:
cpu: Spreadtrum SC7731
Android 5.1

Thanks in advance.

I just used default setting. My Android Studio is 3.3.1. I tested on mac.

The above issue exists only for test projects. It’s normal in new generated one.

Now I try to port my code on new engine and found out the following issues:

  1. There are no ‘precision mediump float’ in 3d fragment shaders. It causes to the compile error on opengl es.
  2. There are very big ‘light count number’ macroses for 3d shaders. It equals 5 for each light source. This leads to the overflow of ‘varying’ variables in the 3d shaders. The count of ‘varying’ variables is differs for different GPU. (ex. It is 16 of Vec4 for mali 400).
    It would be great if you reduce the default ‘light count number’ to 1, as it was before.

@solan thanks for the feedback, could you please describe the issue in detail?

Which shader causes the issue? Of course we will review all the shaders, but it is better if you can describe it in detail. And which platform did you test? We didn’t meet it.

Which shader has this issue. As i remember we don’t modify the shader a lot.

I test Android Studio project. My GPU is Mali 400 mp2 which support’s only opengl es 2.0.
You can find some info about the issue to the link:

There is the list of shader file names, which I can to find for fixing:
3D_colorTexture.frag
3D_particle.frag
cameraClear.frag
3D_color.frag
3D_colorNormal.frag
3D_colorNormalTexture.frag

(It strange that 3D_skybox.frag and 3D_terrain.frag include the ‘precise’ line).

I mean the following shader 3D_positionNormalTexture.vert.

There are the following lines:
image

Array’s of varying varriable’s, which size’s are depend on MAX_DIRECTIONAL_LIGHT_NUM, MAX_POINT_LIGHT_NUM and MAX_SPOT_LIGHT_NUM.

These macroses are hardcoded in the:

Mali 400 supports only 16 Vec4s varying varriables for example. I know that it is very ancient unit, but still)

PS. As I can see it marked as TODO.

PPS. Could you please do not forget to add the following also:

There written that ‘isVisibleInFrustum removal’ but as I can see this function exists and works properly.

@solan thanks for the detail information. I have crated [https://github.com/cocos2d/cocos2d-x/issues/19653] and [https://github.com/cocos2d/cocos2d-x/issues/19652] for them. About the commented codes, there is already an issue to fix TODO.

@zhangxm Can you please clarify. I need to have 1 Material with 1 Technique, which includes 2 Pass for Mesh. The first Pass should be processed with disabled ‘blend’, while the second Pass should be processed with enabled ‘blend’.

I see that there is

inline RenderState::StateBlock &getStateBlock() { return _renderState._state; }

function for Material and Technique classes, but there is no the same for Pass class.
Why this design, and is it possible to add this function?

//===

It seems that the function does not work properly:

What to do if the depth writing was set before to the ‘true’. Like in the
Renderer::visitRenderQueue(RenderQueue& queue)
for opaque objects.

We call RenterState::StateBlock::setDepthWrite(false), but _modifiedBits will be cleared for the corresponding bit.

It leads to the case when the following code will bypass updating of the depth value.
image

It happens in the following code:

May be restore is the extra action also? The default values will be restored anyway in the
void RenderState::unbindPass(Pass* pass, MeshCommand* command)

Could you please investigate this.

Yep, it seems this functions is missed when refactoring. In v3, Pass inherits from RenderState, so doesn’t need this function.

Yep, it is an issue when refactoring.

@zhangxm It seems I found some new issues. Could you please check if possible:

  1. There is shader “lineColor.vert” which includes the following code:

I have error while compile it on opengl es 2.0 on my phone under Android 5.1 (with mali 400). And everything is ok if change ‘1.0f’ on ‘1.0’ (without ‘f’). Is it fundamental to use ‘f’ :grinning:

  1. The issue is touch opengl backend. Look please at the function:

As I could understand this parameter should relate on backend::BufferUsage. Otherwise it is impossible to create dynamic buffer and update it from time to time.

  1. The issue is also related to the opengl backend. backecnd::VertexFormat supports USHORT4 and USHORT2 but they are not supported in the GLenum UtilsGL::toGLAttributeType(VertexFormat vertexFormat) and GLsizei UtilsGL::getGLAttributeSize(VertexFormat vertexFormat)

Besides there are some constants which should be supported according to the opengl es specification. Could they be supported also? Look please to the link as reference: glVertexAttribPointer

  1. And one very bad for me issue. I did not have any problems with that on V3 branch, but here encounter the problem. I can’t provide some cause - only observation:

Imagine that you have some class derived from cocos2d::ui::Layout. Then you add some children to that class. My issue is the following. The children that was added after cocos2d::ui::ListView are not rendered. If ListView is not added to the class, than all children can be rendered properly.

// Target id editbox
	_idTargeUI = cocos2d::ui::EditBox::create(cocos2d::Size(100, 16), cocos2d::ui::Scale9Sprite::create("res/ui/background.png"));
	_idTargeUI->setFontColor(cocos2d::Color3B::WHITE);
	_idTargeUI->setPlaceHolder("Target ID");
	_idTargeUI->setPlaceholderFontColor(cocos2d::Color3B::WHITE);
	_idTargeUI->setMaxLength(100);
	_idTargeUI->setFontSize(14);
	_idTargeUI->setText("");
	_idTargeUI->setInputFlag(cocos2d::ui::EditBox::InputFlag::SENSITIVE);
	_idTargeUI->setReturnType(cocos2d::ui::EditBox::KeyboardReturnType::DONE);

	cocos2d::ui::RelativeLayoutParameter* r = cocos2d::ui::RelativeLayoutParameter::create();
	//r->setMargin(cocos2d::ui::Margin(p.x - pos_in.x - scaled_width / 2, (getContentSize().height + pos_in.y - p.y - scaled_height + scaled_height / 2), 0.0, 0.0));
	r->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT);
	_idTargeUI->setLayoutParameter(r);
	addChild(_idTargeUI);

	float hght = 20.0;

	// Phrase list box
	_lstPhraseUI = cocos2d::ui::ListView::create();
	_lstPhraseUI->setContentSize(cocos2d::Size(200, 200));
	_lstPhraseUI->setSwallowTouches(false);
	_lstPhraseUI->setBackGroundColor(cocos2d::Color3B(0xBC, 0x8F, 0x8F));
	_lstPhraseUI->setBackGroundColorType(cocos2d::ui::Layout::BackGroundColorType::SOLID);

	_lstLayParam = cocos2d::ui::RelativeLayoutParameter::create();
	_lstLayParam->retain();
	_lstLayParam->setMargin(cocos2d::ui::Margin(0.0, hght, 0.0, 0.0));
	_lstLayParam->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT);

	_lstPhraseUI->setLayoutParameter(_lstLayParam);
//	addChild(_lstPhraseUI);

	hght += _lstPhraseUI->getContentSize().height + 5.0;

	// Edit box to add new phrase
	_phraseUI = cocos2d::ui::EditBox::create(cocos2d::Size(getContentSize().width, 200), cocos2d::ui::Scale9Sprite::create("res/ui/background.png"));
	_phraseUI->setFontColor(cocos2d::Color3B::WHITE);
	_phraseUI->setPlaceHolder("New script");
	_phraseUI->setPlaceholderFontSize(30.f);
	_phraseUI->setPlaceholderFontColor(cocos2d::Color3B::WHITE);
	_phraseUI->setMaxLength(1000);
	_phraseUI->setFontSize(14);
	_phraseUI->setText("");
	//_phraseUI->setReturnType(cocos2d::ui::EditBox::KeyboardReturnType::DONE);
	_phraseUI->setInputFlag(cocos2d::ui::EditBox::InputFlag::SENSITIVE);
	_phraseUI->setDelegate(&_editBoxDelegate);
	_phraseUI->setEnabled(false);

	r = cocos2d::ui::RelativeLayoutParameter::create();
	r->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT);
	r->setMargin(cocos2d::ui::Margin(0.0, hght, 0.0, 0.0));
	_phraseUI->setLayoutParameter(r);
	addChild(_phraseUI);

	hght += _phraseUI->getContentSize().height + 5.0;

	// Button to create new phrase
	_btCreatePhrUI = cocos2d::ui::Button::create();
	_btCreatePhrUI->setTitleColor(cocos2d::Color3B::BLACK);
	_btCreatePhrUI->setTitleText("New Phr");
	_btCreatePhrUI->setTitleFontSize(14);
	_btCreatePhrUI->setPressedActionEnabled(true);
	_btCreatePhrUI->addClickEventListener([this](Ref *pSender) {
		this->addPhrase("New phrase");
	});
	r = cocos2d::ui::RelativeLayoutParameter::create();
	r->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT);
	r->setMargin(cocos2d::ui::Margin(0.0, hght, 0.0, 0.0));
	_btCreatePhrUI->setLayoutParameter(r);
	addChild(_btCreatePhrUI);

	float wdth = _btCreatePhrUI->getContentSize().width + 5.0;

	// Button to record of the camera position
	_btPhotoUI = cocos2d::ui::Button::create();
	_btPhotoUI->setTitleColor(cocos2d::Color3B::BLACK);
	_btPhotoUI->setTitleText("Photo");
	_btPhotoUI->setTitleFontSize(14);
	_btPhotoUI->setPressedActionEnabled(true);
	_btPhotoUI->addClickEventListener([this](Ref *pSender) {
		
		Editor::getEditor().setStaticPhotoData(_idTargeUI->getText(), [this](const Editor::PHOTO_STATIC_PARAM& par) {
			
			// Get data from the adjusted Editor::PHOTO_DATA
			_photoParam[_editBoxDelegate.getEditListNumber()] = par;
			
			// Change mode on the 'Dialogue' back
			Editor::getEditor().changeMode(Editor::MODE::DIALOGUE);
			
			// Reset parameters
			Editor::getEditor().setStaticPhotoData("", 
				                                   [](const Editor::PHOTO_STATIC_PARAM& par) {}, 
				                                   Editor::PHOTO_STATIC_PARAM());
		
		}, _photoParam[_editBoxDelegate.getEditListNumber()]);
		
		Editor::getEditor().changeMode(Editor::MODE::PHOTO);

	});
	r = cocos2d::ui::RelativeLayoutParameter::create();
	r->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT);
	r->setMargin(cocos2d::ui::Margin(wdth, hght, 0.0, 0.0));
	_btPhotoUI->setLayoutParameter(r);
	addChild(_btPhotoUI);

	wdth += _btPhotoUI->getContentSize().width + 5.0;

	// Button to edit PhraseBall
	_btPhraseUI = cocos2d::ui::Button::create();
	_btPhraseUI->setTitleColor(cocos2d::Color3B::BLACK);
	_btPhraseUI->setTitleText("Phrase");
	_btPhraseUI->setTitleFontSize(14);
	_btPhraseUI->setPressedActionEnabled(true);
	_btPhraseUI->addClickEventListener([this](Ref *pSender) {

		DlgMenu* men = static_cast<DlgMenu*>(Editor::getEditor().getActiveMenu());
		int num = _editBoxDelegate.getEditListNumber();

		men->createPhraseBall(_phrParam.at(num), 
			                  [this](PhraseBall* pb) { 
			                         acceptPhrBallCallback(pb); 
		                      }, 
			                  static_cast<ui::Text*>(_lstPhraseUI->getItem(num))->getString().c_str());
		men->stopEvent(true);
		
		// Close Dlg editor
		auto ed = Editor::getEditor().getActiveMenu()->getChildByName("block_editor");
		assert(ed);
		ed->setVisible(false);

		// Set Camera
		Editor::getEditor().setStaticPhotoData(_idTargeUI->getText(),
			                                   [](const Editor::PHOTO_STATIC_PARAM& par) {},
                                               _photoParam[num]);

	});
	r = cocos2d::ui::RelativeLayoutParameter::create();
	r->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT);
	r->setMargin(cocos2d::ui::Margin(wdth, hght, 0.0, 0.0));
	_btPhraseUI->setLayoutParameter(r);
	addChild(_btPhraseUI);

The other widgets are not rendered if addChild(_lstPhraseUI); will be uncommented.

  1. f is not needed. We will correct it.
  2. Yep, i think you are right.
  3. We will take a look, not all size format are supported in metal.
  4. Could you please provide a test case? Thanks.

Thanks again for your feedback.

  1. lineColor.vert issue was fixed in this PR
  2. Buffer usage was fixed in this PR

Thanks for you work.
About (3) I thought the same about metal, really it is not very important.
About (4) - sorry, I can’t provide now some standalone testcase, except the code above right now. May be some later.

@zhangxm I checked one more time and found out that the second added ListView as child is not rendered for some reason.

There is the following UI test in the cpp-tests, which is called UILayoutTest_Layout_Relative_Align_Parent. At first I thought that the issue is related with the RelativeLayoutParameter::RelativeAlign But it seems that it is not correct. This test is commented - may be there is some known issue with ui::Layout?
By the way, I uncommented this test and added two ListView there, to see them with other Buttons which are rendered by default.
The second ListView is not rendered on the screen. But if you comment adding of the first ListView, then second ListView is rendered properly.
I see the similar thing in my code.
Replace please the attached UILayoutTest.cpp on the same in the cpp-tests, and try the test number 4 from the 14:Layout Test.UILayoutTest.cpp (41.9 KB)

Look please at the 615 line to see my changes. 622 line is intended to comment it to view the second ListView.

//===

The issue was gone if disable “Clipping” via setClippingEnabled(false) for second listView, or set SCISSOR type via setClippingType(Layout::ClippingType::SCISSOR) for it.

I can suppose that the issue could be relate somehow with stencil buffer. There is some logic about using it, and different values passes to these functions for both ListView:

  if (_isBackFrontStencilEqual)
        {
            glStencilFunc(UtilsGL::toGLComareFunction(_depthStencilInfo.frontFaceStencil.stencilCompareFunction),
                          stencilReferenceValueFront,
                          _depthStencilInfo.frontFaceStencil.readMask);
            glStencilOp(UtilsGL::toGLStencilOperation(_depthStencilInfo.frontFaceStencil.stencilFailureOperation),
                        UtilsGL::toGLStencilOperation(_depthStencilInfo.frontFaceStencil.depthFailureOperation),
                        UtilsGL::toGLStencilOperation(_depthStencilInfo.frontFaceStencil.depthStencilPassOperation));
            glStencilMask(_depthStencilInfo.frontFaceStencil.writeMask);
        }

in the void DepthStencilStateGL::apply(unsigned int stencilReferenceValueFront, unsigned int stencilReferenceValueBack)

I don’t have enough experience in using stencil buffer to say more precise.

I found out that Custom command can use CustomCommand::PrimitiveType::POINT as primitive type, but there is no function to set size of points, like setLineWidth(...) for CustomCommand::PrimitiveType::LINE.
Could you please to consider this?

And would be appreciate to know, what do you think about previous message (about Layout clipping type)? Can you confirm that this is issue?

@coulsonwang could you please take a look?

@zhangxm One more thing =)

I tried your metal repository with last changes on 21.05, and found out that there is bad rendering when #define CC_ENABLE_CACHE_TEXTURE_DATA 1.

After some analysis, I think you forgot to copy location inside the following functions:

Take a look please.

@solan thanks. @coulsonwang please take a look.
@solan CC_ENABLE_CACHE_TEXTURE_DATA is used to cache texture data and other GL related states, because Android may lost GL context after back from background. You don’t need it on windows.

@solan Got it, could you please provide a test case? Thanks.

@coulsonwang I have the issue when try to use my custom backend::ProgramState. The copying is not performed here:
%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5

And it cause to the error in the CommandBufferGL::setUniforms(ProgramGL* program) function:

I did not check, but the issue should exist on cpp-test on Android.
I tested on Windows only to analysis.

@solan at the beginning of setTexture , there is a validation check for location. So you should get the location from ProgramState first like this:

backend::UniformLocation texLocation = programState->getUniformLocation(“u_texture”);
programState->setTexture(texLocation, 0, _texture->getBackendTexture());