Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support define custom filter outside the GPUImage framework bundle #77

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
BCD985BA1CA43FD5001FF01F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BCD985B81CA43FD5001FF01F /* LaunchScreen.storyboard */; };
BCD985D51CA48F15001FF01F /* WID-small.jpg in Resources */ = {isa = PBXBuildFile; fileRef = BCD985D41CA48F15001FF01F /* WID-small.jpg */; };
BCFB058C1CBF17FD009B2333 /* Assets-iOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BCFB058B1CBF17FD009B2333 /* Assets-iOS.xcassets */; };
CB3611A324357214007F3C0E /* Lambeau.jpg in Resources */ = {isa = PBXBuildFile; fileRef = CB3611A224357214007F3C0E /* Lambeau.jpg */; };
CB3611A5243572F9007F3C0E /* CustomBrightnessAdjustment.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB3611A4243572F9007F3C0E /* CustomBrightnessAdjustment.swift */; };
CB3611A724357309007F3C0E /* CustomBrightnessAdjustment.metal in Sources */ = {isa = PBXBuildFile; fileRef = CB3611A624357309007F3C0E /* CustomBrightnessAdjustment.metal */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -63,6 +66,9 @@
BCD985BB1CA43FD5001FF01F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BCD985D41CA48F15001FF01F /* WID-small.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = "WID-small.jpg"; path = "../../../SharedAssets/WID-small.jpg"; sourceTree = "<group>"; };
BCFB058B1CBF17FD009B2333 /* Assets-iOS.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = "Assets-iOS.xcassets"; path = "../../../SharedAssets/Assets-iOS.xcassets"; sourceTree = "<group>"; };
CB3611A224357214007F3C0E /* Lambeau.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = Lambeau.jpg; path = ../../../SharedAssets/Lambeau.jpg; sourceTree = "<group>"; };
CB3611A4243572F9007F3C0E /* CustomBrightnessAdjustment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomBrightnessAdjustment.swift; sourceTree = "<group>"; };
CB3611A624357309007F3C0E /* CustomBrightnessAdjustment.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = CustomBrightnessAdjustment.metal; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -107,6 +113,8 @@
children = (
BCD985AF1CA43FD5001FF01F /* AppDelegate.swift */,
BCD985B11CA43FD5001FF01F /* ViewController.swift */,
CB3611A4243572F9007F3C0E /* CustomBrightnessAdjustment.swift */,
CB3611A624357309007F3C0E /* CustomBrightnessAdjustment.metal */,
BCD985B31CA43FD5001FF01F /* Main.storyboard */,
BCD985CA1CA44005001FF01F /* Resources */,
);
Expand All @@ -118,6 +126,7 @@
children = (
BCFB058B1CBF17FD009B2333 /* Assets-iOS.xcassets */,
BCD985D41CA48F15001FF01F /* WID-small.jpg */,
CB3611A224357214007F3C0E /* Lambeau.jpg */,
BCD985B81CA43FD5001FF01F /* LaunchScreen.storyboard */,
BCD985BB1CA43FD5001FF01F /* Info.plist */,
);
Expand Down Expand Up @@ -167,8 +176,9 @@
TargetAttributes = {
BCD985AB1CA43FD5001FF01F = {
CreatedOnToolsVersion = 7.3;
DevelopmentTeam = J2U2U9GBML;
DevelopmentTeam = FLBD7VX6BF;
LastSwiftMigration = 0940;
ProvisioningStyle = Automatic;
};
};
};
Expand All @@ -177,6 +187,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down Expand Up @@ -219,6 +230,7 @@
buildActionMask = 2147483647;
files = (
BCD985BA1CA43FD5001FF01F /* LaunchScreen.storyboard in Resources */,
CB3611A324357214007F3C0E /* Lambeau.jpg in Resources */,
BCD985D51CA48F15001FF01F /* WID-small.jpg in Resources */,
BCFB058C1CBF17FD009B2333 /* Assets-iOS.xcassets in Resources */,
BCD985B51CA43FD5001FF01F /* Main.storyboard in Resources */,
Expand All @@ -233,6 +245,8 @@
buildActionMask = 2147483647;
files = (
BCD985B21CA43FD5001FF01F /* ViewController.swift in Sources */,
CB3611A724357309007F3C0E /* CustomBrightnessAdjustment.metal in Sources */,
CB3611A5243572F9007F3C0E /* CustomBrightnessAdjustment.swift in Sources */,
BCD985B01CA43FD5001FF01F /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -377,11 +391,14 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = J2U2U9GBML;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = SimpleImageFilter/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redqueencoder.SimpleImageFilter;
PRODUCT_BUNDLE_IDENTIFIER = com.sunsetlakesoftware.SimpleImageFilter;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
};
Expand All @@ -394,7 +411,7 @@
DEVELOPMENT_TEAM = J2U2U9GBML;
INFOPLIST_FILE = SimpleImageFilter/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redqueencoder.SimpleImageFilter;
PRODUCT_BUNDLE_IDENTIFIER = com.sunsetlakesoftware.SimpleImageFilter;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// CustomBrightnessAdjustment.metal
// SimpleImageFilter
//
// Created by yang on 2020/4/2.
// Copyright © 2020 Sunset Lake Software LLC. All rights reserved.
//

#include <metal_stdlib>
#include <GPUImage/OperationShaderTypes.h>

using namespace metal;

typedef struct
{
float brightness;
} BrightnessUniform;

fragment half4 brightnessFragment(SingleInputVertexIO fragmentInput [[stage_in]],
texture2d<half> inputTexture [[texture(0)]],
constant BrightnessUniform& uniform [[ buffer(1) ]])
{
constexpr sampler quadSampler;
half4 color = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);

return half4(color.rgb + uniform.brightness, color.a);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// CustomBrightnessAdjustment.swift
// SimpleImageFilter
//
// Created by yang on 2020/4/2.
// Copyright © 2020 Sunset Lake Software LLC. All rights reserved.
//

import GPUImage
import Foundation

class CustomBrightnessAdjustment: BasicOperation {
public var brightness:Float = 0.0 { didSet { uniformSettings["brightness"] = brightness } }

public init() {
let libraryPath = Bundle.main.path(forResource: "default", ofType: "metallib")!
super.init(fragmentFunctionName:"brightnessFragment", fragmentLibraryPath: libraryPath, numberOfInputs:1)

({brightness = 0.0})()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ViewController: UIViewController {

var picture:PictureInput!
var filter:SaturationAdjustment!
var customFilter: CustomBrightnessAdjustment!

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
Expand All @@ -28,7 +29,10 @@ class ViewController: UIViewController {
// Filtering image for display
picture = PictureInput(image:UIImage(named:"WID-small.jpg")!)
filter = SaturationAdjustment()
picture --> filter --> renderView
// demo for define custom filter outside GPUImage framework bundle
customFilter = CustomBrightnessAdjustment()
customFilter.brightness = 0.5
picture --> filter --> customFilter --> renderView
picture.processImage()
}
}
Expand Down
8 changes: 4 additions & 4 deletions framework/GPUImage.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
79CB6E3F210A106B0042F87B /* SubtractBlend.metal in Sources */ = {isa = PBXBuildFile; fileRef = 79CB6E3D210A106B0042F87B /* SubtractBlend.metal */; };
79CB6E41210A53CA0042F87B /* BlendShaderTypes.metal in Sources */ = {isa = PBXBuildFile; fileRef = 79CB6E40210A53C90042F87B /* BlendShaderTypes.metal */; };
79CB6E42210A53CA0042F87B /* BlendShaderTypes.metal in Sources */ = {isa = PBXBuildFile; fileRef = 79CB6E40210A53C90042F87B /* BlendShaderTypes.metal */; };
79CB6E45210A55CB0042F87B /* BlendShaderTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CB6E44210A55CB0042F87B /* BlendShaderTypes.h */; };
79CB6E45210A55CB0042F87B /* BlendShaderTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CB6E44210A55CB0042F87B /* BlendShaderTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
79CB6E46210A55CB0042F87B /* BlendShaderTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CB6E44210A55CB0042F87B /* BlendShaderTypes.h */; };
79DD50C4213450BE004EF308 /* SwirlDistortion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DD50C3213450BE004EF308 /* SwirlDistortion.swift */; };
79DD50C5213450BE004EF308 /* SwirlDistortion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DD50C3213450BE004EF308 /* SwirlDistortion.swift */; };
Expand Down Expand Up @@ -350,7 +350,7 @@
BC7BA27420F2BD1E006B5F4B /* ShaderUniformSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA27320F2BD1E006B5F4B /* ShaderUniformSettings.swift */; };
BC7BA27720F2C269006B5F4B /* BrightnessAdjustment.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA27620F2C269006B5F4B /* BrightnessAdjustment.swift */; };
BC7BA27920F2C2CF006B5F4B /* BrightnessAdjustment.metal in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA27820F2C2CF006B5F4B /* BrightnessAdjustment.metal */; };
BC7BA27B20F2C5E8006B5F4B /* OperationShaderTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7BA27A20F2C5E8006B5F4B /* OperationShaderTypes.h */; };
BC7BA27B20F2C5E8006B5F4B /* OperationShaderTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7BA27A20F2C5E8006B5F4B /* OperationShaderTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC7BA27C20F2C5E8006B5F4B /* OperationShaderTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7BA27A20F2C5E8006B5F4B /* OperationShaderTypes.h */; };
BC7BA28120F599DD006B5F4B /* MonochromeFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA28020F599DD006B5F4B /* MonochromeFilter.swift */; };
BC7BA28220F599DD006B5F4B /* MonochromeFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC7BA28020F599DD006B5F4B /* MonochromeFilter.swift */; };
Expand All @@ -377,7 +377,7 @@
BCC6AB60210E5E7900F9803A /* TextureSamplingOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCC6AB5E210E5E7900F9803A /* TextureSamplingOperation.swift */; };
BCC6AB62210E5ECE00F9803A /* NearbyTexelSampling.metal in Sources */ = {isa = PBXBuildFile; fileRef = BCC6AB61210E5ECE00F9803A /* NearbyTexelSampling.metal */; };
BCC6AB63210E5ECE00F9803A /* NearbyTexelSampling.metal in Sources */ = {isa = PBXBuildFile; fileRef = BCC6AB61210E5ECE00F9803A /* NearbyTexelSampling.metal */; };
BCC6AB65210E5FF600F9803A /* TexelSamplingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC6AB64210E5FF600F9803A /* TexelSamplingTypes.h */; };
BCC6AB65210E5FF600F9803A /* TexelSamplingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC6AB64210E5FF600F9803A /* TexelSamplingTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
BCC6AB66210E5FF600F9803A /* TexelSamplingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC6AB64210E5FF600F9803A /* TexelSamplingTypes.h */; };
BCC6AB69210E62EB00F9803A /* Convolution3x3.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCC6AB68210E62EB00F9803A /* Convolution3x3.swift */; };
BCC6AB6A210E62EB00F9803A /* Convolution3x3.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCC6AB68210E62EB00F9803A /* Convolution3x3.swift */; };
Expand Down Expand Up @@ -931,8 +931,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
BCC6AB65210E5FF600F9803A /* TexelSamplingTypes.h in Headers */,
BC7BA27B20F2C5E8006B5F4B /* OperationShaderTypes.h in Headers */,
BCC6AB65210E5FF600F9803A /* TexelSamplingTypes.h in Headers */,
79CB6E45210A55CB0042F87B /* BlendShaderTypes.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
4 changes: 2 additions & 2 deletions framework/Source/BasicOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ open class BasicOperation: ImageProcessingOperation {
var useNormalizedTextureCoordinates = true
var metalPerformanceShaderPathway: ((MTLCommandBuffer, [UInt:Texture], Texture) -> ())?

public init(vertexFunctionName: String? = nil, fragmentFunctionName: String, numberOfInputs: UInt = 1, operationName: String = #file) {
public init(vertexFunctionName: String? = nil, vertexLibraryPath: String? = nil, fragmentFunctionName: String, fragmentLibraryPath: String? = nil, numberOfInputs: UInt = 1, operationName: String = #file) {
self.maximumInputs = numberOfInputs
self.operationName = operationName

let concreteVertexFunctionName = vertexFunctionName ?? defaultVertexFunctionNameForInputs(numberOfInputs)
let (pipelineState, lookupTable) = generateRenderPipelineState(device:sharedMetalRenderingDevice, vertexFunctionName:concreteVertexFunctionName, fragmentFunctionName:fragmentFunctionName, operationName:operationName)
let (pipelineState, lookupTable) = generateRenderPipelineState(device:sharedMetalRenderingDevice, vertexFunctionName:concreteVertexFunctionName, vertexLibraryPath: vertexLibraryPath, fragmentFunctionName:fragmentFunctionName, fragmentLibraryPath: fragmentLibraryPath, operationName:operationName)
self.renderPipelineState = pipelineState
self.uniformSettings = ShaderUniformSettings(uniformLookupTable:lookupTable)
}
Expand Down
6 changes: 3 additions & 3 deletions framework/Source/MetalRendering.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ extension MTLCommandBuffer {
}
}

func generateRenderPipelineState(device:MetalRenderingDevice, vertexFunctionName:String, fragmentFunctionName:String, operationName:String) -> (MTLRenderPipelineState, [String:(Int, MTLDataType)]) {
guard let vertexFunction = device.shaderLibrary.makeFunction(name: vertexFunctionName) else {
func generateRenderPipelineState(device:MetalRenderingDevice, vertexFunctionName:String, vertexLibraryPath: String? = nil, fragmentFunctionName:String, fragmentLibraryPath: String? = nil, operationName:String) -> (MTLRenderPipelineState, [String:(Int, MTLDataType)]) {
guard let vertexFunction = device.library(for: vertexLibraryPath).makeFunction(name: vertexFunctionName) else {
fatalError("\(operationName): could not compile vertex function \(vertexFunctionName)")
}

guard let fragmentFunction = device.shaderLibrary.makeFunction(name: fragmentFunctionName) else {
guard let fragmentFunction = device.library(for: fragmentLibraryPath).makeFunction(name: fragmentFunctionName) else {
fatalError("\(operationName): could not compile fragment function \(fragmentFunctionName)")
}

Expand Down
14 changes: 14 additions & 0 deletions framework/Source/MetalRenderingDevice.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ public class MetalRenderingDevice {
public let commandQueue: MTLCommandQueue
public let shaderLibrary: MTLLibrary
public let metalPerformanceShadersAreSupported: Bool

func library(for path: String? = nil) -> MTLLibrary {
guard let path = path else { return shaderLibrary }
guard libraryMap[path] == nil else { return libraryMap[path]! }
do {
let library = try device.makeLibrary(filepath: path)
libraryMap[path] = library
return library
} catch {
fatalError("Could not load library for bundle: \(path)")
}
}
private var libraryMap: [String: MTLLibrary] = [:]

lazy var passthroughRenderState: MTLRenderPipelineState = {
let (pipelineState, _) = generateRenderPipelineState(device:self, vertexFunctionName:"oneInputVertex", fragmentFunctionName:"passthroughFragment", operationName:"Passthrough")
Expand Down Expand Up @@ -41,6 +54,7 @@ public class MetalRenderingDevice {
let metalLibraryPath = frameworkBundle.path(forResource: "default", ofType: "metallib")!

self.shaderLibrary = try device.makeLibrary(filepath:metalLibraryPath)
libraryMap[metalLibraryPath] = self.shaderLibrary
} catch {
fatalError("Could not load library")
}
Expand Down
2 changes: 1 addition & 1 deletion framework/Source/TextureSamplingOperation.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
open class TextureSamplingOperation: BasicOperation {
// public var overriddenTexelSize:Size?

override public init(vertexFunctionName: String? = "nearbyTexelSampling",
public init(vertexFunctionName: String? = "nearbyTexelSampling",
fragmentFunctionName: String,
numberOfInputs: UInt = 1,
operationName: String = #file) {
Expand Down