schnellste Weg, um einen Bildschirmpuffer auf dem iPhone zu zeichnen

Ich habe einen "Software-Renderer", den ich vom PC auf das iPhone portiere. Was ist der schnellste Weg, um den Bildschirm manuell mit einem Pixelpuffer auf dem iPhone zu aktualisieren? In Windows ist zum Beispiel die schnellste Funktion, die ich gefunden habe, SetDIBitsToDevice.

Ich weiß nicht viel über das iPhone oder die Bibliotheken, und es scheint so viele Ebenen und verschiedene Arten von UI-Elementen zu geben, dass ich möglicherweise eine Menge Erklärung brauche ...

Im Moment aktualisiere ich ständig eine Textur in OpenGL und rendere sie auf dem Bildschirm. Ich bezweifle sehr, dass dies der beste Weg ist, dies zu tun.

AKTUALISIEREN:

Ich habe die Texturmethode in OpenGL-Bildschirmgröße ausprobiert:

Ich habe 17fps ...

Ich habe eine 512x512 Textur verwendet (weil es eine Zweierpotenz sein muss)

nur der Anruf von

glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,512,GL_RGBA,GL_UNSIGNED_BYTE, baseWindowGUI->GetBuffer());

schien ziemlich viel für die Verlangsamung verantwortlich zu sein.

Das Auskommentieren und Verlassen des GUI-Codes für alle meine Software-Renderings sowie das Rendern der jetzt nicht aktualisierten Textur führten zu 60 fps, 30% Renderernutzung und keinen nennenswerten CPU-Spitzen.

Beachten Sie, dass GetBuffer () einfach einen Zeiger auf den Software-Backbuffer des GUI-Systems zurückgibt. Es findet keine erneute Vergrößerung oder Verkleinerung des Puffers statt. Die Größe und das Format des Puffers sind für die Textur angemessen, daher bin ich mir ziemlich sicher, dass die Verlangsamung eingetreten ist Das hat nichts mit dem Software-Renderer zu tun, was die gute Nachricht ist. Es sieht so aus, als ob ich bei 60 eine Möglichkeit finde, den Bildschirm zu aktualisieren. Das Software-Rendering sollte vorerst funktionieren.

Ich habe versucht, den Update-Textur-Aufruf mit 512.320 anstatt mit 512.512 durchzuführen. Dies war seltsamerweise sogar langsamer. Er lief mit 10 Bildern pro Sekunde. Außerdem heißt es, dass die Renderauslastung nur 5% beträgt und die gesamte Zeit in einem Aufruf von Untwiddle32bpp in openGLES verschwendet wird .

Ich kann meine Software so rendern, dass sie nativ in jedes Pixelformat gerendert wird, wenn dies zu einem direkteren Blit führen würde.

Zur Info, getestet auf einem 2.2.1 ipod touch G2 (so wie ein Iphone 3G auf Steroiden)

UPDATE 2:

Ich habe gerade die CoreAnimation / Graphics-Methode fertig geschrieben, sie sieht gut aus, aber ich mache mir ein wenig Sorgen darüber, wie der Bildschirm bei jedem Frame aktualisiert wird. Im Grunde wird das alte CGImage verworfen und ein brandneues erstellt ... siehe 'someRandomFunction' 'unten: Ist dies der schnellste Weg, um das Bild zu aktualisieren? Jede Hilfe wäre sehr dankbar.

//
//  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

Antworten auf die Frage(5)

Ihre Antwort auf die Frage