TextureCache.hx 3.6 KB

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