/* CoreImage - CIRenderDestination.h Copyright (c) 2017 Apple, Inc. All rights reserved. */ #ifndef CIRENDERDESTINATION_H #define CIRENDERDESTINATION_H #ifdef __OBJC__ #import #import #import #import #import #import #if COREIMAGE_SUPPORTS_IOSURFACE #import #endif #import @protocol MTLTexture, MTLCommandBuffer; NS_ASSUME_NONNULL_BEGIN // This is a lightweight API to allow clients to specify all the // attributes of a render that pertain to the render's destination. // It is intended to be used for issuing renders that return to the // caller as soon as all the work has been issued but before it completes/ // NS_CLASS_AVAILABLE(10_13, 11_0) @interface CIRenderDestination : NSObject { void *_priv; } // MARK: PixelBuffer destinations // Create a CIRenderDestination based on a CVPixelBufferRef object. // // The destination's 'colorspace' property will default a CGColorSpace created by, // querying the CVPixelBufferRef attributes. // - (instancetype) initWithPixelBuffer:(CVPixelBufferRef)pixelBuffer; // MARK: Surface destinations #if COREIMAGE_SUPPORTS_IOSURFACE // Create a CIRenderDestination based on an IOSurface object. // // The destination's 'colorspace' property will default a CGColorSpace created by, // querying the IOSurface attributes. // - (instancetype) initWithIOSurface:(IOSurface*)surface; #endif // MARK: Metal destinations // A render to a MTLTexture-backed CIRenderDestination is only supported by MTLTexture-backed CIContexts. // The texture must have a MTLTextureType of MTLTextureType2D // // An optional MTLCommandBuffer can be specified, with which to use for rendering to the MTLTexture. // NOTE: Rendering to a texture initialized with a commandBuffer requires encoding all the commands to render an image into the specified buffer. // This may impact system responsiveness and may result in higher memory usage if the image requires many passes to render. // To avoid this impact, it is recommended to create a context using [CIContext contextWithMTLCommandQueue:] and create the CIRenderDestination without specifying a buffer. // // The destination's 'colorspace' property will default a CGColorSpace created with kCGColorSpaceSRGB, // kCGColorSpaceExtendedSRGB, or kCGColorSpaceGenericGrayGamma2_2. // - (instancetype) initWithMTLTexture:(id)texture commandBuffer:(nullable id)commandBuffer; // Create a CIRenderDestination based on a Metal texture. // // Rendering to a MTLTexture-backed CIRenderDestination is only supported by MTLTexture-backed CIContexts. // The provider 'block' will be called lazily when the destination is rendered to. // The block must return a texture with a MTLTextureType of MTLTextureType2D. // The 'width', 'height' and 'pixelFormat' argument values should be the same as the // width, height and pixelFormat of the MTLTexture that will be returned by 'block' // // An optional MTLCommandBuffer can be specified, with which to use for rendering to the MTLTexture. // NOTE: Rendering to a texture initialized with a commandBuffer requires encoding all the commands to render an image into the specified buffer. // This may impact system responsiveness and may result in higher memory usage if the image requires many passes to render. // To avoid this impact, it is recommended to create a context using [CIContext contextWithMTLCommandQueue:] and create the CIRenderDestination without specifying a buffer. // // The destination's 'colorspace' property will default a CGColorSpace created with kCGColorSpaceSRGB, // kCGColorSpaceExtendedSRGB, or kCGColorSpaceGenericGrayGamma2_2. // - (instancetype) initWithWidth:(NSUInteger)width height:(NSUInteger)height pixelFormat:(MTLPixelFormat)pixelFormat commandBuffer:(nullable id)commandBuffer mtlTextureProvider:(nullable id (^)(void))block; // MARK: OpenGL destination // Create a CIRenderDestination based on an OpenGL texture. // // Rendering to a GLTexture-backed CIRenderDestination is only supported by GLContext-backed CIContexts. // The texture id must be bound to a GLContext that is shared with that of the GLContext-backed CIContext. // // The destination's 'colorspace' property will default a CGColorSpace created with kCGColorSpaceSRGB, // kCGColorSpaceExtendedSRGB, or kCGColorSpaceGenericGrayGamma2_2. // - (instancetype) initWithGLTexture:(unsigned int)texture target:(unsigned int)target // GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_EXT width:(NSUInteger)width height:(NSUInteger)height; // MARK: Bitmap data destination // Create a CIRenderDestination based on client-managed buffer. // // The 'data' parameter must point to a buffer that is at least bytesPerRow * height bytes in size. // // The destination's 'colorspace' property will default a CGColorSpace created with kCGColorSpaceSRGB, // kCGColorSpaceExtendedSRGB, or kCGColorSpaceGenericGrayGamma2_2. - (instancetype) initWithBitmapData:(void *)data width:(NSUInteger)width height:(NSUInteger)height bytesPerRow:(NSUInteger)bytesPerRow format:(CIFormat)format; // MARK: Properties @property (readonly) NSUInteger width; @property (readonly) NSUInteger height; typedef NS_ENUM(NSUInteger, CIRenderDestinationAlphaMode) { CIRenderDestinationAlphaNone = 0, CIRenderDestinationAlphaPremultiplied = 1, CIRenderDestinationAlphaUnpremultiplied = 2 }; // This property will default to an appropriate value given // the object that the CIRenderDestination was initialized with. // This property can be set to a different value if desired. @property CIRenderDestinationAlphaMode alphaMode; // The logical coordinate system of a CIRenderDestination is always cartesian: // (0,0) represents the lower-left corner // (0.5,0.5) represents the lower-left pixel center // (pixelsWide-0.5,pixelsHigh-0.5) represents the upper-right pixel center // (pixelsWide,pixelsHigh) represents the upper-right corner. // // The 'flipped' property controls how pixels this logical coordinate system // are stored into the memory of the object backing the destination. // // If 'flipped' is false, then the base address of the backing stores the // pixel centered on the logical coordinate (0.5,0.5) // // If 'flipped' is true, then the base address of the backing stores the // pixel centered on the logical coordinate (0.5,height-0.5) // @property (getter=isFlipped) BOOL flipped; // Instructs the render to add pseudo-random luma noise given the depth of the destination. // The magnitude of the noise is approximately ±pow(2,-(bitPerComponent+1)) @property (getter=isDithered) BOOL dithered; // If true, the render will clamp color channels // to 0..alpha if 'alphaMode' is premultiplied otherwise 0..1 // This property is initialized to false if the destination's format supports extended range @property (getter=isClamped) BOOL clamped; // This property will default to an appropriate value given // the object that the CIRenderDestination was initialized with. // This property can be set to a different colorSpace if desired. // This property can be set to nil to disable color matching // from the working space to the destination. @property (nullable, nonatomic) CGColorSpaceRef colorSpace; // Allow client to specify a CIBlendKernel (e.g. CIBlendKernel.sourceOver) // to be used on the destination. @property (nullable, nonatomic, retain) CIBlendKernel* blendKernel; // If true, then the blendKernel is applied in the destination's colorSpace. // If false, then the blendKernel is applied in the CIContext's working colorspace. // This is false by default. @property BOOL blendsInDestinationColorSpace; /// Tell the next render using this destination to capture a Metal trace. /// /// If this property is set to a file-based URL, then the next render using this /// destination will capture a Metal trace, deleting any existing file if present. /// This property is nil by default. @property (nullable, nonatomic, retain) NSURL* captureTraceURL NS_AVAILABLE(16_0, 19_0); @end // An Xcode quicklook of this object will show a graph visualization of the render // with detailed timing information. NS_CLASS_AVAILABLE(10_13, 11_0) @interface CIRenderInfo : NSObject { void *_priv; } // This property will return how much time a render spent executing kernels. @property (readonly) NSTimeInterval kernelExecutionTime; // This property will return how much time a render spent compiling kernels. @property (readonly) NSTimeInterval kernelCompileTime NS_AVAILABLE(14_0, 17_0); // This property will return how many passes the render requires. // If passCount is 1 than the render can be fully concatinated and no // intermediate buffers will be required. @property (readonly) NSInteger passCount; // This property will return how many pixels a render produced executing kernels. @property (readonly) NSInteger pixelsProcessed; @end // An Xcode quicklook of this object will show a graph visualization of the render NS_CLASS_AVAILABLE(10_13, 11_0) @interface CIRenderTask : NSObject { void *_priv; } - (nullable CIRenderInfo*) waitUntilCompletedAndReturnError:(NSError**)error; @end @interface CIContext (CIRenderDestination) // Renders a portion of image to a point of destination // It renders as if 'image' is cropped to 'fromRect' // and the origin of the result is placed at 'atPoint' // // If image.extent and fromRect are infinite, then it renders // so that point (0,0) of image is placed at 'atPoint' // // MTLTexture-backed CIRenderDestinations are only supported by MTLTexture-backed CIContexts. // GLTexture-backed CIRenderDestinations are only supported by GLContext-backed CIContexts. // // For contexts that are initialized with a command queue, this call will return as soon as all the work for the render is enqueued on the // context's device. // Otherwise, it will return as soon as all the work is scheduled. // // In many situations, after issuing a render, the client can use the destination // or its backing object without waiting for the enqueued work to complete. // For example, after rendering a surface CIRenderDestination, the surface can be passed // on for further processing by the GPU. // // In other situations, the client may need to wait for the render to be complete. // For example, after rendering a surface CIRenderDestination, the surface can be accessed // by CPU code by calling IOSurfaceGetBytePointer only after the render is completed. // // In this case the client can use the returned CIRenderTask like this: // CIRenderTask* task = [context render:...]; // [task waitUntilCompletedAndReturnError:&error]; // - (nullable CIRenderTask*) startTaskToRender:(CIImage*)image fromRect:(CGRect)fromRect toDestination:(CIRenderDestination*)destination atPoint:(CGPoint)atPoint error:(NSError**)error NS_AVAILABLE(10_13, 11_0); // Renders an image to a destination so that point (0,0) of image. // is placed at point (0,0) of the destination. // - (nullable CIRenderTask*) startTaskToRender:(CIImage*)image toDestination:(CIRenderDestination*)destination error:(NSError**)error NS_AVAILABLE(10_13, 11_0); // This is an optional call which can be used to "warm up" a CIContext so that // a subsequent call to render with the same arguments can be more efficient. // By making this call, Core Image will ensure that // - any needed kernels will be compiled // - any intermedate buffers are allocated and marked volatile // - (BOOL) prepareRender:(CIImage*)image fromRect:(CGRect)fromRect toDestination:(CIRenderDestination*)destination atPoint:(CGPoint)atPoint error:(NSError**)error NS_AVAILABLE(10_13, 11_0); // Fill the entire destination with black (0,0,0,1) if its alphaMode is None // or clear (0,0,0,0) if its alphaMode is Premultiplied or Unpremultiplied. // - (nullable CIRenderTask*) startTaskToClear:(CIRenderDestination*)destination error:(NSError**)error NS_AVAILABLE(10_13, 11_0); @end NS_ASSUME_NONNULL_END #endif /* __OBJC__ */ #endif /* CIRENDERDESTINATION_H */