@qidiandasheng
2020-07-13T06:47:49.000000Z
字数 4220
阅读 1932
音视频
GPUImageContext类,提供OpenGL ES基本上下文,GPUImage相关处理线程,GLProgram缓存、帧缓存。由于是上下文对象,因此该模块提供的更多是存取、设置相关的方法。
GLProgram与着色器程序创建息息相关,其中包括创建、编译、链接、使用等过程。
// GPUImage处理OpenGL绘制的相关队列,串行队列@property(readonly, nonatomic) dispatch_queue_t contextQueue;// 当前使用的着色器程序@property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram;// OpenGLES上下文对象@property(readonly, retain, nonatomic) EAGLContext *context;// CoreVideo中的纹理缓存@property(readonly) CVOpenGLESTextureCacheRef coreVideoTextureCache;// 帧缓存@property(readonly) GPUImageFramebufferCache *framebufferCache;
// 获取队列标识+ (void *)contextKey;// 单例对象+ (GPUImageContext *)sharedImageProcessingContext;// 获取处理队列+ (dispatch_queue_t)sharedContextQueue;// 帧缓存+ (GPUImageFramebufferCache *)sharedFramebufferCache;// 设置当前上下文+ (void)useImageProcessingContext;- (void)useAsCurrentContext;// 设置当前的GL程序+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;- (void)setContextShaderProgram:(GLProgram *)shaderProgram;// 获取设备OpenGLES相关特性的支持情况+ (GLint)maximumTextureSizeForThisDevice;+ (GLint)maximumTextureUnitsForThisDevice;+ (GLint)maximumVaryingVectorsForThisDevice;+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;+ (BOOL)deviceSupportsRedTextures;+ (BOOL)deviceSupportsFramebufferReads;// 纹理大小调整,保证纹理不超过OpenGLES支持最大的尺寸+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;// 将渲染缓存呈现在设备上- (void)presentBufferForDisplay;// 创建GLProgram,首先在缓存中查找,如果没有则创建- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;// 创建Sharegroup- (void)useSharegroup:(EAGLSharegroup *)sharegroup;// Manage fast texture upload+ (BOOL)supportsFastTextureUpload;
- (id)init;{if (!(self = [super init])){return nil;}// 创建OpenGL渲染队列openGLESContextQueueKey = &openGLESContextQueueKey;_contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", GPUImageDefaultQueueAttribute());#if OS_OBJECT_USE_OBJC// 设置队列标识dispatch_queue_set_specific(_contextQueue, openGLESContextQueueKey, (__bridge void *)self, NULL);#endif// 初始化着色器缓存相关数组shaderProgramCache = [[NSMutableDictionary alloc] init];shaderProgramUsageHistory = [[NSMutableArray alloc] init];return self;}
+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;{GLint maxTextureSize = [self maximumTextureSizeForThisDevice];if ( (inputSize.width < maxTextureSize) && (inputSize.height < maxTextureSize) ){return inputSize;}CGSize adjustedSize;if (inputSize.width > inputSize.height){adjustedSize.width = (CGFloat)maxTextureSize;adjustedSize.height = ((CGFloat)maxTextureSize / inputSize.width) * inputSize.height;}else{adjustedSize.height = (CGFloat)maxTextureSize;adjustedSize.width = ((CGFloat)maxTextureSize / inputSize.height) * inputSize.width;}return adjustedSize;}
+ (GLint)maximumTextureSizeForThisDevice;{static dispatch_once_t pred;static GLint maxTextureSize = 0;dispatch_once(&pred, ^{[self useImageProcessingContext];glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);});return maxTextureSize;}
- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;{NSString *lookupKeyForShaderProgram = [NSString stringWithFormat:@"V: %@ - F: %@", vertexShaderString, fragmentShaderString];GLProgram *programFromCache = [shaderProgramCache objectForKey:lookupKeyForShaderProgram];if (programFromCache == nil){programFromCache = [[GLProgram alloc] initWithVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString];[shaderProgramCache setObject:programFromCache forKey:lookupKeyForShaderProgram];}return programFromCache;}
使用的是kEAGLRenderingAPIOpenGLES2的API也就是OpenGL ES 2.0
- (EAGLContext *)createContext;{EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:_sharegroup];NSAssert(context != nil, @"Unable to create an OpenGL ES 2.0 context. The GPUImage framework requires OpenGL ES 2.0 support to work.");return context;}
- (void)setContextShaderProgram:(GLProgram *)shaderProgram;{EAGLContext *imageProcessingContext = [self context];if ([EAGLContext currentContext] != imageProcessingContext){[EAGLContext setCurrentContext:imageProcessingContext];}if (self.currentShaderProgram != shaderProgram){self.currentShaderProgram = shaderProgram;[shaderProgram use];}}