MLRTexturePool.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include "MLRHeaders.hpp"
  5. MLRTexturePool *MLRTexturePool::Instance;
  6. MLRTexturePool::ClassData*
  7. MLRTexturePool::DefaultData = NULL;
  8. //#############################################################################
  9. //############################ MLRTexture ###############################
  10. //#############################################################################
  11. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  12. //
  13. void
  14. MLRTexturePool::InitializeClass()
  15. {
  16. Verify(!DefaultData);
  17. Verify(gos_GetCurrentHeap() == StaticHeap);
  18. DefaultData =
  19. new ClassData(
  20. MLRTexturePoolClassID,
  21. "MidLevelRenderer::MLRTexturePool",
  22. RegisteredClass::DefaultData
  23. );
  24. Register_Object(DefaultData);
  25. MLRTexturePool::Instance = NULL;
  26. }
  27. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  28. //
  29. void
  30. MLRTexturePool::TerminateClass()
  31. {
  32. if (MLRTexturePool::Instance)
  33. {
  34. Unregister_Object(MLRTexturePool::Instance);
  35. delete MLRTexturePool::Instance;
  36. }
  37. Unregister_Object(DefaultData);
  38. delete DefaultData;
  39. DefaultData = NULL;
  40. }
  41. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  42. //
  43. MLRTexturePool::MLRTexturePool(MemoryStream *stream):
  44. RegisteredClass(DefaultData)
  45. {
  46. Verify(gos_GetCurrentHeap() == Heap);
  47. unLoadedImages = false;
  48. STOP(("Not implemented"));
  49. }
  50. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  51. //
  52. void MLRTexturePool::Stop (void)
  53. {
  54. Verify(gos_GetCurrentHeap() == Heap);
  55. int i;
  56. for(i=0;i<MLRState::TextureMask;i++)
  57. {
  58. if(textureArray[i] != NULL)
  59. {
  60. Unregister_Object(textureArray[i]);
  61. delete textureArray[i];
  62. textureArray[i] = NULL;
  63. }
  64. }
  65. Unregister_Pointer(freeHandle);
  66. delete [] freeHandle;
  67. }
  68. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  69. //
  70. void MLRTexturePool::Restart (void)
  71. {
  72. Verify(gos_GetCurrentHeap() == Heap);
  73. freeHandle = new int [handleMax];
  74. Register_Pointer(freeHandle);
  75. lastHandle = 0;
  76. firstFreeHandle = 0;
  77. lastFreeHandle = 0;
  78. storedTextures = 0;
  79. for(int i=0;i<MLRState::TextureMask+1;i++)
  80. {
  81. textureArray[i] = NULL;
  82. }
  83. unLoadedImages = false;
  84. }
  85. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  86. //
  87. MLRTexturePool::MLRTexturePool(GOSImagePool *image_pool, int insDep):
  88. RegisteredClass(DefaultData)
  89. {
  90. Check_Object(image_pool);
  91. Verify(gos_GetCurrentHeap() == Heap);
  92. instanceDepth = insDep;
  93. instanceMax = 1<<insDep;
  94. handleDepth = MLRState::TextureNumberBits - insDep;
  95. handleMax = 1<<handleDepth;
  96. freeHandle = new int [handleMax];
  97. Register_Pointer(freeHandle);
  98. lastHandle = 0;
  99. firstFreeHandle = 0;
  100. lastFreeHandle = 0;
  101. storedTextures = 0;
  102. imagePool = image_pool;
  103. for(int i=0;i<MLRState::TextureMask+1;i++)
  104. {
  105. textureArray[i] = NULL;
  106. }
  107. unLoadedImages = false;
  108. }
  109. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  110. //
  111. MLRTexturePool::~MLRTexturePool()
  112. {
  113. int i;
  114. for(i=0;i<MLRState::TextureMask;i++)
  115. {
  116. if(textureArray[i] != NULL)
  117. {
  118. Unregister_Object(textureArray[i]);
  119. delete textureArray[i];
  120. textureArray[i] = NULL;
  121. }
  122. }
  123. Unregister_Object(imagePool);
  124. delete imagePool;
  125. Unregister_Pointer(freeHandle);
  126. delete [] freeHandle;
  127. }
  128. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  129. //
  130. MLRTexturePool*
  131. MLRTexturePool::Make(MemoryStream *stream)
  132. {
  133. Check_Object(stream);
  134. gos_PushCurrentHeap(Heap);
  135. MLRTexturePool *pool = new MLRTexturePool(stream);
  136. gos_PopCurrentHeap();
  137. return pool;
  138. }
  139. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  140. //
  141. void
  142. MLRTexturePool::Save(MemoryStream *stream)
  143. {
  144. STOP(("Not implemented"));
  145. }
  146. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. //
  148. MLRTexture*
  149. MLRTexturePool::Add(const char *tn, int instance)
  150. {
  151. MString textureName(tn);
  152. int i, j, textureNameHashValue = textureName.GetHashValue();
  153. for(i=0;i<lastHandle;i++)
  154. {
  155. int first = i<<instanceDepth;
  156. bool yo = false;
  157. for(j=first;j<first+instanceMax;j++)
  158. {
  159. if( textureArray[j] &&
  160. textureArray[j]->textureNameHashValue == textureNameHashValue )
  161. {
  162. yo = 1;
  163. }
  164. }
  165. if(yo == false)
  166. {
  167. continue;
  168. }
  169. for(j=first;j<first+instanceMax;j++)
  170. {
  171. if( textureArray[j] &&
  172. textureArray[j]->instance == instance)
  173. {
  174. return textureArray[j];
  175. }
  176. }
  177. for(j=first;j<first+instanceMax;j++)
  178. {
  179. if(!textureArray[j])
  180. {
  181. gos_PushCurrentHeap(Heap);
  182. textureArray[j] =
  183. new MLRTexture(
  184. this,
  185. textureName,
  186. instance,
  187. j+1
  188. );
  189. Register_Object(textureArray[j]);
  190. gos_PopCurrentHeap();
  191. storedTextures++;
  192. unLoadedImages = true;
  193. return textureArray[j];
  194. }
  195. }
  196. STOP(("Asked for too much image instances !"));
  197. }
  198. int newHandle;
  199. gos_PushCurrentHeap(Heap);
  200. if(firstFreeHandle < lastFreeHandle)
  201. {
  202. newHandle = (freeHandle[firstFreeHandle&(handleMax-1)])<<instanceDepth;
  203. textureArray[newHandle] =
  204. new MLRTexture(
  205. this,
  206. textureName,
  207. instance,
  208. newHandle+1
  209. );
  210. storedTextures++;
  211. firstFreeHandle++;
  212. }
  213. else
  214. {
  215. Verify( ((lastHandle<<instanceDepth)+1) < MLRState::TextureMask );
  216. newHandle = lastHandle<<instanceDepth;
  217. textureArray[newHandle] =
  218. new MLRTexture(
  219. this,
  220. textureName,
  221. instance,
  222. newHandle+1
  223. );
  224. storedTextures++;
  225. lastHandle++;
  226. }
  227. Register_Object(textureArray[newHandle]);
  228. gos_PopCurrentHeap();
  229. unLoadedImages = true;
  230. return textureArray[newHandle];
  231. }
  232. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  233. //
  234. MLRTexture*
  235. MLRTexturePool::Add(GOSImage *image)
  236. {
  237. MString textureName;
  238. textureName = image->GetName();
  239. int i, j, textureNameHashValue = textureName.GetHashValue();
  240. for(i=0;i<lastHandle;i++)
  241. {
  242. int first = i<<instanceDepth;
  243. for(j=first;j<first+instanceMax;j++)
  244. {
  245. if( textureArray[j] &&
  246. textureArray[j]->textureNameHashValue == textureNameHashValue )
  247. {
  248. Verify(image == textureArray[j]->GetImage());
  249. return textureArray[j];
  250. // STOP(("Image allready in texture pool !"));
  251. }
  252. }
  253. }
  254. int newHandle;
  255. gos_PushCurrentHeap(Heap);
  256. if(firstFreeHandle < lastFreeHandle)
  257. {
  258. newHandle = (freeHandle[firstFreeHandle&(handleMax-1)])<<instanceDepth;
  259. textureArray[newHandle] =
  260. new MLRTexture(
  261. this,
  262. image,
  263. newHandle+1
  264. );
  265. storedTextures++;
  266. firstFreeHandle++;
  267. }
  268. else
  269. {
  270. Verify( ((lastHandle<<instanceDepth)+1) < MLRState::TextureMask );
  271. newHandle = lastHandle<<instanceDepth;
  272. textureArray[newHandle] =
  273. new MLRTexture(
  274. this,
  275. image,
  276. newHandle+1
  277. );
  278. storedTextures++;
  279. lastHandle++;
  280. }
  281. Register_Object(textureArray[newHandle]);
  282. gos_PopCurrentHeap();
  283. return textureArray[newHandle];
  284. }
  285. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  286. //
  287. void
  288. MLRTexturePool::Remove(MLRTexture *tex)
  289. {
  290. textureArray[tex->textureHandle-1] = NULL;
  291. storedTextures--;
  292. int i, first = (tex->textureHandle-1) & ~(instanceMax-1);
  293. for(i=first;i<first+instanceMax;i++)
  294. {
  295. if(textureArray[i] != NULL)
  296. {
  297. break;
  298. }
  299. }
  300. if(i >= first+instanceMax)
  301. {
  302. imagePool->RemoveImage(tex->image);
  303. tex->image = NULL;
  304. freeHandle[lastFreeHandle&(handleMax-1)] = (tex->textureHandle-1) >> instanceDepth;
  305. lastFreeHandle++;
  306. }
  307. tex->textureHandle = 0;
  308. unLoadedImages = true;
  309. }
  310. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  311. //
  312. MLRTexture*
  313. MLRTexturePool::operator()(const char *tn, int instance)
  314. {
  315. Check_Object(this);
  316. MString textureName = tn;
  317. int i, j, textureNameHashValue = textureName.GetHashValue();
  318. for(i=0;i<lastHandle;i++)
  319. {
  320. int first = i<<instanceDepth;
  321. for(j=first;j<first+instanceMax;j++)
  322. {
  323. if( textureArray[j] )
  324. {
  325. if( textureArray[j]->textureNameHashValue == textureNameHashValue )
  326. {
  327. if (textureArray[j]->instance == instance )
  328. {
  329. return textureArray[j];
  330. }
  331. }
  332. else
  333. {
  334. break;
  335. }
  336. }
  337. }
  338. }
  339. return NULL;
  340. }
  341. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  342. //
  343. unsigned
  344. MLRTexturePool::LoadImages()
  345. {
  346. Check_Object(imagePool);
  347. if(unLoadedImages == false)
  348. {
  349. return lastHandle;
  350. }
  351. //
  352. // Statistic timing function
  353. //
  354. for (unsigned i=0;i<MLRState::TextureMask+1;i++)
  355. {
  356. if(textureArray[i])
  357. {
  358. int hint;
  359. GOSImage *image = textureArray[i]->GetImage(&hint);
  360. if (image && !image->IsLoaded())
  361. {
  362. Check_Object(image);
  363. if (!imagePool->LoadImage(image, hint))
  364. {
  365. STOP(("Cannot load texture: %s!", textureArray[i]->textureName));
  366. }
  367. }
  368. }
  369. }
  370. //
  371. // End timing function
  372. //
  373. unLoadedImages = false;
  374. return lastHandle;
  375. }