zoukankan      html  css  js  c++  java
  • GPUImage API文档之GPUImageFramebufferCache类

      GPUImageFramebufferCache类负责管理GPUImageFramebuffer对象,是一个GPUImageFramebuffer对象的缓存。

      方法

      - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture

      说明:从cache中获取一个GPUImageFramebuffer对象,如果获取失败,那么创建一个新的GPUImageFramebuffer对象。

      参数:framebufferSize是对象的大小,textureOptions是纹理的配置信息,onlyTexture指示是否只为纹理,是否包含framebuffer对象。

      返回:一个GPUImageFramebuffer对象

      实现

    - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;
    {
        __block GPUImageFramebuffer *framebufferFromCache = nil;
    //    dispatch_sync(framebufferCacheQueue, ^{
        runSynchronouslyOnVideoProcessingQueue(^{
            NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];
            NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];
            NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];
            
            if ([numberOfMatchingTexturesInCache integerValue] < 1)
            {
                // Nothing in the cache, create a new framebuffer to use
                framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];
            }
            else
            {
                // Something found, pull the old framebuffer and decrement the count
                NSInteger currentTextureID = (numberOfMatchingTextures - 1);
                while ((framebufferFromCache == nil) && (currentTextureID >= 0))
                {
                    NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)currentTextureID];
                    framebufferFromCache = [framebufferCache objectForKey:textureHash];
                    // Test the values in the cache first, to see if they got invalidated behind our back
                    if (framebufferFromCache != nil)
                    {
                        // Withdraw this from the cache while it's in use
                        [framebufferCache removeObjectForKey:textureHash];
                    }
                    currentTextureID--;
                }
                
                currentTextureID++;
                
                [framebufferTypeCounts setObject:[NSNumber numberWithInteger:currentTextureID] forKey:lookupHash];
                
                if (framebufferFromCache == nil)
                {
                    framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];
                }
            }
        });
    
        [framebufferFromCache lock];
        return framebufferFromCache;
    }

      - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture

      说明:同上

      实现

    - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture;
    {
        GPUTextureOptions defaultTextureOptions;
        defaultTextureOptions.minFilter = GL_LINEAR;
        defaultTextureOptions.magFilter = GL_LINEAR;
        defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;
        defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;
        defaultTextureOptions.internalFormat = GL_RGBA;
        defaultTextureOptions.format = GL_BGRA;
        defaultTextureOptions.type = GL_UNSIGNED_BYTE;
        
        return [self fetchFramebufferForSize:framebufferSize textureOptions:defaultTextureOptions onlyTexture:onlyTexture];
    }

      - (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer

      说明:向GPUImageFramebuffer缓存加添加GPUImageFramebuffer对象

      参数:需要添加的GPUImageFramebuffer对象

      实现

    - (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer;
    {
        [framebuffer clearAllLocks];
        
    //    dispatch_async(framebufferCacheQueue, ^{
        runAsynchronouslyOnVideoProcessingQueue(^{
            CGSize framebufferSize = framebuffer.size;
            GPUTextureOptions framebufferTextureOptions = framebuffer.textureOptions;
            NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:framebufferTextureOptions onlyTexture:framebuffer.missingFramebuffer];
            NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];
            NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];
            
            NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)numberOfMatchingTextures];
            
    //        [framebufferCache setObject:framebuffer forKey:textureHash cost:round(framebufferSize.width * framebufferSize.height * 4.0)];
            [framebufferCache setObject:framebuffer forKey:textureHash];
            [framebufferTypeCounts setObject:[NSNumber numberWithInteger:(numberOfMatchingTextures + 1)] forKey:lookupHash];
        });
    }

      - (void)purgeAllUnassignedFramebuffers

      说明:清理缓存中的纹理缓存,清理framebufferCache中的所有对象

      实现

    - (void)purgeAllUnassignedFramebuffers;
    {
        runAsynchronouslyOnVideoProcessingQueue(^{
    //    dispatch_async(framebufferCacheQueue, ^{
            [framebufferCache removeAllObjects];
            [framebufferTypeCounts removeAllObjects];
    #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
            CVOpenGLESTextureCacheFlush([[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], 0);
    #else
    #endif
        });
    }

      - (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer

      说明:

      实现

    - (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;
    {
        runAsynchronouslyOnVideoProcessingQueue(^{
    //    dispatch_async(framebufferCacheQueue, ^{
            [activeImageCaptureList addObject:framebuffer];
        });
    }

      - (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer

      说明:

      实现

    - (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;
    {
        runAsynchronouslyOnVideoProcessingQueue(^{
    //  dispatch_async(framebufferCacheQueue, ^{
            [activeImageCaptureList removeObject:framebuffer];
        });
    }

    完整代码

    #import <Foundation/Foundation.h>
    #import <QuartzCore/QuartzCore.h>
    #import "GPUImageFramebuffer.h"
    
    @interface GPUImageFramebufferCache : NSObject
    
    // Framebuffer management
    - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;
    - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture;
    - (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer;
    - (void)purgeAllUnassignedFramebuffers;
    - (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;
    - (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;
    
    @end
    #import "GPUImageFramebufferCache.h"
    #import "GPUImageContext.h"
    #import "GPUImageOutput.h"
    
    #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
    #import <UIKit/UIKit.h>
    #else
    #endif
    
    @interface GPUImageFramebufferCache()
    {
    //    NSCache *framebufferCache;
        NSMutableDictionary *framebufferCache;
        NSMutableDictionary *framebufferTypeCounts;
        NSMutableArray *activeImageCaptureList; // Where framebuffers that may be lost by a filter, but which are still needed for a UIImage, etc., are stored
        id memoryWarningObserver;
    
        dispatch_queue_t framebufferCacheQueue;
    }
    
    - (NSString *)hashForSize:(CGSize)size textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;
    
    @end
    
    
    @implementation GPUImageFramebufferCache
    
    #pragma mark -
    #pragma mark Initialization and teardown
    
    - (id)init;
    {
        if (!(self = [super init]))
        {
            return nil;
        }
        
    #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
        memoryWarningObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
            
            [self purgeAllUnassignedFramebuffers];
        }];
    #else
    #endif
    
    //    framebufferCache = [[NSCache alloc] init];
        framebufferCache = [[NSMutableDictionary alloc] init];
        framebufferTypeCounts = [[NSMutableDictionary alloc] init];
        activeImageCaptureList = [[NSMutableArray alloc] init];
        framebufferCacheQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.framebufferCacheQueue", NULL);
        
        return self;
    }
    
    #pragma mark -
    #pragma mark Framebuffer management
    
    - (NSString *)hashForSize:(CGSize)size textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;
    {
        if (onlyTexture)
        {
            return [NSString stringWithFormat:@"%.1fx%.1f-%d:%d:%d:%d:%d:%d:%d-NOFB", size.width, size.height, textureOptions.minFilter, textureOptions.magFilter, textureOptions.wrapS, textureOptions.wrapT, textureOptions.internalFormat, textureOptions.format, textureOptions.type];
        }
        else
        {
            return [NSString stringWithFormat:@"%.1fx%.1f-%d:%d:%d:%d:%d:%d:%d", size.width, size.height, textureOptions.minFilter, textureOptions.magFilter, textureOptions.wrapS, textureOptions.wrapT, textureOptions.internalFormat, textureOptions.format, textureOptions.type];
        }
    }
    
    - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;
    {
        __block GPUImageFramebuffer *framebufferFromCache = nil;
    //    dispatch_sync(framebufferCacheQueue, ^{
        runSynchronouslyOnVideoProcessingQueue(^{
            NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];
            NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];
            NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];
            
            if ([numberOfMatchingTexturesInCache integerValue] < 1)
            {
                // Nothing in the cache, create a new framebuffer to use
                framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];
            }
            else
            {
                // Something found, pull the old framebuffer and decrement the count
                NSInteger currentTextureID = (numberOfMatchingTextures - 1);
                while ((framebufferFromCache == nil) && (currentTextureID >= 0))
                {
                    NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)currentTextureID];
                    framebufferFromCache = [framebufferCache objectForKey:textureHash];
                    // Test the values in the cache first, to see if they got invalidated behind our back
                    if (framebufferFromCache != nil)
                    {
                        // Withdraw this from the cache while it's in use
                        [framebufferCache removeObjectForKey:textureHash];
                    }
                    currentTextureID--;
                }
                
                currentTextureID++;
                
                [framebufferTypeCounts setObject:[NSNumber numberWithInteger:currentTextureID] forKey:lookupHash];
                
                if (framebufferFromCache == nil)
                {
                    framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];
                }
            }
        });
    
        [framebufferFromCache lock];
        return framebufferFromCache;
    }
    
    - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture;
    {
        GPUTextureOptions defaultTextureOptions;
        defaultTextureOptions.minFilter = GL_LINEAR;
        defaultTextureOptions.magFilter = GL_LINEAR;
        defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;
        defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;
        defaultTextureOptions.internalFormat = GL_RGBA;
        defaultTextureOptions.format = GL_BGRA;
        defaultTextureOptions.type = GL_UNSIGNED_BYTE;
        
        return [self fetchFramebufferForSize:framebufferSize textureOptions:defaultTextureOptions onlyTexture:onlyTexture];
    }
    
    - (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer;
    {
        [framebuffer clearAllLocks];
        
    //    dispatch_async(framebufferCacheQueue, ^{
        runAsynchronouslyOnVideoProcessingQueue(^{
            CGSize framebufferSize = framebuffer.size;
            GPUTextureOptions framebufferTextureOptions = framebuffer.textureOptions;
            NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:framebufferTextureOptions onlyTexture:framebuffer.missingFramebuffer];
            NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];
            NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];
            
            NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)numberOfMatchingTextures];
            
    //        [framebufferCache setObject:framebuffer forKey:textureHash cost:round(framebufferSize.width * framebufferSize.height * 4.0)];
            [framebufferCache setObject:framebuffer forKey:textureHash];
            [framebufferTypeCounts setObject:[NSNumber numberWithInteger:(numberOfMatchingTextures + 1)] forKey:lookupHash];
        });
    }
    
    - (void)purgeAllUnassignedFramebuffers;
    {
        runAsynchronouslyOnVideoProcessingQueue(^{
    //    dispatch_async(framebufferCacheQueue, ^{
            [framebufferCache removeAllObjects];
            [framebufferTypeCounts removeAllObjects];
    #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
            CVOpenGLESTextureCacheFlush([[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], 0);
    #else
    #endif
        });
    }
    
    - (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;
    {
        runAsynchronouslyOnVideoProcessingQueue(^{
    //    dispatch_async(framebufferCacheQueue, ^{
            [activeImageCaptureList addObject:framebuffer];
        });
    }
    
    - (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;
    {
        runAsynchronouslyOnVideoProcessingQueue(^{
    //  dispatch_async(framebufferCacheQueue, ^{
            [activeImageCaptureList removeObject:framebuffer];
        });
    }
    
    @end
  • 相关阅读:
    洛谷 P3868 [TJOI2009]猜数字
    洛谷 P2661 信息传递
    hdu 5418 Victor and World
    洛谷 P5024 保卫王国
    洛谷 P2470 [SCOI2007]压缩
    双栈排序 2008年NOIP全国联赛提高组(二分图染色)
    理想的正方形 HAOI2007(二维RMQ)
    10.23NOIP模拟题
    疫情控制 2012年NOIP全国联赛提高组(二分答案+贪心)
    图论模板
  • 原文地址:https://www.cnblogs.com/salam/p/4964490.html
Copyright © 2011-2022 走看看