У меня есть "программный рендерер", который я переношу с ПК на iPhone. какой самый быстрый способ вручную обновить экран с помощью буфера пикселей на iphone? например, в окнах самая быстрая функция, которую я нашел, - SetDIBitsToDevice.
Я не знаю много о iphone или библиотеках, и, похоже, столько слоев и разных типов элементов пользовательского интерфейса, поэтому мне может понадобиться много объяснений...
пока я просто собираюсь постоянно обновлять текстуру в opengl и отображать ее на экране, я очень сомневаюсь, что это будет лучший способ сделать это.
UPDATE:
Я попробовал метод текстуры с разрешением экрана OpenGL:
Я получил 17 кадров в секунду...
Я использовал текстуру 512x512 (потому что она должна быть двух)
просто вызов
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,512,GL_RGBA,GL_UNSIGNED_BYTE, baseWindowGUI->GetBuffer());
казался очень ответственным за ВСЕ замедление.
комментируя это и оставляя во всем моем графическом коде программного обеспечения, а также рендеринг текстуры, не обновляющейся сейчас, привел к использованию 60 кадров в секунду, 30% -ному использованию визуализатора и отсутствию заметных всплесков от процессора.
обратите внимание, что GetBuffer() просто возвращает указатель на программный backbuffer системы GUI, во всяком случае, нет никакого повторного звонка или изменения размера буфера, он должным образом отформатирован и отформатирован для текстуры, поэтому я достаточно уверен замедление не имеет ничего общего с программным рендерером, что является хорошей новостью. Похоже, если я смогу найти способ обновления экрана на 60, рендеринг программного обеспечения должен работать пока.
Я попытался сделать вызов текстуры обновления с 512,320, а не 512 512, это было странно еще медленнее... работая на скорости 10 кадров в секунду, также говорится, что использование рендеринга составляет всего 5%, и все время тратится впустую на вызов Untwiddle32bpp внутри openGLES.
Я могу изменить свой рендеринг программного обеспечения для рендеринга в любой формат изображения, если это приведет к более прямому blit.
fyi, протестированный на 2.2.1 ipod touch G2 (так же, как Iphone 3G на стероидах)
ОБНОВЛЕНИЕ 2:
Я только что закончил написание метода CoreAnimation/Graphics, он выглядит неплохо, но я немного беспокоюсь о том, как он обновляет экран в каждом кадре, в основном отбрасывая старый CGImage, создавая совершенно новый... проверьте его в разделе "someRandomFunction" ниже: это самый быстрый способ обновления изображения? любая помощь будет принята с благодарностью.
//
// 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 CALayer 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