Объявите эти переменные, глобально:
dispatch_fd_t write_dfd, read_dfd;
dispatch_io_t write_channel, read_channel;
Чтобы открыть канал для записи текстуры металла в файл:
NSString *documentDictionary = [(NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)) objectAtIndex:0];
write_dfd = open([[NSString stringWithFormat:@"%@/textures.data", documentDictionary] UTF8String], O_CREAT | O_TRUNC | O_WRONLY | O_APPEND);
write_channel = dispatch_io_create(DISPATCH_IO_STREAM, write_dfd, AppServices.textureQueue, ^(int error) {
NSLog(@"Write channel to %@ open", documentDictionary);
});
dispatch_io_set_low_water(write_channel, 33177608);
dispatch_io_set_high_water(write_channel, 33177608);
Кзапишите текстуру металла в файл:
void *write_buffer = malloc([_textureBGRA allocatedSize]);
[_textureBGRA getBytes:write_buffer bytesPerRow:15360 fromRegion:MTLRegionMake2D(0.0, 0.0, [_textureBGRA width], [_textureBGRA height]) mipmapLevel:0];
dispatch_data_t message_data = dispatch_data_create(write_buffer, [_textureBGRA allocatedSize], AppServices.textureQueue, ^{
free((void *)write_buffer);
});
dispatch_io_write(write_channel, 0, message_data, AppServices.textureQueue, ^(bool done, dispatch_data_t _Nullable data, int error) {
if (done)
{
NSLog(@"Wrote %lu bytes", [_textureBGRA allocatedSize]);
}
});
Чтобы закрыть файл:
dispatch_io_close(write_channel, 0);
close(write_dfd);
Чтобы открыть канал для чтенияТекстура металла из файла:
NSString *documentDictionary = [(NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)) objectAtIndex:0];
read_dfd = open([[NSString stringWithFormat:@"%@/textures.data", documentDictionary] UTF8String], O_RDONLY | O_NONBLOCK);
read_channel = dispatch_io_create(DISPATCH_IO_STREAM, read_dfd, dispatch_get_main_queue(), ^(int error) {
NSLog(@"Read channel to %@ open", documentDictionary);
});
dispatch_io_set_low_water(read_channel, 33177608);
dispatch_io_set_high_water(read_channel, 33177608);
Чтобы прочитать текстуру металла из файла:
dispatch_io_read(read_channel, [_textureBGRA allocatedSize] * textureIndex, [_textureBGRA allocatedSize], dispatch_get_main_queue(), ^(bool done, dispatch_data_t _Nullable data, int error) {
if ( read_channel == nil )
return;
if ( error != 0 ) {
__autoreleasing NSError * nsError = nil;
nsError = [[NSError alloc] initWithDomain:NSPOSIXErrorDomain code:error userInfo:nil];
NSLog(@"Error reading from channel: %@", nsError.localizedDescription);
return;
}
// read data
void *buffer = malloc([_textureBGRA allocatedSize]);
dispatch_data_t mapped_data = dispatch_data_create_map(data, buffer, NULL);
dispatch_data_apply(mapped_data, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
NSUInteger rowBytes = 3840 * 4;
NSUInteger imageBytes = rowBytes * 2160;
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
width:3840
height:2160
mipmapped:NO];
textureDescriptor.usage = MTLTextureUsageShaderRead;
id<MTLTexture> texture = [_device newTextureWithDescriptor:textureDescriptor];
[texture replaceRegion:MTLRegionMake2D(0, 0, 3840, 2160)
mipmapLevel:0 slice:0 withBytes:buffer
bytesPerRow:rowBytes bytesPerImage:imageBytes];
dispatch_async(dispatch_get_main_queue(), ^{
NSString *label = [NSString stringWithFormat:@"%lu", textureIndex];
const char *queue_index = [[NSString stringWithFormat:@"%lu", textureIndex] cStringUsingEncoding:NSUTF8StringEncoding];
dispatch_queue_set_specific(AppServices.textureQueue, queue_index, (void *)CFBridgingRetain(texture), NULL);
[self.mediaCollectionView insertItemForQueueDataIndex:label];
textureIndex++;
});
return TRUE;
});
});
Чтобы закрыть файл:
dispatch_io_close(read_channel, 0);
close(read_dfd);