TextureCache.hx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package h3d.impl;
  2. class TextureCache {
  3. var cache : Array<h3d.mat.Texture>;
  4. var position : Int = 0;
  5. var defaultDepthBuffer : h3d.mat.Texture;
  6. public var defaultFormat : hxd.PixelFormat;
  7. public function new() {
  8. cache = [];
  9. var engine = h3d.Engine.getCurrent();
  10. defaultFormat = h3d.mat.Texture.nativeFormat;
  11. defaultDepthBuffer = h3d.mat.Texture.getDefaultDepth();
  12. }
  13. public inline function get( index = 0 ) {
  14. return cache[index];
  15. }
  16. public function getNamed( name : String ) {
  17. for( i in 0...position )
  18. if( cache[i].name == name )
  19. return cache[i];
  20. return null;
  21. }
  22. public function set( t, index ) {
  23. cache[index] = t;
  24. }
  25. public function begin() {
  26. // dispose extra textures we didn't use in previous run
  27. while( cache.length > position ) {
  28. var t = cache.pop();
  29. if( t != null ) t.dispose();
  30. }
  31. position = 0;
  32. }
  33. function lookupTarget( name, width, height, format, flags : Array<h3d.mat.Data.TextureFlags> ) {
  34. var t = cache[position];
  35. // look for a suitable candidate
  36. for( i in position+1...cache.length ) {
  37. var t2 = cache[i];
  38. if( t2 != null && !t2.isDisposed() && t2.width == width && t2.height == height && t2.format == format ) {
  39. if ( flags != null ) {
  40. var fitFlags = true;
  41. for ( f in flags ) {
  42. if ( !t2.flags.has(f) ) {
  43. fitFlags = false;
  44. break;
  45. }
  46. }
  47. if ( !fitFlags )
  48. continue;
  49. }
  50. // swap
  51. cache[position] = t2;
  52. cache[i] = t;
  53. return t2;
  54. }
  55. }
  56. // same name, most likely resolution changed, dispose before allocating new
  57. if( t != null && t.name == name ) {
  58. t.dispose();
  59. t = null;
  60. }
  61. if ( flags == null ) flags = [];
  62. if ( !flags.contains(Target) )
  63. flags.push(Target);
  64. var newt = new h3d.mat.Texture(width, height, flags, format);
  65. // make the texture disposable if we're out of memory
  66. newt.realloc = function() {};
  67. if( t != null )
  68. cache.insert(position,newt);
  69. else
  70. cache[position] = newt;
  71. return newt;
  72. }
  73. public function allocTarget( name : String, width : Int, height : Int, defaultDepth=true, ?format:hxd.PixelFormat, flags : Array<h3d.mat.Data.TextureFlags> = null ) {
  74. var t = cache[position];
  75. if( format == null ) format = defaultFormat;
  76. var alloc = false;
  77. if( t == null || t.isDisposed() || t.width != width || t.height != height || t.format != format )
  78. alloc = true;
  79. if ( !alloc && flags != null ) {
  80. for ( f in flags ) {
  81. if ( !t.flags.has(f) ) {
  82. alloc = true;
  83. break;
  84. }
  85. }
  86. }
  87. if ( alloc )
  88. t = lookupTarget(name,width,height,format,flags);
  89. t.depthBuffer = defaultDepth ? defaultDepthBuffer : null;
  90. t.setName(name);
  91. position++;
  92. return t;
  93. }
  94. public function allocTargetScale( name : String, scale : Float, defaultDepth=true, ?format:hxd.PixelFormat ) {
  95. var e = h3d.Engine.getCurrent();
  96. return allocTarget(name, Math.ceil(e.width * scale), Math.ceil(e.height * scale), defaultDepth, format);
  97. }
  98. public function allocTileTarget( name : String, tile : h2d.Tile, defaultDepth=false, ?format:hxd.PixelFormat ) {
  99. return allocTarget( name, tile.iwidth, tile.iheight, defaultDepth, format );
  100. }
  101. public function dispose() {
  102. for( t in cache )
  103. t.dispose();
  104. cache = [];
  105. }
  106. }