CCConfiguration.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /****************************************************************************
  2. Copyright (c) 2010 Ricardo Quesada
  3. Copyright (c) 2010-2012 cocos2d-x.org
  4. Copyright (c) 2013-2016 Chukong Technologies Inc.
  5. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
  6. http://www.cocos2d-x.org
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. ****************************************************************************/
  23. #include "base/CCConfiguration.h"
  24. #include "platform/CCFileUtils.h"
  25. #include "base/CCEventCustom.h"
  26. #include "base/CCDirector.h"
  27. #include "base/CCEventDispatcher.h"
  28. NS_CC_BEGIN
  29. extern const char* cocos2dVersion();
  30. Configuration* Configuration::s_sharedConfiguration = nullptr;
  31. const char* Configuration::CONFIG_FILE_LOADED = "config_file_loaded";
  32. Configuration::Configuration()
  33. : _maxTextureSize(0)
  34. , _maxModelviewStackDepth(0)
  35. , _supportsPVRTC(false)
  36. , _supportsETC1(false)
  37. , _supportsS3TC(false)
  38. , _supportsATITC(false)
  39. , _supportsNPOT(false)
  40. , _supportsBGRA8888(false)
  41. , _supportsDiscardFramebuffer(false)
  42. , _supportsShareableVAO(false)
  43. , _supportsOESDepth24(false)
  44. , _supportsOESPackedDepthStencil(false)
  45. , _supportsOESMapBuffer(false)
  46. , _maxSamplesAllowed(0)
  47. , _maxTextureUnits(0)
  48. , _glExtensions(nullptr)
  49. , _maxDirLightInShader(1)
  50. , _maxPointLightInShader(1)
  51. , _maxSpotLightInShader(1)
  52. , _animate3DQuality(Animate3DQuality::QUALITY_LOW)
  53. {
  54. _loadedEvent = new (std::nothrow) EventCustom(CONFIG_FILE_LOADED);
  55. }
  56. bool Configuration::init()
  57. {
  58. _valueDict["cocos2d.x.version"] = Value(cocos2dVersion());
  59. #if CC_ENABLE_PROFILERS
  60. _valueDict["cocos2d.x.compiled_with_profiler"] = Value(true);
  61. #else
  62. _valueDict["cocos2d.x.compiled_with_profiler"] = Value(false);
  63. #endif
  64. #if CC_ENABLE_GL_STATE_CACHE == 0
  65. _valueDict["cocos2d.x.compiled_with_gl_state_cache"] = Value(false);
  66. #else
  67. _valueDict["cocos2d.x.compiled_with_gl_state_cache"] = Value(true);
  68. #endif
  69. #if COCOS2D_DEBUG
  70. _valueDict["cocos2d.x.build_type"] = Value("DEBUG");
  71. #else
  72. _valueDict["cocos2d.x.build_type"] = Value("RELEASE");
  73. #endif
  74. return true;
  75. }
  76. Configuration::~Configuration()
  77. {
  78. CC_SAFE_DELETE(_loadedEvent);
  79. }
  80. std::string Configuration::getInfo() const
  81. {
  82. // And Dump some warnings as well
  83. #if CC_ENABLE_PROFILERS
  84. CCLOG("cocos2d: **** WARNING **** CC_ENABLE_PROFILERS is defined. Disable it when you finish profiling (from ccConfig.h)\n");
  85. #endif
  86. #if CC_ENABLE_GL_STATE_CACHE == 0
  87. CCLOG("cocos2d: **** WARNING **** CC_ENABLE_GL_STATE_CACHE is disabled. To improve performance, enable it (from ccConfig.h)\n");
  88. #endif
  89. // Dump
  90. Value forDump = Value(_valueDict);
  91. return forDump.getDescription();
  92. }
  93. void Configuration::gatherGPUInfo()
  94. {
  95. _valueDict["gl.vendor"] = Value((const char*)glGetString(GL_VENDOR));
  96. _valueDict["gl.renderer"] = Value((const char*)glGetString(GL_RENDERER));
  97. _valueDict["gl.version"] = Value((const char*)glGetString(GL_VERSION));
  98. _glExtensions = (char *)glGetString(GL_EXTENSIONS);
  99. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize);
  100. _valueDict["gl.max_texture_size"] = Value((int)_maxTextureSize);
  101. glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &_maxTextureUnits);
  102. _valueDict["gl.max_texture_units"] = Value((int)_maxTextureUnits);
  103. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  104. glGetIntegerv(GL_MAX_SAMPLES_APPLE, &_maxSamplesAllowed);
  105. _valueDict["gl.max_samples_allowed"] = Value((int)_maxSamplesAllowed);
  106. #endif
  107. _supportsETC1 = checkForGLExtension("GL_OES_compressed_ETC1_RGB8_texture");
  108. _valueDict["gl.supports_ETC1"] = Value(_supportsETC1);
  109. _supportsS3TC = checkForGLExtension("GL_EXT_texture_compression_s3tc");
  110. _valueDict["gl.supports_S3TC"] = Value(_supportsS3TC);
  111. _supportsATITC = checkForGLExtension("GL_AMD_compressed_ATC_texture");
  112. _valueDict["gl.supports_ATITC"] = Value(_supportsATITC);
  113. _supportsPVRTC = checkForGLExtension("GL_IMG_texture_compression_pvrtc");
  114. _valueDict["gl.supports_PVRTC"] = Value(_supportsPVRTC);
  115. _supportsNPOT = true;
  116. _valueDict["gl.supports_NPOT"] = Value(_supportsNPOT);
  117. _supportsBGRA8888 = checkForGLExtension("GL_IMG_texture_format_BGRA8888");
  118. _valueDict["gl.supports_BGRA8888"] = Value(_supportsBGRA8888);
  119. _supportsDiscardFramebuffer = checkForGLExtension("GL_EXT_discard_framebuffer");
  120. _valueDict["gl.supports_discard_framebuffer"] = Value(_supportsDiscardFramebuffer);
  121. #ifdef CC_PLATFORM_PC
  122. _supportsShareableVAO = checkForGLExtension("vertex_array_object");
  123. #else
  124. _supportsShareableVAO = checkForGLExtension("GL_OES_vertex_array_object");
  125. #endif
  126. _valueDict["gl.supports_vertex_array_object"] = Value(_supportsShareableVAO);
  127. _supportsOESMapBuffer = checkForGLExtension("GL_OES_mapbuffer");
  128. _valueDict["gl.supports_OES_map_buffer"] = Value(_supportsOESMapBuffer);
  129. _supportsOESDepth24 = checkForGLExtension("GL_OES_depth24");
  130. _valueDict["gl.supports_OES_depth24"] = Value(_supportsOESDepth24);
  131. _supportsOESPackedDepthStencil = checkForGLExtension("GL_OES_packed_depth_stencil");
  132. _valueDict["gl.supports_OES_packed_depth_stencil"] = Value(_supportsOESPackedDepthStencil);
  133. CHECK_GL_ERROR_DEBUG();
  134. }
  135. Configuration* Configuration::getInstance()
  136. {
  137. if (! s_sharedConfiguration)
  138. {
  139. s_sharedConfiguration = new (std::nothrow) Configuration();
  140. s_sharedConfiguration->init();
  141. }
  142. return s_sharedConfiguration;
  143. }
  144. void Configuration::destroyInstance()
  145. {
  146. CC_SAFE_RELEASE_NULL(s_sharedConfiguration);
  147. }
  148. // FIXME: deprecated
  149. Configuration* Configuration::sharedConfiguration()
  150. {
  151. return Configuration::getInstance();
  152. }
  153. // FIXME: deprecated
  154. void Configuration::purgeConfiguration()
  155. {
  156. Configuration::destroyInstance();
  157. }
  158. bool Configuration::checkForGLExtension(const std::string &searchName) const
  159. {
  160. return (_glExtensions && strstr(_glExtensions, searchName.c_str() ) ) ? true : false;
  161. }
  162. //
  163. // getters for specific variables.
  164. // Maintained for backward compatibility reasons only.
  165. //
  166. int Configuration::getMaxTextureSize() const
  167. {
  168. return _maxTextureSize;
  169. }
  170. int Configuration::getMaxModelviewStackDepth() const
  171. {
  172. return _maxModelviewStackDepth;
  173. }
  174. int Configuration::getMaxTextureUnits() const
  175. {
  176. return _maxTextureUnits;
  177. }
  178. bool Configuration::supportsNPOT() const
  179. {
  180. return _supportsNPOT;
  181. }
  182. bool Configuration::supportsPVRTC() const
  183. {
  184. return _supportsPVRTC;
  185. }
  186. bool Configuration::supportsETC() const
  187. {
  188. //GL_ETC1_RGB8_OES is not defined in old opengl version
  189. #ifdef GL_ETC1_RGB8_OES
  190. return _supportsETC1;
  191. #else
  192. return false;
  193. #endif
  194. }
  195. bool Configuration::supportsS3TC() const
  196. {
  197. #ifdef GL_EXT_texture_compression_s3tc
  198. return _supportsS3TC;
  199. #else
  200. return false;
  201. #endif
  202. }
  203. bool Configuration::supportsATITC() const
  204. {
  205. return _supportsATITC;
  206. }
  207. bool Configuration::supportsBGRA8888() const
  208. {
  209. return _supportsBGRA8888;
  210. }
  211. bool Configuration::supportsDiscardFramebuffer() const
  212. {
  213. return _supportsDiscardFramebuffer;
  214. }
  215. bool Configuration::supportsShareableVAO() const
  216. {
  217. #if CC_TEXTURE_ATLAS_USE_VAO
  218. return _supportsShareableVAO;
  219. #else
  220. return false;
  221. #endif
  222. }
  223. bool Configuration::supportsMapBuffer() const
  224. {
  225. // Fixes Github issue #16123
  226. //
  227. // XXX: Fixme. Should check GL ES and not iOS or Android
  228. // For example, linux could be compiled with GL ES. Or perhaps in the future Android will
  229. // support OpenGL. This is because glMapBufferOES() is an extension of OpenGL ES. And glMapBuffer()
  230. // is always implemented in OpenGL.
  231. // XXX: Warning. On iOS this is always `true`. Avoiding the comparison.
  232. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
  233. return _supportsOESMapBuffer;
  234. #else
  235. return true;
  236. #endif
  237. }
  238. bool Configuration::supportsOESDepth24() const
  239. {
  240. return _supportsOESDepth24;
  241. }
  242. bool Configuration::supportsOESPackedDepthStencil() const
  243. {
  244. return _supportsOESPackedDepthStencil;
  245. }
  246. int Configuration::getMaxSupportDirLightInShader() const
  247. {
  248. return _maxDirLightInShader;
  249. }
  250. int Configuration::getMaxSupportPointLightInShader() const
  251. {
  252. return _maxPointLightInShader;
  253. }
  254. int Configuration::getMaxSupportSpotLightInShader() const
  255. {
  256. return _maxSpotLightInShader;
  257. }
  258. Animate3DQuality Configuration::getAnimate3DQuality() const
  259. {
  260. return _animate3DQuality;
  261. }
  262. //
  263. // generic getters for properties
  264. //
  265. const Value& Configuration::getValue(const std::string& key, const Value& defaultValue) const
  266. {
  267. auto iter = _valueDict.find(key);
  268. if (iter != _valueDict.cend())
  269. return _valueDict.at(key);
  270. return defaultValue;
  271. }
  272. void Configuration::setValue(const std::string& key, const Value& value)
  273. {
  274. _valueDict[key] = value;
  275. }
  276. //
  277. // load file
  278. //
  279. void Configuration::loadConfigFile(const std::string& filename)
  280. {
  281. ValueMap dict = FileUtils::getInstance()->getValueMapFromFile(filename);
  282. CCASSERT(!dict.empty(), "cannot create dictionary");
  283. // search for metadata
  284. bool validMetadata = false;
  285. auto metadataIter = dict.find("metadata");
  286. if (metadataIter != dict.cend() && metadataIter->second.getType() == Value::Type::MAP)
  287. {
  288. const auto& metadata = metadataIter->second.asValueMap();
  289. auto formatIter = metadata.find("format");
  290. if (formatIter != metadata.cend())
  291. {
  292. int format = formatIter->second.asInt();
  293. // Support format: 1
  294. if (format == 1)
  295. {
  296. validMetadata = true;
  297. }
  298. }
  299. }
  300. if (! validMetadata)
  301. {
  302. CCLOG("Invalid config format for file: %s", filename.c_str());
  303. return;
  304. }
  305. auto dataIter = dict.find("data");
  306. if (dataIter == dict.cend() || dataIter->second.getType() != Value::Type::MAP)
  307. {
  308. CCLOG("Expected 'data' dict, but not found. Config file: %s", filename.c_str());
  309. return;
  310. }
  311. // Add all keys in the existing dictionary
  312. const auto& dataMap = dataIter->second.asValueMap();
  313. for (const auto& dataMapIter : dataMap)
  314. {
  315. if (_valueDict.find(dataMapIter.first) == _valueDict.cend())
  316. _valueDict[dataMapIter.first] = dataMapIter.second;
  317. else
  318. CCLOG("Key already present. Ignoring '%s'",dataMapIter.first.c_str());
  319. }
  320. //light info
  321. std::string name = "cocos2d.x.3d.max_dir_light_in_shader";
  322. if (_valueDict.find(name) != _valueDict.end())
  323. _maxDirLightInShader = _valueDict[name].asInt();
  324. else
  325. _valueDict[name] = Value(_maxDirLightInShader);
  326. name = "cocos2d.x.3d.max_point_light_in_shader";
  327. if (_valueDict.find(name) != _valueDict.end())
  328. _maxPointLightInShader = _valueDict[name].asInt();
  329. else
  330. _valueDict[name] = Value(_maxPointLightInShader);
  331. name = "cocos2d.x.3d.max_spot_light_in_shader";
  332. if (_valueDict.find(name) != _valueDict.end())
  333. _maxSpotLightInShader = _valueDict[name].asInt();
  334. else
  335. _valueDict[name] = Value(_maxSpotLightInShader);
  336. name = "cocos2d.x.3d.animate_quality";
  337. if (_valueDict.find(name) != _valueDict.end())
  338. _animate3DQuality = (Animate3DQuality)_valueDict[name].asInt();
  339. else
  340. _valueDict[name] = Value((int)_animate3DQuality);
  341. Director::getInstance()->getEventDispatcher()->dispatchEvent(_loadedEvent);
  342. }
  343. NS_CC_END