3
我创建并加载了很多纹理(由字符串组成)。为了保持动画顺畅运行,我将工作卸载到单独的工作线程。它似乎或多或少地按照我想要的方式工作,但在较旧的设备(iPhone 3GS)上,我有时会注意到很长时间(1秒)的延迟。它只是偶尔发生。现在我想知道我是否正确地做了这个或者是否有任何概念问题。我粘贴下面的源代码。异步纹理加载iPhone OpenGL ES 2
我还应该提到我不想使用GLKit纹理加载器,因为我也想将纹理生成工作卸载到另一个线程,而不仅仅是加载部分。
如果你想知道什么,我需要这些纹理,看看这个视频: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"]];
}
像往常一样,在发布问题后不久,我就开始工作。我现在使用NSOperationQueue而不是创建太多的NSThreads。这使我可以设置'maxConcurrentOperationCount'这似乎解决了这个问题。我仍然喜欢听到我是否在做其他任何看起来很愚蠢的事情。 – hanno 2012-07-07 00:50:01
如果是资源限制问题,您可能还会考虑调度信号量:http://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html。我通常将这些用于这样的项目,其中I/O速度可能比处理速度更受限制。 – 2012-07-08 17:48:56
谢谢。其他情况:根据仪器获取和设置共享组的新环境需要很长时间。我应该只创建一个额外的上下文并在线程中重用它,同时确保我一次只能从一个线程访问它?我记得在某个地方读书时,我不应该记得原因。 – hanno 2012-07-08 19:01:25