CVOpenGLESTextureCacheCreateTextureFromImage en iPad2 es demasiado lento, necesita casi 30 ms, demasiado loco

Utilizo opengl es para mostrar datos de bgr24 en iPad, soy nuevo en opengl es, así que en la parte de video de visualización utilizo el código de RosyWriter, una muestra de APPLE. Funciona, pero la function CVOpenGLESTextureCacheCreateTextureFromImage cuesta más de 30 ms, mientras que en RosyWriter su costo es insignificante. lo que hago es primero transformar BGR24 a formatting de píxel BGRA, luego usar la function CVPixelBufferCreateWithBytes crear un CVPixelBufferRef y luego get un CVOpenGLESTextureRef por CVOpenGLESTextureCacheCreateTextureFromImage. Mis códigos como siguientes,

- (void)transformBGRToBGRA:(const UInt8 *)pict width:(int)width height:(int)height { rgb.data = (void *)pict; vImage_Error error = vImageConvert_RGB888toARGB8888(&rgb,NULL,0,&argb,NO,kvImageNoFlags); if (error != kvImageNoError) { NSLog(@"vImageConvert_RGB888toARGB8888 error"); } const uint8_t permuteMap[4] = {1,2,3,0}; error = vImagePermuteChannels_ARGB8888(&argb,&bgra,permuteMap,kvImageNoFlags); if (error != kvImageNoError) { NSLog(@"vImagePermuteChannels_ARGB8888 error"); } free((void *)pict); } 

y después de la transformación, generará CVPixelBufferRef, códigos como sigue,

 [self transformBGRToBGRA:pict width:width height:height]; CVPixelBufferRef pixelBuffer; CVReturn err = CVPixelBufferCreateWithBytes(NULL, width, height, kCVPixelFormatType_32BGRA, (void*)bgraData, bytesByRow, NULL, 0, NULL, &pixelBuffer); if(!pixelBuffer || err) { NSLog(@"CVPixelBufferCreateWithBytes failed (error: %d)", err); return; } CVOpenGLESTextureRef texture = NULL; err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0, &texture); if (!texture || err) { NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err); CVPixelBufferRelease(pixelBuffer); return; } 

Los otros códigos son ejemplos similares de RosyWriter, incluyen sombreadores. Entonces, quiero saber por qué, cómo solucionar este problema.

Con mi investigación en estos días, encuentro por qué CVOpenGLESTextureCacheCreateTextureFromImage cuesta mucho time, cuando los datos son grandes, aquí está 3M, la operación de asignación, copy y movimiento cuyo costo es considerable, especialmente la operación de Copia. Luego, con la agrupación de almacenamientos intermedios de píxeles, mejorar considerablemente el performance de CVOpenGLESTextureCacheCreateTextureFromImage desde 30 ms a 5 ms, el mismo nivel con glTexImage2D (). Mi solución como sigue:

 NSMutableDictionary* attributes; attributes = [NSMutableDictionary dictionary]; [attributes setObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; [attributes setObject:[NSNumber numberWithInt:videoWidth] forKey: (NSString*)kCVPixelBufferWidthKey]; [attributes setObject:[NSNumber numberWithInt:videoHeight] forKey: (NSString*)kCVPixelBufferHeightKey]; CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (CFDictionaryRef) attributes, &bufferPool); CVPixelBufferPoolCreatePixelBuffer (NULL,bufferPool,&pixelBuffer); CVPixelBufferLockBaseAddress(pixelBuffer,0); UInt8 * baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer); memcpy(baseAddress, bgraData, bytesByRow * videoHeight); CVPixelBufferUnlockBaseAddress(pixelBuffer,0); 

con este nuevo pixelBuffer creado puedes hacerlo rápido.

Agregar las siguientes configuraciones a attribtes puede hacer que su performance sea el mejor, less de 1 ms.

  NSDictionary *IOSurfaceProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], @"IOSurfaceOpenGLESFBOCompatibility",[NSNumber numberWithBool:YES], @"IOSurfaceOpenGLESTextureCompatibility",nil]; [attributes setObject:IOSurfaceProperties forKey:(NSString*)kCVPixelBufferIOSurfacePropertiesKey];