[英]Asynchronous texture loading iPhone OpenGL ES 2
I'm creating and loading a lot of textures (made of strings). 我正在创建和加载大量纹理(由字符串组成)。 To keep the animation running smoothly, I offload the work to a separate worker thread.
为了使动画顺利运行,我将工作卸载到单独的工作线程。 It seems to work more or less exactly the way I want, but on older devices (iPhone 3GS) I sometimes notice a long (1 sec) lag.
它似乎或多或少地按照我想要的方式工作,但在旧设备(iPhone 3GS)上,我有时会注意到很长(1秒)的延迟。 It only occurs sometimes.
它有时只会发生。 Now I'm wondering if I'm doing this correctly or if there is any conceptual issue.
现在我想知道我是否正确地做了这个或者是否存在任何概念问题。 I paste the source code below.
我粘贴下面的源代码。
I should also mention that I do not want to use the GLKit TextureLoader because I also want to offload the texture generating work to the other thread, not just the loading part. 我还要提一下,我不想使用GLKit TextureLoader,因为我还想将纹理生成工作卸载到另一个线程,而不仅仅是加载部分。
In case you're wondering what I need these textures for, have a look at this video: http://youtu.be/U03p4ZhLjvY?hd=1 如果你想知道我需要这些纹理,看看这个视频:http: //youtu.be/U03p4ZhLjvY?hd = 1
NSLock* _textureLock;
NSMutableDictionary* _texturesWithString;
NSMutableArray* _texturesWithStringLoading;
// This is called when I request a new texture from the drawing routine.
// If this function returns 0, it means the texture is not ready and Im not displaying it.
-(unsigned int)getTextureWithString:(NSString*)string {
Texture2D* _texture = [_texturesWithString objectForKey:string];
if (_texture==nil){
if (![_texturesWithStringLoading containsObject:string]){
[_texturesWithStringLoading addObject:string];
NSDictionary* dic = [[NSDictionary alloc] initWithObjectsAndKeys:string,@"string", nil];
NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadTextureWithDictionary:)object:dic];
thread.threadPriority = 0.01;
[thread start];
[thread release];
}
return 0;
}
return _texture.name;
}
// This is executed on a separate worker thread.
// The lock makes sure that there are not hundreds of separate threads all creating a texture at the same time and therefore slowing everything down.
// There must be a smarter way of doing that. Please let me know if you know how! ;-)
-(void)loadTextureWithOptions:(NSDictionary*)_dic{
[_textureLock lock];
EAGLContext* context = [[SharegroupManager defaultSharegroup] getNewContext];
[EAGLContext setCurrentContext: context];
NSString* string = [_dic objectForKey:@"string"];
Texture2D* _texture = [[Texture2D alloc] initWithStringModified:string];
if (_texture!=nil) {
NSDictionary* _newdic = [[NSDictionary alloc] initWithObjectsAndKeys:_texture,@"texture",string,@"string", nil];
[self performSelectorOnMainThread:@selector(doneLoadingTexture:) withObject:_newdic waitUntilDone:NO];
[_newdic release];
[_texture release];
}
[EAGLContext setCurrentContext: nil];
[context release];
[_textureLock unlock];
}
// This callback is executed on the main thread and marks adds the texture to the texture cache.
-(void)doneLoadingTextureWithDictionary:(NSDictionary*)_dic{
[_texturesWithString setValue:[_dic objectForKey:@"texture"] forKey:[_dic objectForKey:@"string"]];
[_texturesWithStringLoading removeObject:[_dic objectForKey:@"string"]];
}
The problem was that too many threads were started at the same time. 问题是同时启动了太多线程。 Now I am using a
NSOperationQueue
rather than NSThreads
. 现在我使用的是
NSOperationQueue
而不是NSThreads
。 That allows me to set maxConcurrentOperationCount
and only run one extra background thread that does the texture loading. 这允许我设置
maxConcurrentOperationCount
并且只运行一个额外的后台线程来执行纹理加载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.