blob: be4d6c2d5c369658cbcbdb946f6f6f3e3bd2de8c [file] [log] [blame]
bsalomonf267c1e2016-02-01 13:16:14 -08001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrYUVEffect.h"
9
10#include "GrCoordTransform.h"
11#include "GrFragmentProcessor.h"
bsalomonf267c1e2016-02-01 13:16:14 -080012#include "GrProcessor.h"
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -050013#include "GrTextureProxy.h"
bsalomonf267c1e2016-02-01 13:16:14 -080014#include "glsl/GrGLSLFragmentProcessor.h"
15#include "glsl/GrGLSLFragmentShaderBuilder.h"
16#include "glsl/GrGLSLProgramDataManager.h"
17#include "glsl/GrGLSLUniformHandler.h"
18
19namespace {
20
21static const float kJPEGConversionMatrix[16] = {
22 1.0f, 0.0f, 1.402f, -0.701f,
23 1.0f, -0.34414f, -0.71414f, 0.529f,
24 1.0f, 1.772f, 0.0f, -0.886f,
25 0.0f, 0.0f, 0.0f, 1.0
26};
27
28static const float kRec601ConversionMatrix[16] = {
29 1.164f, 0.0f, 1.596f, -0.87075f,
30 1.164f, -0.391f, -0.813f, 0.52925f,
31 1.164f, 2.018f, 0.0f, -1.08175f,
32 0.0f, 0.0f, 0.0f, 1.0}
33;
34
35static const float kRec709ConversionMatrix[16] = {
36 1.164f, 0.0f, 1.793f, -0.96925f,
37 1.164f, -0.213f, -0.533f, 0.30025f,
38 1.164f, 2.112f, 0.0f, -1.12875f,
39 0.0f, 0.0f, 0.0f, 1.0f}
40;
41
42static const float kJPEGInverseConversionMatrix[16] = {
43 0.299001f, 0.586998f, 0.114001f, 0.0000821798f,
44 -0.168736f, -0.331263f, 0.499999f, 0.499954f,
45 0.499999f, -0.418686f, -0.0813131f, 0.499941f,
46 0.f, 0.f, 0.f, 1.f
47};
48
49static const float kRec601InverseConversionMatrix[16] = {
50 0.256951f, 0.504421f, 0.0977346f, 0.0625f,
51 -0.148212f, -0.290954f, 0.439166f, 0.5f,
52 0.439166f, -0.367886f, -0.0712802f, 0.5f,
53 0.f, 0.f, 0.f, 1.f
54};
55
56static const float kRec709InverseConversionMatrix[16] = {
57 0.182663f, 0.614473f, 0.061971f, 0.0625f,
58 -0.100672f, -0.338658f, 0.43933f, 0.5f,
59 0.439142f, -0.39891f, -0.040231f, 0.5f,
60 0.f, 0.f, 0.f, 1.
61};
62
63class YUVtoRGBEffect : public GrFragmentProcessor {
64public:
Robert Phillips296b1cc2017-03-15 10:42:12 -040065 static sk_sp<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -050066 sk_sp<GrTextureProxy> yProxy,
67 sk_sp<GrTextureProxy> uProxy,
68 sk_sp<GrTextureProxy> vProxy, const SkISize sizes[3],
jbaumanb445a572016-06-09 13:24:48 -070069 SkYUVColorSpace colorSpace, bool nv12) {
bsalomonf267c1e2016-02-01 13:16:14 -080070 SkScalar w[3], h[3];
Robert Phillips67c18d62017-01-20 12:44:06 -050071 w[0] = SkIntToScalar(sizes[0].fWidth);
72 h[0] = SkIntToScalar(sizes[0].fHeight);
73 w[1] = SkIntToScalar(sizes[1].fWidth);
74 h[1] = SkIntToScalar(sizes[1].fHeight);
75 w[2] = SkIntToScalar(sizes[2].fWidth);
76 h[2] = SkIntToScalar(sizes[2].fHeight);
77 const SkMatrix yuvMatrix[3] = {
78 SkMatrix::I(),
79 SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]),
80 SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0])
81 };
Brian Salomon514baff2016-11-17 15:17:07 -050082 GrSamplerParams::FilterMode uvFilterMode =
bsalomonf267c1e2016-02-01 13:16:14 -080083 ((sizes[1].fWidth != sizes[0].fWidth) ||
84 (sizes[1].fHeight != sizes[0].fHeight) ||
85 (sizes[2].fWidth != sizes[0].fWidth) ||
86 (sizes[2].fHeight != sizes[0].fHeight)) ?
Brian Salomon514baff2016-11-17 15:17:07 -050087 GrSamplerParams::kBilerp_FilterMode :
88 GrSamplerParams::kNone_FilterMode;
jbaumanb445a572016-06-09 13:24:48 -070089 return sk_sp<GrFragmentProcessor>(new YUVtoRGBEffect(
Robert Phillips296b1cc2017-03-15 10:42:12 -040090 resourceProvider, std::move(yProxy), std::move(uProxy), std::move(vProxy),
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -050091 yuvMatrix, uvFilterMode, colorSpace, nv12));
bsalomonf267c1e2016-02-01 13:16:14 -080092 }
93
94 const char* name() const override { return "YUV to RGB"; }
95
96 SkYUVColorSpace getColorSpace() const { return fColorSpace; }
97
jbaumanb445a572016-06-09 13:24:48 -070098 bool isNV12() const {
99 return fNV12;
100 }
101
bsalomonf267c1e2016-02-01 13:16:14 -0800102 class GLSLProcessor : public GrGLSLFragmentProcessor {
103 public:
bsalomonf267c1e2016-02-01 13:16:14 -0800104 void emitCode(EmitArgs& args) override {
cdalton85285412016-02-18 12:37:07 -0800105 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
jbaumanb445a572016-06-09 13:24:48 -0700106 const YUVtoRGBEffect& effect = args.fFp.cast<YUVtoRGBEffect>();
bsalomonf267c1e2016-02-01 13:16:14 -0800107
108 const char* colorSpaceMatrix = nullptr;
cdalton5e58cee2016-02-11 12:49:47 -0800109 fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
110 kMat44f_GrSLType, kDefault_GrSLPrecision,
111 "ColorSpaceMatrix", &colorSpaceMatrix);
bsalomonf267c1e2016-02-01 13:16:14 -0800112 fragBuilder->codeAppendf("%s = vec4(", args.fOutputColor);
bsalomon1a1aa932016-09-12 09:30:36 -0700113 fragBuilder->appendTextureLookup(args.fTexSamplers[0],
114 args.fTransformedCoords[0].c_str(),
115 args.fTransformedCoords[0].getType());
bsalomonf267c1e2016-02-01 13:16:14 -0800116 fragBuilder->codeAppend(".r,");
bsalomon1a1aa932016-09-12 09:30:36 -0700117 fragBuilder->appendTextureLookup(args.fTexSamplers[1],
118 args.fTransformedCoords[1].c_str(),
119 args.fTransformedCoords[1].getType());
jbaumanb445a572016-06-09 13:24:48 -0700120 if (effect.fNV12) {
121 fragBuilder->codeAppendf(".rg,");
122 } else {
123 fragBuilder->codeAppend(".r,");
bsalomon1a1aa932016-09-12 09:30:36 -0700124 fragBuilder->appendTextureLookup(args.fTexSamplers[2],
125 args.fTransformedCoords[2].c_str(),
126 args.fTransformedCoords[2].getType());
jbaumanb445a572016-06-09 13:24:48 -0700127 fragBuilder->codeAppendf(".g,");
128 }
129 fragBuilder->codeAppendf("1.0) * %s;", colorSpaceMatrix);
bsalomonf267c1e2016-02-01 13:16:14 -0800130 }
131
132 protected:
133 void onSetData(const GrGLSLProgramDataManager& pdman,
Brian Salomonab015ef2017-04-04 10:15:51 -0400134 const GrFragmentProcessor& processor) override {
bsalomonf267c1e2016-02-01 13:16:14 -0800135 const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>();
136 switch (yuvEffect.getColorSpace()) {
137 case kJPEG_SkYUVColorSpace:
138 pdman.setMatrix4f(fMatrixUni, kJPEGConversionMatrix);
139 break;
140 case kRec601_SkYUVColorSpace:
141 pdman.setMatrix4f(fMatrixUni, kRec601ConversionMatrix);
142 break;
143 case kRec709_SkYUVColorSpace:
144 pdman.setMatrix4f(fMatrixUni, kRec709ConversionMatrix);
145 break;
146 }
147 }
148
149 private:
150 GrGLSLProgramDataManager::UniformHandle fMatrixUni;
151
152 typedef GrGLSLFragmentProcessor INHERITED;
153 };
154
155private:
Robert Phillips296b1cc2017-03-15 10:42:12 -0400156 YUVtoRGBEffect(GrResourceProvider* resourceProvider,
157 sk_sp<GrTextureProxy> yProxy, sk_sp<GrTextureProxy> uProxy,
Brian Salomon587e08f2017-01-27 10:59:27 -0500158 sk_sp<GrTextureProxy> vProxy, const SkMatrix yuvMatrix[3],
159 GrSamplerParams::FilterMode uvFilterMode, SkYUVColorSpace colorSpace, bool nv12)
160 : INHERITED(kPreservesOpaqueInput_OptimizationFlag)
Brian Osman5869ea92017-04-03 16:36:58 -0400161 , fYTransform(resourceProvider, yuvMatrix[0], yProxy.get())
Robert Phillips296b1cc2017-03-15 10:42:12 -0400162 , fYSampler(resourceProvider, std::move(yProxy))
Brian Osman5869ea92017-04-03 16:36:58 -0400163 , fUTransform(resourceProvider, yuvMatrix[1], uProxy.get())
Robert Phillips296b1cc2017-03-15 10:42:12 -0400164 , fUSampler(resourceProvider, std::move(uProxy), uvFilterMode)
165 , fVSampler(resourceProvider, vProxy, uvFilterMode)
Brian Salomon587e08f2017-01-27 10:59:27 -0500166 , fColorSpace(colorSpace)
167 , fNV12(nv12) {
bsalomonf267c1e2016-02-01 13:16:14 -0800168 this->initClassID<YUVtoRGBEffect>();
169 this->addCoordTransform(&fYTransform);
Brian Salomon0bbecb22016-11-17 11:38:22 -0500170 this->addTextureSampler(&fYSampler);
bsalomonf267c1e2016-02-01 13:16:14 -0800171 this->addCoordTransform(&fUTransform);
Brian Salomon0bbecb22016-11-17 11:38:22 -0500172 this->addTextureSampler(&fUSampler);
jbaumanb445a572016-06-09 13:24:48 -0700173 if (!fNV12) {
Brian Osman5869ea92017-04-03 16:36:58 -0400174 fVTransform = GrCoordTransform(resourceProvider, yuvMatrix[2], vProxy.get());
jbaumanb445a572016-06-09 13:24:48 -0700175 this->addCoordTransform(&fVTransform);
Brian Salomon0bbecb22016-11-17 11:38:22 -0500176 this->addTextureSampler(&fVSampler);
jbaumanb445a572016-06-09 13:24:48 -0700177 }
bsalomonf267c1e2016-02-01 13:16:14 -0800178 }
179
180 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
robertphillips9cdb9922016-02-03 12:25:40 -0800181 return new GLSLProcessor;
bsalomonf267c1e2016-02-01 13:16:14 -0800182 }
183
Brian Salomon94efbf52016-11-29 13:43:05 -0500184 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
jbaumanb445a572016-06-09 13:24:48 -0700185 b->add32(fNV12);
bsalomonf267c1e2016-02-01 13:16:14 -0800186 }
187
188 bool onIsEqual(const GrFragmentProcessor& sBase) const override {
189 const YUVtoRGBEffect& s = sBase.cast<YUVtoRGBEffect>();
jbaumanb445a572016-06-09 13:24:48 -0700190 return (fColorSpace == s.getColorSpace()) && (fNV12 == s.isNV12());
bsalomonf267c1e2016-02-01 13:16:14 -0800191 }
192
bsalomonf267c1e2016-02-01 13:16:14 -0800193 GrCoordTransform fYTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500194 TextureSampler fYSampler;
bsalomonf267c1e2016-02-01 13:16:14 -0800195 GrCoordTransform fUTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500196 TextureSampler fUSampler;
bsalomonf267c1e2016-02-01 13:16:14 -0800197 GrCoordTransform fVTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500198 TextureSampler fVSampler;
bsalomonf267c1e2016-02-01 13:16:14 -0800199 SkYUVColorSpace fColorSpace;
jbaumanb445a572016-06-09 13:24:48 -0700200 bool fNV12;
bsalomonf267c1e2016-02-01 13:16:14 -0800201
202 typedef GrFragmentProcessor INHERITED;
203};
204
205
206class RGBToYUVEffect : public GrFragmentProcessor {
207public:
208 enum OutputChannels {
209 // output color r = y, g = u, b = v, a = a
210 kYUV_OutputChannels,
211 // output color rgba = y
212 kY_OutputChannels,
213 // output color r = u, g = v, b = 0, a = a
214 kUV_OutputChannels,
215 // output color rgba = u
216 kU_OutputChannels,
217 // output color rgba = v
218 kV_OutputChannels
219 };
220
bungeman06ca8ec2016-06-09 08:01:03 -0700221 RGBToYUVEffect(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace,
bsalomonf267c1e2016-02-01 13:16:14 -0800222 OutputChannels output)
Brian Salomon587e08f2017-01-27 10:59:27 -0500223 // This could advertise kConstantOutputForConstantInput, but doesn't seem useful.
224 : INHERITED(kPreservesOpaqueInput_OptimizationFlag)
225 , fColorSpace(colorSpace)
226 , fOutputChannels(output) {
bsalomonf267c1e2016-02-01 13:16:14 -0800227 this->initClassID<RGBToYUVEffect>();
bungeman06ca8ec2016-06-09 08:01:03 -0700228 this->registerChildProcessor(std::move(rgbFP));
bsalomonf267c1e2016-02-01 13:16:14 -0800229 }
230
231 const char* name() const override { return "RGBToYUV"; }
232
233 SkYUVColorSpace getColorSpace() const { return fColorSpace; }
234
235 OutputChannels outputChannels() const { return fOutputChannels; }
236
237 class GLSLProcessor : public GrGLSLFragmentProcessor {
238 public:
robertphillips9cdb9922016-02-03 12:25:40 -0800239 GLSLProcessor() : fLastColorSpace(-1), fLastOutputChannels(-1) {}
bsalomonf267c1e2016-02-01 13:16:14 -0800240
241 void emitCode(EmitArgs& args) override {
cdalton85285412016-02-18 12:37:07 -0800242 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
bsalomonf267c1e2016-02-01 13:16:14 -0800243 OutputChannels oc = args.fFp.cast<RGBToYUVEffect>().outputChannels();
244
245 SkString outputColor("rgbColor");
246 this->emitChild(0, args.fInputColor, &outputColor, args);
247
248 const char* uniName;
249 switch (oc) {
250 case kYUV_OutputChannels:
251 fRGBToYUVUni = args.fUniformHandler->addUniformArray(
cdalton5e58cee2016-02-11 12:49:47 -0800252 kFragment_GrShaderFlag,
bsalomonf267c1e2016-02-01 13:16:14 -0800253 kVec4f_GrSLType, kDefault_GrSLPrecision,
254 "RGBToYUV", 3, &uniName);
255 fragBuilder->codeAppendf("%s = vec4(dot(rgbColor.rgb, %s[0].rgb) + %s[0].a,"
256 "dot(rgbColor.rgb, %s[1].rgb) + %s[1].a,"
257 "dot(rgbColor.rgb, %s[2].rgb) + %s[2].a,"
258 "rgbColor.a);",
259 args.fOutputColor, uniName, uniName, uniName, uniName,
260 uniName, uniName);
261 break;
262 case kUV_OutputChannels:
263 fRGBToYUVUni = args.fUniformHandler->addUniformArray(
cdalton5e58cee2016-02-11 12:49:47 -0800264 kFragment_GrShaderFlag,
bsalomonf267c1e2016-02-01 13:16:14 -0800265 kVec4f_GrSLType, kDefault_GrSLPrecision,
266 "RGBToUV", 2, &uniName);
267 fragBuilder->codeAppendf("%s = vec4(dot(rgbColor.rgb, %s[0].rgb) + %s[0].a,"
268 "dot(rgbColor.rgb, %s[1].rgb) + %s[1].a,"
269 "0.0,"
270 "rgbColor.a);",
271 args.fOutputColor, uniName, uniName, uniName, uniName);
272 break;
273 case kY_OutputChannels:
274 case kU_OutputChannels:
275 case kV_OutputChannels:
276 fRGBToYUVUni = args.fUniformHandler->addUniform(
cdalton5e58cee2016-02-11 12:49:47 -0800277 kFragment_GrShaderFlag,
bsalomonf267c1e2016-02-01 13:16:14 -0800278 kVec4f_GrSLType, kDefault_GrSLPrecision,
279 "RGBToYUorV", &uniName);
280 fragBuilder->codeAppendf("%s = vec4(dot(rgbColor.rgb, %s.rgb) + %s.a);\n",
281 args.fOutputColor, uniName, uniName);
282 break;
283 }
284 }
285
286 private:
287 void onSetData(const GrGLSLProgramDataManager& pdman,
Brian Salomonab015ef2017-04-04 10:15:51 -0400288 const GrFragmentProcessor& processor) override {
bsalomonf267c1e2016-02-01 13:16:14 -0800289 const RGBToYUVEffect& effect = processor.cast<RGBToYUVEffect>();
290 OutputChannels oc = effect.outputChannels();
291 if (effect.getColorSpace() != fLastColorSpace || oc != fLastOutputChannels) {
292
293 const float* matrix = nullptr;
294 switch (effect.getColorSpace()) {
295 case kJPEG_SkYUVColorSpace:
296 matrix = kJPEGInverseConversionMatrix;
297 break;
298 case kRec601_SkYUVColorSpace:
299 matrix = kRec601InverseConversionMatrix;
300 break;
301 case kRec709_SkYUVColorSpace:
302 matrix = kRec709InverseConversionMatrix;
303 break;
304 }
305 switch (oc) {
306 case kYUV_OutputChannels:
307 pdman.set4fv(fRGBToYUVUni, 3, matrix);
308 break;
309 case kUV_OutputChannels:
310 pdman.set4fv(fRGBToYUVUni, 2, matrix + 4);
311 break;
312 case kY_OutputChannels:
313 pdman.set4fv(fRGBToYUVUni, 1, matrix);
314 break;
315 case kU_OutputChannels:
316 pdman.set4fv(fRGBToYUVUni, 1, matrix + 4);
317 break;
318 case kV_OutputChannels:
319 pdman.set4fv(fRGBToYUVUni, 1, matrix + 8);
320 break;
321 }
322 fLastColorSpace = effect.getColorSpace();
323 }
324 }
325 GrGLSLProgramDataManager::UniformHandle fRGBToYUVUni;
326 int fLastColorSpace;
327 int fLastOutputChannels;
328
329 typedef GrGLSLFragmentProcessor INHERITED;
330 };
331
332private:
333 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
robertphillips9cdb9922016-02-03 12:25:40 -0800334 return new GLSLProcessor;
bsalomonf267c1e2016-02-01 13:16:14 -0800335 }
336
Brian Salomon94efbf52016-11-29 13:43:05 -0500337 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
bsalomonf267c1e2016-02-01 13:16:14 -0800338 // kY, kU, and kV all generate the same code, just upload different coefficients.
339 if (kU_OutputChannels == fOutputChannels || kV_OutputChannels == fOutputChannels) {
340 b->add32(kY_OutputChannels);
341 } else {
342 b->add32(fOutputChannels);
343 }
344 }
345
346 bool onIsEqual(const GrFragmentProcessor& sBase) const override {
347 const RGBToYUVEffect& s = sBase.cast<RGBToYUVEffect>();
348 return fColorSpace == s.getColorSpace() && fOutputChannels == s.outputChannels();
349 }
350
bsalomonf267c1e2016-02-01 13:16:14 -0800351 GrCoordTransform fTransform;
Brian Salomon0bbecb22016-11-17 11:38:22 -0500352 TextureSampler fTextureSampler;
bsalomonf267c1e2016-02-01 13:16:14 -0800353 SkYUVColorSpace fColorSpace;
354 OutputChannels fOutputChannels;
355
356 typedef GrFragmentProcessor INHERITED;
357};
358
359}
360
361//////////////////////////////////////////////////////////////////////////////
362
Robert Phillips296b1cc2017-03-15 10:42:12 -0400363sk_sp<GrFragmentProcessor> GrYUVEffect::MakeYUVToRGB(GrResourceProvider* resourceProvider,
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500364 sk_sp<GrTextureProxy> yProxy,
365 sk_sp<GrTextureProxy> uProxy,
366 sk_sp<GrTextureProxy> vProxy,
367 const SkISize sizes[3],
jbaumanb445a572016-06-09 13:24:48 -0700368 SkYUVColorSpace colorSpace, bool nv12) {
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500369 SkASSERT(yProxy && uProxy && vProxy && sizes);
Robert Phillips296b1cc2017-03-15 10:42:12 -0400370 return YUVtoRGBEffect::Make(resourceProvider,
Robert Phillipsbc7a4fb2017-01-23 15:30:35 -0500371 std::move(yProxy), std::move(uProxy), std::move(vProxy),
372 sizes, colorSpace, nv12);
bsalomonf267c1e2016-02-01 13:16:14 -0800373}
374
bungeman06ca8ec2016-06-09 08:01:03 -0700375sk_sp<GrFragmentProcessor>
376GrYUVEffect::MakeRGBToYUV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace) {
bsalomonf267c1e2016-02-01 13:16:14 -0800377 SkASSERT(rgbFP);
bungeman06ca8ec2016-06-09 08:01:03 -0700378 return sk_sp<GrFragmentProcessor>(
379 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kYUV_OutputChannels));
bsalomonf267c1e2016-02-01 13:16:14 -0800380}
381
bungeman06ca8ec2016-06-09 08:01:03 -0700382sk_sp<GrFragmentProcessor>
383GrYUVEffect::MakeRGBToY(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace) {
bsalomonf267c1e2016-02-01 13:16:14 -0800384 SkASSERT(rgbFP);
bungeman06ca8ec2016-06-09 08:01:03 -0700385 return sk_sp<GrFragmentProcessor>(
386 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kY_OutputChannels));
bsalomonf267c1e2016-02-01 13:16:14 -0800387}
388
bungeman06ca8ec2016-06-09 08:01:03 -0700389sk_sp<GrFragmentProcessor>
390GrYUVEffect::MakeRGBToUV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace) {
bsalomonf267c1e2016-02-01 13:16:14 -0800391 SkASSERT(rgbFP);
bungeman06ca8ec2016-06-09 08:01:03 -0700392 return sk_sp<GrFragmentProcessor>(
393 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kUV_OutputChannels));
bsalomonf267c1e2016-02-01 13:16:14 -0800394}
395
bungeman06ca8ec2016-06-09 08:01:03 -0700396sk_sp<GrFragmentProcessor>
397GrYUVEffect::MakeRGBToU(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace) {
bsalomonf267c1e2016-02-01 13:16:14 -0800398 SkASSERT(rgbFP);
bungeman06ca8ec2016-06-09 08:01:03 -0700399 return sk_sp<GrFragmentProcessor>(
400 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kU_OutputChannels));
bsalomonf267c1e2016-02-01 13:16:14 -0800401}
402
bungeman06ca8ec2016-06-09 08:01:03 -0700403sk_sp<GrFragmentProcessor>
404GrYUVEffect::MakeRGBToV(sk_sp<GrFragmentProcessor> rgbFP, SkYUVColorSpace colorSpace) {
bsalomonf267c1e2016-02-01 13:16:14 -0800405 SkASSERT(rgbFP);
bungeman06ca8ec2016-06-09 08:01:03 -0700406 return sk_sp<GrFragmentProcessor>(
407 new RGBToYUVEffect(std::move(rgbFP), colorSpace, RGBToYUVEffect::kV_OutputChannels));
bsalomonf267c1e2016-02-01 13:16:14 -0800408}