| /* |
| * Copyright 2018 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| in uniform sampler2D ySampler; |
| in half4x4 ySamplerTransform; |
| @coordTransform(ySampler) { |
| ySamplerTransform |
| } |
| |
| in uniform sampler2D uSampler; |
| in half4x4 uSamplerTransform; |
| @coordTransform(uSampler) { |
| uSamplerTransform |
| } |
| @samplerParams(uSampler) { |
| uvSamplerParams |
| } |
| |
| in uniform sampler2D vSampler; |
| in half4x4 vSamplerTransform; |
| @coordTransform(vSampler) { |
| vSamplerTransform |
| } |
| @samplerParams(vSampler) { |
| uvSamplerParams |
| } |
| |
| in uniform half4x4 colorSpaceMatrix; |
| layout(key) in bool nv12; |
| |
| @constructorParams { |
| GrSamplerState uvSamplerParams |
| } |
| |
| @class { |
| static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> yProxy, |
| sk_sp<GrTextureProxy> uProxy, |
| sk_sp<GrTextureProxy> vProxy, |
| const SkISize sizes[3], |
| SkYUVColorSpace colorSpace, bool nv12); |
| } |
| |
| @cpp { |
| static const float kJPEGConversionMatrix[16] = { |
| 1.0f, 0.0f, 1.402f, -0.703749f, |
| 1.0f, -0.344136f, -0.714136f, 0.531211f, |
| 1.0f, 1.772f, 0.0f, -0.889475f, |
| 0.0f, 0.0f, 0.0f, 1.0 |
| }; |
| |
| static const float kRec601ConversionMatrix[16] = { |
| 1.164f, 0.0f, 1.596f, -0.87075f, |
| 1.164f, -0.391f, -0.813f, 0.52925f, |
| 1.164f, 2.018f, 0.0f, -1.08175f, |
| 0.0f, 0.0f, 0.0f, 1.0} |
| ; |
| |
| static const float kRec709ConversionMatrix[16] = { |
| 1.164f, 0.0f, 1.793f, -0.96925f, |
| 1.164f, -0.213f, -0.533f, 0.30025f, |
| 1.164f, 2.112f, 0.0f, -1.12875f, |
| 0.0f, 0.0f, 0.0f, 1.0f} |
| ; |
| |
| std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(sk_sp<GrTextureProxy> yProxy, |
| sk_sp<GrTextureProxy> uProxy, |
| sk_sp<GrTextureProxy> vProxy, |
| const SkISize sizes[3], |
| SkYUVColorSpace colorSpace, |
| bool nv12) { |
| SkScalar w[3], h[3]; |
| w[0] = SkIntToScalar(sizes[0].fWidth); |
| h[0] = SkIntToScalar(sizes[0].fHeight); |
| w[1] = SkIntToScalar(sizes[1].fWidth); |
| h[1] = SkIntToScalar(sizes[1].fHeight); |
| w[2] = SkIntToScalar(sizes[2].fWidth); |
| h[2] = SkIntToScalar(sizes[2].fHeight); |
| SkMatrix yTransform = SkMatrix::I(); |
| SkMatrix uTransform = SkMatrix::MakeScale(w[1] / w[0], h[1] / h[0]); |
| SkMatrix vTransform = SkMatrix::MakeScale(w[2] / w[0], h[2] / h[0]); |
| GrSamplerState::Filter uvFilterMode = |
| ((sizes[1].fWidth != sizes[0].fWidth) || |
| (sizes[1].fHeight != sizes[0].fHeight) || |
| (sizes[2].fWidth != sizes[0].fWidth) || |
| (sizes[2].fHeight != sizes[0].fHeight)) ? |
| GrSamplerState::Filter::kBilerp : |
| GrSamplerState::Filter::kNearest; |
| SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); |
| switch (colorSpace) { |
| case kJPEG_SkYUVColorSpace: |
| mat.setColMajorf(kJPEGConversionMatrix); |
| break; |
| case kRec601_SkYUVColorSpace: |
| mat.setColMajorf(kRec601ConversionMatrix); |
| break; |
| case kRec709_SkYUVColorSpace: |
| mat.setColMajorf(kRec709ConversionMatrix); |
| break; |
| } |
| return std::unique_ptr<GrFragmentProcessor>( |
| new GrYUVtoRGBEffect(std::move(yProxy), yTransform, std::move(uProxy), uTransform, |
| std::move(vProxy), vTransform, mat, nv12, |
| GrSamplerState(GrSamplerState::WrapMode::kClamp, |
| uvFilterMode))); |
| } |
| } |
| |
| void main() { |
| @if (nv12) { |
| sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r, |
| texture(uSampler, sk_TransformedCoords2D[1]).rg, |
| 1.0) * colorSpaceMatrix; |
| } else { |
| sk_OutColor = half4(texture(ySampler, sk_TransformedCoords2D[0]).r, |
| texture(uSampler, sk_TransformedCoords2D[1]).r, |
| texture(vSampler, sk_TransformedCoords2D[2]).r, |
| 1.0) * colorSpaceMatrix; |
| } |
| } |