1 /*
2 * This file is part of openfx-arena <https://github.com/olear/openfx-arena>,
3 * Copyright (C) 2016 INRIA
4 *
5 * openfx-arena is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation.
8 *
9 * openfx-arena is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with openfx-arena. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
16 */
17
18 #include "OCLPlugin.h"
19
20 using namespace OFX;
21 OFXS_NAMESPACE_ANONYMOUS_ENTER
22
23 #define kPluginName "CLFilter"
24 #define kPluginGrouping "Filter"
25 #define kPluginIdentifier "net.fxarena.opencl.CLFilter"
26 #define kPluginDescription "OpenCL filter meta node."
27 #define kPluginVersionMajor 1
28 #define kPluginVersionMinor 0
29
30 #define kSupportsTiles 0
31 #define kSupportsMultiResolution 1
32 #define kSupportsRenderScale 1
33 #define kRenderThreadSafety eRenderFullySafe
34 #define kHostFrameThreading false
35 #define kHostMasking true
36 #define kHostMixing true
37
38 #define kParamKernel "kernel"
39 #define kParamKernelLabel "Kernel"
40 #define kParamKernelHint "The kernel to build and use."
41 #define kParamKernelDefault \
42 "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;\n" \
43 "void kernel filter(__read_only image2d_t input, __write_only image2d_t output)\n" \
44 "{ /* basic image copy: */ \n"\
45 "int2 pos = {get_global_id(0), get_global_id(1)};\n" \
46 "float4 pixels = read_imagef(input, sampler, pos);\n" \
47 "write_imagef(output, pos, pixels);\n" \
48 "}\n"
49
50 class CLFilterCLPlugin
51 : public OCLPluginHelper<kSupportsRenderScale>
52 {
53 public:
CLFilterCLPlugin(OfxImageEffectHandle handle)54 CLFilterCLPlugin(OfxImageEffectHandle handle)
55 : OCLPluginHelper<kSupportsRenderScale>(handle, "", "")
56 , _kSource(NULL)
57 {
58 _kSource = fetchStringParam(kParamKernel);
59 assert(_kSource);
60
61 std::string source;
62 _kSource->getValue(source);
63 setupContext(false, source);
64 }
65
render(const OFX::RenderArguments &,cl::Kernel)66 virtual void render(const OFX::RenderArguments &/*args*/, cl::Kernel /*kernel*/) OVERRIDE FINAL
67 {
68 }
69 virtual void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName) OVERRIDE FINAL;
70 private:
71 OFX::StringParam *_kSource;
72 };
73
changedParam(const OFX::InstanceChangedArgs & args,const std::string & paramName)74 void CLFilterCLPlugin::changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName)
75 {
76 if (!kSupportsRenderScale && (args.renderScale.x != 1. || args.renderScale.y != 1.)) {
77 OFX::throwSuiteStatusException(kOfxStatFailed);
78 return;
79 }
80
81 std::string source;
82 _kSource->getValueAtTime(args.time, source);
83
84 if (paramName == kParamOCLDevice) {
85 setupContext(true, source);
86 }
87 else if (paramName == kParamKernel) {
88 setupContext(false, source);
89 }
90
91 clearPersistentMessage();
92 }
93
94 mDeclarePluginFactory(CLFilterCLPluginFactory, {}, {});
95
describe(ImageEffectDescriptor & desc)96 void CLFilterCLPluginFactory::describe(ImageEffectDescriptor &desc)
97 {
98 desc.setLabel(kPluginName);
99 desc.setPluginGrouping(kPluginGrouping);
100 desc.setPluginDescription(kPluginDescription);
101 desc.addSupportedContext(eContextGeneral);
102 desc.addSupportedContext(eContextFilter);
103 desc.addSupportedBitDepth(eBitDepthFloat);
104 desc.setSupportsTiles(kSupportsTiles);
105 desc.setSupportsMultiResolution(kSupportsMultiResolution);
106 desc.setRenderThreadSafety(kRenderThreadSafety);
107 desc.setHostFrameThreading(kHostFrameThreading);
108 desc.setHostMaskingEnabled(kHostMasking);
109 desc.setHostMixingEnabled(kHostMixing);
110 }
111
describeInContext(ImageEffectDescriptor & desc,ContextEnum context)112 void CLFilterCLPluginFactory::describeInContext(ImageEffectDescriptor &desc, ContextEnum context)
113 {
114 OFX::PageParamDescriptor *page = CLFilterCLPlugin::describeInContextBegin(desc, context);
115 {
116 StringParamDescriptor* param = desc.defineStringParam(kParamKernel);
117 param->setLabel(kParamKernelLabel);
118 param->setHint(kParamKernelHint);
119 param->setStringType(eStringTypeMultiLine);
120 param->setAnimates(true);
121 param->setDefault(kParamKernelDefault);
122 page->addChild(*param);
123 }
124 CLFilterCLPlugin::describeInContextEnd(desc, context, page);
125 }
126
127 OFX::ImageEffect*
createInstance(OfxImageEffectHandle handle,ContextEnum)128 CLFilterCLPluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
129 {
130 return new CLFilterCLPlugin(handle);
131 }
132
133 static CLFilterCLPluginFactory p(kPluginIdentifier, kPluginVersionMajor, kPluginVersionMinor);
134 mRegisterPluginFactoryInstance(p)
135
136 OFXS_NAMESPACE_ANONYMOUS_EXIT
137