2

質問の要約は次のとおりです。

一部のレイヤーの合成では、CGContext で OpenGL テクスチャをレンダリングする必要があります。それを行う最も速い方法は何ですか?

これまでの考え:

明らかに、renderInContext を呼び出しても OpenGL コンテンツはキャプチャされず、glReadPixels は遅すぎます。

一部の「コンテキスト」については、レイヤーのデリゲート クラスでこのメソッドを呼び出しています。

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx

CVOpenGLESTextureCache の使用を検討しましたが、それには追加のレンダリングが必要であり、レンダリング後に複雑な変換が必要になるようです。

これが私の(ひどい)実装です。

glBindRenderbuffer(GL_RENDERBUFFER, displayRenderbuffer);

NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;
NSInteger dataLength = width * height * 4;
GLubyte *data = (GLubyte *) malloc(dataLength * sizeof(GLubyte));

glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);

CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
                                ref, NULL, true, kCGRenderingIntentDefault);

CGFloat scale = self.contentScaleFactor;
NSInteger widthInPoints, heightInPoints;
widthInPoints = width / scale;
heightInPoints = height / scale;

CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);

// Clean up
free(data);
CFRelease(ref);
CFRelease(colorspace);
CGImageRelease(iref);
4

1 に答える 1