--- /dev/null 2019-05-16 19:17:18.000000000 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m 2019-05-16 19:17:18.000000000 +0300 @@ -0,0 +1,92 @@ +#import "MTLTexturePool.h" +#import "Trace.h" + +@implementation MTLTexturePoolItem + +@synthesize texture; +@synthesize isBusy; + +- (id) initWithTexture:(id)tex { + self = [super init]; + if (self == nil) return self; + self.texture = tex; + isBusy = NO; + return self; +} +@end + +@implementation MTLTexturePool + +@synthesize device; +@synthesize pool; + +- (id) initWithDevice:(id)dev { + self = [super init]; + if (self == nil) return self; + + self.device = dev; + self.pool = [NSMutableArray arrayWithCapacity:10]; + return self; +} + +// NOTE: called from RQ-thread (on blit operations) +- (id) getTexture:(int)width height:(int)height format:(MTLPixelFormat)format { + @synchronized (self) { + // 1. find free item + // TODO: optimize search, use Map<(w,h,pf), TexPoolItem> + const int count = [self.pool count]; + for (int c = 0; c < count; ++c) { + MTLTexturePoolItem *tpi = [self.pool objectAtIndex:c]; + if (tpi == nil) + continue; + // TODO: use checks tpi.texture.width <= width && tpi.texture.height <= height + if (tpi.texture.width == width && tpi.texture.height == height && tpi.texture.pixelFormat == format && + !tpi.isBusy) { + tpi.isBusy = YES; + return tpi.texture; + } + } + + // 2. create + MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format width:width height:height mipmapped:NO]; + id tex = [self.device newTextureWithDescriptor:textureDescriptor]; + MTLTexturePoolItem *tpi = [[MTLTexturePoolItem alloc] initWithTexture:tex]; + [self.pool addObject:tpi]; + J2dTraceLn4(J2D_TRACE_VERBOSE, "MTLTexturePool: created pool item: tex=%p, w=%d h=%d, pf=%d", tex, width, height, format); + return tpi.texture; + } +}; + +// NOTE: called from completion-handler (pooled thread) +- (void) markTextureFree:(id)texture { + // TODO: optimize search, use Map<(w,h,pf), TexPoolItem> + @synchronized (self) { + const int count = [self.pool count]; + for (int c = 0; c < count; ++c) { + MTLTexturePoolItem * tpi = [self.pool objectAtIndex:c]; + if (tpi == nil) + continue; + if (tpi.texture == texture) { + tpi.isBusy = NO; + return; + } + } + J2dTraceLn1(J2D_TRACE_ERROR, "MTLTexturePool: can't find item with texture %p", texture); + } +} + +// NOTE: called from completion-handler (pooled thread) +- (void) markAllTexturesFree { + @synchronized (self) { + const int count = [self.pool count]; + for (int c = 0; c < count; ++c) { + MTLTexturePoolItem *tpi = [self.pool objectAtIndex:c]; + if (tpi == nil) + continue; + tpi.isBusy = NO; + } + } +} + + +@end \ No newline at end of file