Tengo un "procesador de software" que estoy portando desde la PC al iPhone. ¿Cuál es la forma más rápida de actualizar manualmente la pantalla con un buffer de píxeles en el iphone? por ejemplo, en Windows, la función más rápida que he encontrado es SetDIBitsToDevice.manera más rápida de dibujar un búfer de pantalla en el iphone
No sé mucho sobre el iPhone, o las bibliotecas, y parece que hay tantas capas y diferentes tipos de elementos de interfaz de usuario, así que puede ser que necesite mucha explicación ...
por ahora Voy a actualizar constantemente una textura en OpenGL y renderizarla en la pantalla, dudo mucho que esta sea la mejor manera de hacerlo.
ACTUALIZACIÓN:
He probado el método de la textura del tamaño de pantalla OpenGL:
llegué 17fps ...
utilicé una textura de 512x512 (ya que tiene que ser una potencia de dos)
simplemente la llamada de
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,512,GL_RGBA,GL_UNSIGNED_BYTE, baseWindowGUI->GetBuffer());
parecía más o menos re Es responsable de TODA la ralentización.
comentándolo, y dejando en todo mi software el código de la GUI, y la representación de la textura que ahora no se actualiza, resultó en 60fps, 30% de uso del procesador, y sin picos notables de la CPU.
tenga en cuenta que GetBuffer() simplemente devuelve un puntero al backbuffer de software del sistema GUI, no hay reorganización ni cambio de tamaño del búfer, tiene el tamaño y el formato adecuados para la textura, así que estoy bastante seguro de que la ralentización no tiene nada que ver con el procesador de software, que es una buena noticia, parece que si puedo encontrar una manera de actualizar la pantalla a 60, la renderización del software debería funcionar por el momento.
He intentado actualizar la llamada de textura con 512,320 en lugar de 512,512 esto fue extrañamente aún más lento ... corriendo a 10 fps, también dice que la utilización del renderizado es solo del 5% y todo el tiempo se desperdicia en una llamada a Untwiddle32bpp dentro de openGLES.
Puedo cambiar mi procesamiento de software para que se procese de forma nativa a cualquier formato de píxel, si resultara en un blit directo.
FYI, probado en un G2 2.2.1 iPod touch (así como un Iphone 3G en los esteroides)
ACTUALIZACIÓN 2:
acabo de terminar escribiendo el método CoreAnimation/gráficos, se ve bien, pero estoy un poco preocupado acerca de cómo actualiza la pantalla cada fotograma, básicamente abandonando el viejo CGImage, creando uno nuevo ... compruébalo en 'someRandomFunction' a continuación: ¿es esta la manera más rápida de actualizar la imagen? cualquier ayuda sería muy apreciada.
//
// catestAppDelegate.m
// catest
//
// Created by User on 3/14/10.
// Copyright __MyCompanyName__ 2010. All rights reserved.
//
#import "catestAppDelegate.h"
#import "catestViewController.h"
#import "QuartzCore/QuartzCore.h"
const void* GetBytePointer(void* info)
{
// this is currently only called once
return info; // info is a pointer to the buffer
}
void ReleaseBytePointer(void*info, const void* pointer)
{
// don't care, just using the one static buffer at the moment
}
size_t GetBytesAtPosition(void* info, void* buffer, off_t position, size_t count)
{
// I don't think this ever gets called
memcpy(buffer, ((char*)info) + position, count);
return count;
}
CGDataProviderDirectCallbacks providerCallbacks =
{ 0, GetBytePointer, ReleaseBytePointer, GetBytesAtPosition, 0 };
static CGImageRef cgIm;
static CGDataProviderRef dataProvider;
unsigned char* imageData;
const size_t imageDataSize = 320 * 480 * 4;
NSTimer *animationTimer;
NSTimeInterval animationInterval= 1.0f/60.0f;
@implementation catestAppDelegate
@synthesize window;
@synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window makeKeyAndVisible];
const size_t byteRowSize = 320 * 4;
imageData = malloc(imageDataSize);
for(int i=0;i<imageDataSize/4;i++)
((unsigned int*)imageData)[i] = 0xFFFF00FF; // just set it to some random init color, currently yellow
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
dataProvider =
CGDataProviderCreateDirect(imageData, imageDataSize,
&providerCallbacks); // currently global
cgIm = CGImageCreate
(320, 480,
8, 32, 320*4, colorSpace,
kCGImageAlphaNone | kCGBitmapByteOrder32Little,
dataProvider, 0, false, kCGRenderingIntentDefault); // also global, probably doesn't need to be
self.window.layer.contents = cgIm; // set the UIWindow's CALayer's contents to the image, yay works!
// CGImageRelease(cgIm); // we should do this at some stage...
// CGDataProviderRelease(dataProvider);
animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(someRandomFunction) userInfo:nil repeats:YES];
// set up a timer in the attempt to update the image
}
float col = 0;
-(void)someRandomFunction
{
// update the original buffer
for(int i=0;i<imageDataSize;i++)
imageData[i] = (unsigned char)(int)col;
col+=256.0f/60.0f;
// and currently the only way I know how to apply that buffer update to the screen is to
// create a new image and bind it to the layer...???
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
cgIm = CGImageCreate
(320, 480,
8, 32, 320*4, colorSpace,
kCGImageAlphaNone | kCGBitmapByteOrder32Little,
dataProvider, 0, false, kCGRenderingIntentDefault);
CGColorSpaceRelease(colorSpace);
self.window.layer.contents = cgIm;
// and that currently works, updating the screen, but i don't know how well it runs...
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
Oye me encontré con este problema, también, ¿es la única solución para crear y destruir un CGImage cada fotograma? (intenté esto y es más lento que glTexsubimage). Parece que el objetivo del proveedor directo es que debe apuntar a ese búfer, por lo que si lo cambio, la imagen se actualizará. ¿Alguna ayuda en esto? –
Pensé que el objetivo de usar CGDataProviderCreateDirect era el acceso directo a un búfer de píxeles, actualizado con CADisplayLink. Desafortunadamente, esto es terriblemente lento. ¿Alguna solución descubierta? – aoakenfo