Skip to content
Permalink
Browse files

8254176: Lanai: MTLTexturePool optimize lookup of expired textures

  • Loading branch information
Alexey Ushakov
Alexey Ushakov committed Oct 8, 2020
1 parent 2a5cf85 commit 43f1444ef03be8679d44cc46fe74b4f40deee632
@@ -8,14 +8,13 @@
@interface MTLTexturePoolItem : NSObject
@property (readwrite, retain) id<MTLTexture> texture;
@property (readwrite) bool isBusy;
@property (readwrite) NSTimeInterval lastUsed;
@property (readwrite) time_t lastUsed;
@property (readwrite) bool isMultiSample;
@property (readwrite, assign) MTLTexturePoolItem* prev;
@property (readwrite, retain) MTLTexturePoolItem* next;
@property (readwrite, assign) MTLPoolCell* cell;

- (id) initWithTexture:(id<MTLTexture>)tex cell:(MTLPoolCell*)cell;
- (void) releaseTexture;
@end

@interface MTLPooledTextureHandle : NSObject
@@ -36,8 +35,13 @@

@interface MTLPoolCell : NSObject
@property (readwrite, retain) MTLTexturePoolItem* available;
@property (readwrite, assign) MTLTexturePoolItem* availableTail;
@property (readwrite, retain) MTLTexturePoolItem* occupied;
- (MTLTexturePoolItem*) createItem:(id<MTLTexture>) texture;
- (MTLTexturePoolItem *)createItem:(id<MTLDevice>)dev
width:(int)width
height:(int)height
format:(MTLPixelFormat)format
isMultiSample:(bool)isMultiSample;
- (NSUInteger)cleanIfBefore:(time_t)lastUsedTimeToRemove;
- (void)releaseItem:(MTLTexturePoolItem *)item;
@end
@@ -57,12 +57,13 @@ - (void) releaseTexture {
@implementation MTLPoolCell {
NSLock* _lock;
}
@synthesize available, occupied;
@synthesize available, availableTail, occupied;

- (instancetype)init {
self = [super init];
if (self) {
self.available = nil;
self.availableTail = nil;
self.occupied = nil;
_lock = [[NSLock alloc] init];
}
@@ -74,10 +75,18 @@ - (void)occupyItem:(MTLTexturePoolItem *)item {
[item retain];
if (item.prev == nil) {
self.available = item.next;
if (item.next) item.next.prev = nil;
if (item.next) {
item.next.prev = nil;
} else {
self.availableTail = item.prev;
}
} else {
item.prev.next = item.next;
if (item.next) item.next.prev = item.prev;
if (item.next) {
item.next.prev = item.prev;
} else {
self.availableTail = item.prev;
}
item.prev = nil;
}
if (occupied) occupied.prev = item;
@@ -100,7 +109,11 @@ - (void)releaseItem:(MTLTexturePoolItem *)item {
if (item.next) item.next.prev = item.prev;
item.prev = nil;
}
if (self.available) self.available.prev = item;
if (self.available) {
self.available.prev = item;
} else {
self.availableTail = item;
}
item.next = self.available;
self.available = item;
item.isBusy = NO;
@@ -124,12 +137,16 @@ - (void)removeAvailableItem:(MTLTexturePoolItem*)item {
if (item.next) {
item.next.prev = nil;
item.next = nil;
} else {
self.availableTail = item.prev;
}
} else {
item.prev.next = item.next;
if (item.next) {
item.next.prev = item.prev;
item.next = nil;
} else {
self.availableTail = item.prev;
}
}
[item release];
@@ -146,6 +163,7 @@ - (void)removeAllItems {
cur = cur.next;
self.occupied = cur;
}
self.availableTail = nil;
}

- (MTLTexturePoolItem *)createItem:(id<MTLDevice>)dev
@@ -181,10 +199,10 @@ - (MTLTexturePoolItem *)createItem:(id<MTLDevice>)dev
- (NSUInteger)cleanIfBefore:(time_t)lastUsedTimeToRemove {
NSUInteger deallocMem = 0;
[_lock lock];
MTLTexturePoolItem *cur = available;
MTLTexturePoolItem *cur = availableTail;
@try {
while (cur != nil) {
MTLTexturePoolItem *next = cur.next;
MTLTexturePoolItem *prev = cur.prev;
if (lastUsedTimeToRemove <= 0 ||
cur.lastUsed < lastUsedTimeToRemove) {
#ifdef DEBUG
@@ -195,8 +213,10 @@ - (NSUInteger)cleanIfBefore:(time_t)lastUsedTimeToRemove {
#endif //DEBUG
deallocMem += cur.texture.width * cur.texture.height * 4;
[self removeAvailableItem:cur];
} else {
if (lastUsedTimeToRemove > 0) break;
}
cur = next;
cur = prev;
}
} @finally {
[_lock unlock];
@@ -219,7 +239,7 @@ - (MTLTexturePoolItem *)occupyItem:(int)width height:(int)height format:(MTLPixe
if (cur.texture.width < width || cur.texture.height < height) {
continue;
}
const int deltaArea = cur.texture.width * cur.texture.height - requestedPixels;
const int deltaArea = (const int) (cur.texture.width * cur.texture.height - requestedPixels);
if (minDeltaArea < 0 || deltaArea < minDeltaArea) {
minDeltaArea = deltaArea;
minDeltaTpi = cur;
@@ -313,7 +333,9 @@ - (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MT
const int newCellWidth = cellX1 <= _poolCellWidth ? _poolCellWidth : cellX1;
const int newCellHeight = cellY1 <= _poolCellHeight ? _poolCellHeight : cellY1;
const int newCellsCount = newCellWidth*newCellHeight;
#ifdef DEBUG
J2dTraceLn2(J2D_TRACE_VERBOSE, "MTLTexturePool: resize: %d -> %d", _poolCellWidth * _poolCellHeight, newCellsCount);
#endif
void ** newcells = malloc(newCellsCount*sizeof(void*));
const int strideBytes = _poolCellWidth * sizeof(void*);
for (int cy = 0; cy < _poolCellHeight; ++cy) {
@@ -342,7 +364,7 @@ - (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MT
MTLTexturePoolItem* tpi = [cell occupyItem:width height:height
format:format isMultiSample:isMultiSample];
if (!tpi) continue;
const int deltaArea = tpi.texture.width*tpi.texture.height - requestedPixels;
const int deltaArea = (const int) (tpi.texture.width * tpi.texture.height - requestedPixels);
if (minDeltaArea < 0 || deltaArea < minDeltaArea) {
minDeltaArea = deltaArea;
minDeltaTpi = tpi;
@@ -379,7 +401,7 @@ - (MTLPooledTextureHandle *) getTexture:(int)width height:(int)height format:(MT
}

- (void) cleanIfNecessary:(int)lastUsedTimeThreshold {
NSTimeInterval lastUsedTimeToRemove =
time_t lastUsedTimeToRemove =
lastUsedTimeThreshold > 0 ?
time(NULL) - lastUsedTimeThreshold :
lastUsedTimeThreshold;

0 comments on commit 43f1444

Please sign in to comment.