1/*
2 * Copyright 2018 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
8in uniform sampler2D ySampler;
9in half4x4 ySamplerTransform;
10@coordTransform(ySampler) {
11    ySamplerTransform
12}
13
14in uniform sampler2D uSampler;
15in half4x4 uSamplerTransform;
16@coordTransform(uSampler) {
17    uSamplerTransform
18}
19@samplerParams(uSampler) {
20    uvSamplerParams
21}
22
23in uniform sampler2D vSampler;
24in half4x4 vSamplerTransform;
25@coordTransform(vSampler) {
26    vSamplerTransform
27}
28@samplerParams(vSampler) {
29    uvSamplerParams
30}
31
32in uniform half4x4 colorSpaceMatrix;
33layout(key) in bool nv12;
34
35@constructorParams {
36    GrSamplerState uvSamplerParams
37}
38
39@class {
40    static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy,
41                                                     sk_sp<GrTextureProxy> uProxy,
42                                                     sk_sp<GrTextureProxy> vProxy,
43                                                     const SkISize sizes[3],
44                                                     SkYUVColorSpace colorSpace, bool nv12);
45}
46
47@cpp {
48    static const float kJPEGConversionMatrix[16] = {
49        1.0f,  0.0f,       1.402f,   -0.703749f,
50        1.0f, -0.344136f, -0.714136f, 0.531211f,
51        1.0f,  1.772f,     0.0f,     -0.889475f,
52        0.0f,  0.0f,       0.0f,      1.0
53    };
54
55    static const float kRec601ConversionMatrix[16] = {
56        1.164f,  0.0f,    1.596f, -0.87075f,
57        1.164f, -0.391f, -0.813f,  0.52925f,
58        1.164f,  2.018f,  0.0f,   -1.08175f,
59        0.0f,    0.0f,    0.0f,    1.0}
60    ;
61
62    static const float kRec709ConversionMatrix[16] = {
63        1.164f,  0.0f,    1.793f, -0.96925f,
64        1.164f, -0.213f, -0.533f,  0.30025f,
65        1.164f,  2.112f,  0.0f,   -1.12875f,
66        0.0f,    0.0f,    0.0f,    1.0f}
67    ;
68
69    std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(sk_sp<GrTextureProxy> yProxy,
70                                                                sk_sp<GrTextureProxy> uProxy,
71                                                                sk_sp<GrTextureProxy> vProxy,
72                                                                const SkISize sizes[3],
73                                                                SkYUVColorSpace colorSpace,
74                                                                bool nv12) {
75        SkScalar w[3], h[3];
76        w[0] = SkIntToScalar(sizes[0].fWidth);
77        h[0] = SkIntToScalar(sizes[0].fHeight);
78        w[1] = SkIntToScalar(sizes[1].fWidth);
79        h[1] = SkIntToScalar(sizes[1].fHeight);
80        w[2] = SkIntToScalar(sizes[2].fWidth);
81        h[2] = SkIntToScalar(sizes[2].fHeight);
82        SkMatrix yTransform = SkMatrix::I();
83        SkMatrix uTransform = SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]);
84        SkMatrix vTransform = SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]);
85        GrSamplerState::Filter uvFilterMode =
86            ((sizes[1].fWidth  != sizes[0].fWidth) ||
87             (sizes[1].fHeight != sizes[0].fHeight) ||
88             (sizes[2].fWidth  != sizes[0].fWidth) ||
89             (sizes[2].fHeight != sizes[0].fHeight)) ?
90            GrSamplerState::Filter::kBilerp :
91            GrSamplerState::Filter::kNearest;
92        SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
93        switch (colorSpace) {
94            case kJPEG_SkYUVColorSpace:
95                mat.setColMajorf(kJPEGConversionMatrix);
96                break;
97            case kRec601_SkYUVColorSpace:
98                mat.setColMajorf(kRec601ConversionMatrix);
99                break;
100            case kRec709_SkYUVColorSpace:
101                mat.setColMajorf(kRec709ConversionMatrix);
102                break;
103        }
104        return std::unique_ptr<GrFragmentProcessor>(
105                new GrYUVtoRGBEffect(std::move(yProxy), yTransform, std::move(uProxy), uTransform,
106                                     std::move(vProxy), vTransform, mat, nv12,
107                                     GrSamplerState(GrSamplerState::WrapMode::kClamp,
108                                                    uvFilterMode)));
109    }
110}
111
112void main() {
113    @if (nv12) {
114        sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r,
115                            texture(uSampler, sk_TransformedCoords2D[1]).rg,
116                            1.0) * colorSpaceMatrix;
117    } else {
118        sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r,
119                            texture(uSampler, sk_TransformedCoords2D[1]).r,
120                            texture(vSampler, sk_TransformedCoords2D[2]).r,
121                            1.0) * colorSpaceMatrix;
122    }
123}
124