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