Cinema 4D R20.059 bug with many RegisterShaderPlugin() calls



  • Hello everyone,
    After update to this build there is a bug:

    1. say there is Windows 7 or 10
    2. you have cinema4dsdk project, which complies and works fine
    3. remove everything from cinema4dsdk except main.cpp
    4. make ShaderData class with all just blank member function bodies and calls to super::
    5. register 30 shader plugins: call RegisterShaderPlugin 30 times with different names, with incrementing PLUGIN IDS every time with allocated ShaderData. Compile - Cinema 4D launches with these 30 plugins.
    6. Do the same as #5 but 40 times (40 shader plugins) and then Cinema 4D doesn't launch and stalls at plugin loading message.
    7. Do the same as #6 but 50 times (50 shader plugins) and then Cinema 4D launches well and all the plugins are visible.

    In real apps this means that one alone 3rd party renderer plugin launches with Cinema. The other alone also launces. But if you place them both to the plugin folder they may crash Cinema at launch.

    There was no such problem at R20.030 and R20.057... Wasted a day to investigate this.



  • Hi Aaron, thanks for reaching out us.

    With regard to the mentioned issue, although I carefully followed your steps, I wasn't able to reproduce the unexpected behavior.

    I've executed the test both on Windows 10 / C4D 20.059 and on macOS 10.13.6 / C4D 20.059. In both OSes I've successfully executed Cinema with 30, 40 and 50 shaders without stalls or crashes.

    Please find here an archive containing the plugin project I've used to reproduce the behavior. To use it copy in the <path to 20.059>/sdk/plugins folder, unzip and run the ProjectTool in order to regenerate the project.

    Looking forward further comment of yours, give best.

    Riccardo



  • @r_gigante Hi Riccardo! Thanks for help! Actually, your code doesn't reproduce the issue. Have a look at my code too:
    https://www.dropbox.com/s/opwo59utbiup3ks/test.rar?dl=0
    There you will find the generated shader resource files + plugin code + xdll for windows (I don't have mac yet).

    One interesting note is that there is no problem on Cinema R20.059 Demo (I have downloaded R20.057 from Maxon website and then updated to R20.059 using online update). But few users who have updated their non-demo C4D reported a bug with these issues and I have tested it with them using TeamViewer. It looks strange. The issue however seems to be solved when we use

    SetPluginPriority(data, C4DPL_INIT_PRIORITY_PLUGINS);
    

    instead of

    SetPluginPriority(data, C4DPL_INIT_PRIORITY_ADVANCEDRENDER);
    

    I don't remember why and when I started using priority C4DPL_INIT_PRIORITY_ADVANCEDRENDER. Somewhere from pluginscafe advice or maybe the whole system is a 3rd party renderer. But it was ok all the time.

    Here is the code from my example (see comments there):

    /*
     There was no problem in the cases described here for R20.057 or earlier. 
     But this example doesn't launch Cinema when copied to the plugins folder of Windows (7 or 10) + Cinema R20.059.
     Note that there should be no any other plugins in the C4D/plugins folder.
     Note that this example doesn't launch if it has 40 shaders (but launces if it has 30 or 50 shaders). 
     Note that this example successfully launches Cinema if you use SetPluginPriority(data, C4DPL_INIT_PRIORITY_PLUGINS); instead of C4DPL_INIT_PRIORITY_ADVANCEDRENDER (see below)
     Read comments in the code below.
    */
    
    #include "c4d.h"
    #include "c4d_symbols.h"
    
    #define TEST_PLUGIN_ID	1055000
    
    class xshaderTest : public ShaderData
    {
    	INSTANCEOF(xshaderTest, ShaderData)
    
    public:
    	virtual Bool Init(GeListNode* node);
    	virtual Bool Message(GeListNode* node, Int32 type, void* data);
    	virtual	Vector Output(BaseShader* chn, ChannelData* cd);
    
    	virtual	INITRENDERRESULT InitRender(BaseShader* chn, const InitRenderStruct& irs);
    	virtual	void FreeRender(BaseShader* chn);
    
    	static NodeData * Alloc(void) { return NewObjClear(xshaderTest); }   
    };
    
    Bool xshaderTest::Init(GeListNode* node)
    {
    	return ShaderData::Init(node);
    }
    
    Vector xshaderTest::Output(BaseShader* chn, ChannelData* cd)
    {
    	return Vector(0.0);
    }
    
    INITRENDERRESULT xshaderTest::InitRender(BaseShader* chn, const InitRenderStruct& irs)
    {
    	return INITRENDERRESULT::OK;
    }
    
    void xshaderTest::FreeRender(BaseShader* chn)
    {
    }
    
    Bool xshaderTest::Message(GeListNode* node, Int32 type, void* msgdat)
    {
    	return ShaderData::Message(node, type, msgdat);
    }
    
    /*
    #include <windows.h>
    
    static const WORD MAX_CONSOLE_LINES = 500;
    inline void RedirectIOToConsole()
    {
    	// create the console (see https://stackoverflow.com/questions/32185512/output-to-console-from-a-win32-gui-application-on-windows-10)
    	if (AllocConsole()) {
    		FILE* pCout;
    		freopen_s(&pCout, "CONOUT$", "w", stdout);
    		SetConsoleTitle(L"Debug Console");
    		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
    	//	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
    	}
    }
    */
    
    Bool PluginStart(void)
    {
    	// generate different shader resource files and move them in the res folder of the plugin
    	// uncomment to generate files again
    /*	FILE * f = 0;
    	char shader_name[1024];
    	char shader_desc[1024];
    
    	for (int i = 0; i < 50; i++)
    	{
    		sprintf_s(shader_name, 1024, "F:\\testshaders\\test_shader%d_res.res", i, i, i, i);
    		sprintf_s(shader_desc, 1024, "CONTAINER test_shader%d_res \n{\n  NAME test_shader%d_res;\n  GROUP TEST_SHADER%d_GROUP {\n    DEFAULT 1;\n    VECTOR TEST_SHADER%d_DATA { UNIT REAL; STEP 0.01; }\n  }\n}\n", i, i, i, i);
    		size_t strsize = strlen(shader_desc);
    
    		fopen_s(&f, shader_name, "w");
    		size_t written = fwrite(shader_desc, 1, strsize, f);
    		fclose(f);
    
    	//	printf("\n %2d: strsize %3d written %3d", i, int(strsize), int(written));
    	}
    
    	for (int i = 0; i < 50; i++)
    	{
    		sprintf_s(shader_name, 1024, "F:\\testshaders\\test_shader%d_res.h", i, i, i, i);
    		sprintf_s(shader_desc, 1024, "#ifndef TEST_SHADER%d_RES_H__\n#define TEST_SHADER%d_RES_H__\n enum \n { \n    TEST_SHADER%d_GROUP = 10000, \n    TEST_SHADER%d_DATA = 10100,\n };\n#endif", i, i, i, i);
    		size_t strsize = strlen(shader_desc);
    
    		fopen_s(&f, shader_name, "w");
    		size_t written = fwrite(shader_desc, 1, strsize, f);
    		fclose(f);
    
    	//	printf("\n %2d: strsize %3d written %3d", i, int(strsize), int(written));
    	}
    
    	for (int i = 0; i < 50; i++)
    	{
    		sprintf_s(shader_name, 1024, "F:\\testshaders\\test_shader%d_res.str", i, i, i, i);
    		sprintf_s(shader_desc, 1024, "STRINGTABLE test_shader%d_res \n{ \n  test_shader%d_res \"test_shader%d_res\"; \n  TEST_SHADER%d_GROUP \"test_shader%d_res\"; \n  TEST_SHADER%d_DATA \"test_shader%d_res\"; \n}", i, i, i, i, i, i, i);
    		size_t strsize = strlen(shader_desc);
    
    		fopen_s(&f, shader_name, "w");
    		size_t written = fwrite(shader_desc, 1, strsize, f);
    		fclose(f);
    
    	//	printf("\n %2d: strsize %3d written %3d", i, int(strsize), int(written));
    	}*/
    
    	VERSIONTYPE versionType = GeGetVersionType();
    
    //	RedirectIOToConsole();
    
    	// register shaders
    //	for (int i = 0; i < 30; i++) // Cinema is launching
    //	for (int i = 0; i < 50; i++) // Cinema is launching
    	for (int i = 0; i < 40; i++) // Cinema is NOT launching if you use SetPluginPriority(data, C4DPL_INIT_PRIORITY_ADVANCEDRENDER);
    	{
    		String resfile = String("test_shader") + String::IntToString(i) + String("_res");
    		RegisterShaderPlugin(TEST_PLUGIN_ID + i, resfile, 0, xshaderTest::Alloc, resfile, 0);
    	}
    
    	return true; 
    }
    
    void PluginEnd(void)
    {
    }
    
    Bool PluginMessage(Int32 id, void* data)
    {
    	switch (id)
    	{
    		case C4DPL_INIT_SYS:
    		{
    		//	RedirectIOToConsole();
    
    			if (!g_resource.Init())
    				return false;
    
    			return true;
    		}
    
    		case C4DMSG_PRIORITY:
    		{
    			SetPluginPriority(data, C4DPL_INIT_PRIORITY_ADVANCEDRENDER);	// Cinema is NOT launching if you use 40 shaders
    
    		//	SetPluginPriority(data, C4DPL_INIT_PRIORITY_PLUGINS);			// Cinema launches even if you use 40 shaders and priority is set to this. 
    																			// But if you add unchanged compiled c4dsdkplugins to the C4D plugins folder 
    																			// then Cinema will not launch with 2 plugins like c4dsdkplugins and test (which has  40 shaders)
    
    			return true;
    		}
    	}
    
    	return false;
    }
    


  • Hi Aaron, thanks for following up.

    I've downloaded and run your code "as it is" on:

    • Windows 10 / Cinema 4D (20.057 updated via online updater to 20.059);
    • Windows 10 / Cinema 4D (20.059 internal debug version);
    • macOS 10.16 / Cinema 4D (20.059 internal debug version);

    and in not a single case I've been able to reproduce the stall as from this video.

    Since it looks like that on a clean installation it works flawlessly (you actually managed to achieve this with the demo) we need more information on what's happening on your customers' side.

    Looking forward feedback, give best.
    Riccardo



  • Hi Riccardo, thank you for help! Do you have any other shader plugin in the plugins/ folder?
    I had 2 reports about a problem of not launching Cinema R20 after update to 059. Originally I thought that the problem was the large 80MB size of resulting CentiLeo renderer xdll64 (my plugin) where I statically linked all dependencies. One user hasn't replied on further questions about the problem but the other one has helped to investigate.
    For example when plugins folder had:

    1. only Octane 4 demo - Cinema was launching,
    2. only Arnold 5.3 GPU beta - not launching,
    3. only our CentiLeo - not launching,
    4. only Octane and CentiLeo - Cinema was launching.
    5. when c4dsdkplugins were combined there - also different results.

    And that second user has also told that his Cinema 4D R20 version is a cracked pack from cgpersia which he has updated to 059 with usual C4D updater. So this can be the easy explanation of a problem. It's strange that before update things were ok. However I don't know how the cracks are working and what has influenced. At least the factors that I have found like different number of plugins and plugin priority seem not logical for me.



  • Hi Aaron,

    Hi Riccardo, thank you for help! Do you have any other shader plugin in the plugins/ folder?

    No, not any other single plugin

    when c4dsdkplugins were combined there - also different results.

    Also here I found nothing unexpected: either with or without the cinema4dsdk plugins being compiled I had no stall in loading Cinema 4D.

    Last with regard to the cracked version, I can't comment.

    Best, Riccardo



  • Hi Riccardo, I think the issue is solved because there is no any issue. Some not good methods of software distribution just confused us.
    Btw, what benefits different parameters of SetPluginPriority() give to us? For example the xdll has several plugins like materials, shader, tags and renderer. Even some icons with plugin ids. What priority is better to use in this case? I see https://developers.maxon.net/docs/Cinema4DCPPSDK/html/page_manual_module_functions.html
    For example, what is C4DPL_INIT_PRIORITY_ADVANCEDRENDER:

    1. Does it give higher thread priority during some PV rendering task?
    2. Or does it just load the plugin before other renderers and give the chance to lock system resources before others?