你的位置:首页 > 操作系统

[操作系统]GPUImage API文档之GPUImageContext类


  GPUImageContext类,提供OpenGL ES基本环境,我们一般不会用到,所以讲的很简单。

  属性

  @property(readonly, nonatomic) dispatch_queue_t contextQueue

  说明:创建一个context线程

  描述:_contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL);

 

  @property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram

  说明:当前着色器program

 

  @property(readonly, retain, nonatomic) EAGLContext *context

  说明:opengl es绘制环境,管理上下文

 

  方法

    + (void *)contextKey

    说明:设置当前context的线程标识符,全局静态变量。

  

    + (GPUImageContext *)sharedImageProcessingContext

    说明:创建一个全局的GPUImageContext对象的单例。

 

    + (dispatch_queue_t)sharedContextQueue

    说明:创建一个context queue单例

 

    + (GPUImageFramebufferCache *)sharedFramebufferCache

    说明:创建一个GPUFramebufferCache单例

     

    - (void)useAsCurrentContext

    说明:使用当前context

 

    + (void)setActiveShaderProgram:(GLProgram *)shaderProgram;

    - (void)setContextShaderProgram:(GLProgram *)shaderProgram;

    + (GLint)maximumTextureSizeForThisDevice;

    + (GLint)maximumTextureUnitsForThisDevice;

    + (GLint)maximumVaryingVectorsForThisDevice;

    + (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;

    + (BOOL)deviceSupportsRedTextures;

    + (BOOL)deviceSupportsFramebufferReads;

    + (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;

    - (void)presentBufferForDisplay;

    - (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;

    - (void)useSharegroup:(EAGLSharegroup *)sharegroup;

    + (BOOL)supportsFastTextureUpload;

 

完整代码

#import "GLProgram.h"#import "GPUImageFramebuffer.h"#import "GPUImageFramebufferCache.h"#define GPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal)typedef enum { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizonal, kGPUImageRotateRightFlipVertical, kGPUImageRotateRightFlipHorizontal, kGPUImageRotate180 } GPUImageRotationMode;@interface GPUImageContext : NSObject@property(readonly, nonatomic) dispatch_queue_t contextQueue;@property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram;@property(readonly, retain, nonatomic) EAGLContext *context;@property(readonly) CVOpenGLESTextureCacheRef coreVideoTextureCache;@property(readonly) GPUImageFramebufferCache *framebufferCache;+ (void *)contextKey;+ (GPUImageContext *)sharedImageProcessingContext;+ (dispatch_queue_t)sharedContextQueue;+ (GPUImageFramebufferCache *)sharedFramebufferCache;+ (void)useImageProcessingContext;- (void)useAsCurrentContext;+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;- (void)setContextShaderProgram:(GLProgram *)shaderProgram;+ (GLint)maximumTextureSizeForThisDevice;+ (GLint)maximumTextureUnitsForThisDevice;+ (GLint)maximumVaryingVectorsForThisDevice;+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;+ (BOOL)deviceSupportsRedTextures;+ (BOOL)deviceSupportsFramebufferReads;+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;- (void)presentBufferForDisplay;- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;- (void)useSharegroup:(EAGLSharegroup *)sharegroup;// Manage fast texture upload+ (BOOL)supportsFastTextureUpload;@end@protocol GPUImageInput <NSObject>- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;- (NSInteger)nextAvailableTextureIndex;- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;- (CGSize)maximumOutputSize;- (void)endProcessing;- (BOOL)shouldIgnoreUpdatesToThisTarget;- (BOOL)enabled;- (BOOL)wantsMonochromeInput;- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue;@end

View Code

 

#import "GPUImageContext.h"#import <OpenGLES/EAGLDrawable.h>#import <AVFoundation/AVFoundation.h>#define MAXSHADERPROGRAMSALLOWEDINCACHE 40@interface GPUImageContext(){  NSMutableDictionary *shaderProgramCache;  NSMutableArray *shaderProgramUsageHistory;  EAGLSharegroup *_sharegroup;}@end@implementation GPUImageContext@synthesize context = _context;@synthesize currentShaderProgram = _currentShaderProgram;@synthesize contextQueue = _contextQueue;@synthesize coreVideoTextureCache = _coreVideoTextureCache;@synthesize framebufferCache = _framebufferCache;static void *openGLESContextQueueKey;- (id)init;{  if (!(self = [super init]))  {    return nil;  }  openGLESContextQueueKey = &openGLESContextQueueKey;  _contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL);  #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;}+ (void *)contextKey {  return openGLESContextQueueKey;}// Based on Colin Wheeler's example here: http://cocoasamurai.blogspot.com/2011/04/singletons-your-doing-them-wrong.html+ (GPUImageContext *)sharedImageProcessingContext;{  static dispatch_once_t pred;  static GPUImageContext *sharedImageProcessingContext = nil;    dispatch_once(&pred, ^{    sharedImageProcessingContext = [[[self class] alloc] init];  });  return sharedImageProcessingContext;}+ (dispatch_queue_t)sharedContextQueue;{  return [[self sharedImageProcessingContext] contextQueue];}+ (GPUImageFramebufferCache *)sharedFramebufferCache;{  return [[self sharedImageProcessingContext] framebufferCache];}+ (void)useImageProcessingContext;{  [[GPUImageContext sharedImageProcessingContext] useAsCurrentContext];}- (void)useAsCurrentContext;{  EAGLContext *imageProcessingContext = [self context];  if ([EAGLContext currentContext] != imageProcessingContext)  {    [EAGLContext setCurrentContext:imageProcessingContext];  }}+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;{  GPUImageContext *sharedContext = [GPUImageContext sharedImageProcessingContext];  [sharedContext setContextShaderProgram:shaderProgram];}- (void)setContextShaderProgram:(GLProgram *)shaderProgram;{  EAGLContext *imageProcessingContext = [self context];  if ([EAGLContext currentContext] != imageProcessingContext)  {    [EAGLContext setCurrentContext:imageProcessingContext];  }    if (self.currentShaderProgram != shaderProgram)  {    self.currentShaderProgram = shaderProgram;    [shaderProgram use];  }}+ (GLint)maximumTextureSizeForThisDevice;{  static dispatch_once_t pred;  static GLint maxTextureSize = 0;    dispatch_once(&pred, ^{    [self useImageProcessingContext];    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);  });  return maxTextureSize;}+ (GLint)maximumTextureUnitsForThisDevice;{  static dispatch_once_t pred;  static GLint maxTextureUnits = 0;  dispatch_once(&pred, ^{    [self useImageProcessingContext];    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);  });    return maxTextureUnits;}+ (GLint)maximumVaryingVectorsForThisDevice;{  static dispatch_once_t pred;  static GLint maxVaryingVectors = 0;  dispatch_once(&pred, ^{    [self useImageProcessingContext];    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryingVectors);  });  return maxVaryingVectors;}+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;{  static dispatch_once_t pred;  static NSArray *extensionNames = nil;  // Cache extensions for later quick reference, since this won't change for a given device  dispatch_once(&pred, ^{    [GPUImageContext useImageProcessingContext];    NSString *extensionsString = [NSString stringWithCString:(const char *)glGetString(GL_EXTENSIONS) encoding:NSASCIIStringEncoding];    extensionNames = [extensionsString componentsSeparatedByString:@" "];  });  return [extensionNames containsObject:extension];}// http://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_rg.txt+ (BOOL)deviceSupportsRedTextures;{  static dispatch_once_t pred;  static BOOL supportsRedTextures = NO;    dispatch_once(&pred, ^{    supportsRedTextures = [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_texture_rg"];  });    return supportsRedTextures;}+ (BOOL)deviceSupportsFramebufferReads;{  static dispatch_once_t pred;  static BOOL supportsFramebufferReads = NO;    dispatch_once(&pred, ^{    supportsFramebufferReads = [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_shader_framebuffer_fetch"];  });    return supportsFramebufferReads;}+ (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;}- (void)presentBufferForDisplay;{  [self.context presentRenderbuffer:GL_RENDERBUFFER];}- (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];//    [shaderProgramUsageHistory addObject:lookupKeyForShaderProgram];//    if ([shaderProgramUsageHistory count] >= MAXSHADERPROGRAMSALLOWEDINCACHE)//    {//      for (NSUInteger currentShaderProgramRemovedFromCache = 0; currentShaderProgramRemovedFromCache < 10; currentShaderProgramRemovedFromCache++)//      {//        NSString *shaderProgramToRemoveFromCache = [shaderProgramUsageHistory objectAtIndex:0];//        [shaderProgramUsageHistory removeObjectAtIndex:0];//        [shaderProgramCache removeObjectForKey:shaderProgramToRemoveFromCache];//      }//    }  }    return programFromCache;}- (void)useSharegroup:(EAGLSharegroup *)sharegroup;{  NSAssert(_context == nil, @"Unable to use a share group when the context has already been created. Call this method before you use the context for the first time.");    _sharegroup = sharegroup;}- (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;}#pragma mark -#pragma mark Manage fast texture upload+ (BOOL)supportsFastTextureUpload;{#if TARGET_IPHONE_SIMULATOR  return NO;#else  #pragma clang diagnostic push#pragma clang diagnostic ignored "-Wtautological-pointer-compare"  return (CVOpenGLESTextureCacheCreate != NULL);#pragma clang diagnostic pop#endif}#pragma mark -#pragma mark Accessors- (EAGLContext *)context;{  if (_context == nil)  {    _context = [self createContext];    [EAGLContext setCurrentContext:_context];        // Set up a few global settings for the image processing pipeline    glDisable(GL_DEPTH_TEST);  }    return _context;}- (CVOpenGLESTextureCacheRef)coreVideoTextureCache;{  if (_coreVideoTextureCache == NULL)  {#if defined(__IPHONE_6_0)    CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [self context], NULL, &_coreVideoTextureCache);#else    CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[self context], NULL, &_coreVideoTextureCache);#endif        if (err)    {      NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d", err);    }  }    return _coreVideoTextureCache;}- (GPUImageFramebufferCache *)framebufferCache;{  if (_framebufferCache == nil)  {    _framebufferCache = [[GPUImageFramebufferCache alloc] init];  }    return _framebufferCache;}@end

View Code