• 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
  • 相关阅读:
    UE4美术之数学基础知识(一)
    如何用Unity制作逼真的自然场景?
    git拉取和上传项目代码
    Chaosblade-故障使用工具
    如何对数据库做优化
    分布式和集群的概念
    token、cookie、session的区别
    Json中的json.tojsonString()方法
    JSON的put方法
    fastjson中的相关方法
  • 原文地址:https://www.cnblogs.com/salam/p/4964560.html
Copyright © 2020-2023  润新知