• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
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 "src/gpu/ganesh/GrYUVATextureProxies.h"
9 
10 #include "src/gpu/ganesh/GrTextureProxy.h"
11 
12 #ifdef SK_DEBUG
num_channels(uint32_t channelFlags)13 static int num_channels(uint32_t channelFlags) {
14     switch (channelFlags) {
15         case kRed_SkColorChannelFlag        : return 1;
16         case kAlpha_SkColorChannelFlag      : return 1;
17         case kGray_SkColorChannelFlag       : return 1;
18         case kGrayAlpha_SkColorChannelFlags : return 2;
19         case kRG_SkColorChannelFlags        : return 2;
20         case kRGB_SkColorChannelFlags       : return 3;
21         case kRGBA_SkColorChannelFlags      : return 4;
22 
23         default:
24             SkDEBUGFAILF("Unexpected channel combination 0x%08x", channelFlags);
25             return 0;
26     }
27 }
28 #endif
29 
GrYUVATextureProxies(const SkYUVAInfo & yuvaInfo,sk_sp<GrSurfaceProxy> proxies[SkYUVAInfo::kMaxPlanes],GrSurfaceOrigin textureOrigin)30 GrYUVATextureProxies::GrYUVATextureProxies(const SkYUVAInfo& yuvaInfo,
31                                            sk_sp<GrSurfaceProxy> proxies[SkYUVAInfo::kMaxPlanes],
32                                            GrSurfaceOrigin textureOrigin)
33         : fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
34     int n = yuvaInfo.numPlanes();
35     if (n == 0) {
36         *this = {};
37         SkASSERT(!this->isValid());
38         return;
39     }
40     uint32_t textureChannelMasks[SkYUVAInfo::kMaxPlanes];
41     for (int i = 0; i < n; ++i) {
42         if (!proxies[i]) {
43             *this = {};
44             SkASSERT(!this->isValid());
45             return;
46         }
47         textureChannelMasks[i] = proxies[i]->backendFormat().channelMask();
48     }
49     fYUVALocations = yuvaInfo.toYUVALocations(textureChannelMasks);
50     if (fYUVALocations[0].fPlane < 0) {
51         *this = {};
52         SkASSERT(!this->isValid());
53         return;
54     }
55     fMipmapped = skgpu::Mipmapped::kYes;
56     for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
57         if (!proxies[i]) {
58             *this = {};
59             SkASSERT(!this->isValid());
60             return;
61         }
62         SkASSERT(proxies[i]->asTextureProxy());
63         if (proxies[i]->asTextureProxy()->mipmapped() == skgpu::Mipmapped::kNo) {
64             fMipmapped = skgpu::Mipmapped::kNo;
65         }
66         fProxies[i] = std::move(proxies[i]);
67     }
68     SkASSERT(this->isValid());
69 }
70 
GrYUVATextureProxies(const SkYUVAInfo & yuvaInfo,GrSurfaceProxyView views[SkYUVAInfo::kMaxPlanes],GrColorType colorTypes[SkYUVAInfo::kMaxPlanes])71 GrYUVATextureProxies::GrYUVATextureProxies(const SkYUVAInfo& yuvaInfo,
72                                            GrSurfaceProxyView views[SkYUVAInfo::kMaxPlanes],
73                                            GrColorType colorTypes[SkYUVAInfo::kMaxPlanes])
74         : fYUVAInfo(yuvaInfo) {
75     uint32_t pixmapChannelMasks[SkYUVAInfo::kMaxPlanes];
76     int n = yuvaInfo.numPlanes();
77     if (n == 0) {
78         *this = {};
79         SkASSERT(!this->isValid());
80         return;
81     }
82     fMipmapped = skgpu::Mipmapped::kYes;
83     for (int i = 0; i < n; ++i) {
84         pixmapChannelMasks[i] = GrColorTypeChannelFlags(colorTypes[i]);
85         SkASSERT(num_channels(pixmapChannelMasks[i]) <=
86                  num_channels(views[i].proxy()->backendFormat().channelMask()));
87         if (!views[i] || views[i].origin() != views[0].origin()) {
88             *this = {};
89             SkASSERT(!this->isValid());
90             return;
91         }
92         if (views[i].proxy()->asTextureProxy()->mipmapped() == skgpu::Mipmapped::kNo) {
93             fMipmapped = skgpu::Mipmapped::kNo;
94         }
95     }
96     // Initial locations refer to the CPU pixmap channels.
97     fYUVALocations = yuvaInfo.toYUVALocations(pixmapChannelMasks);
98     if (fYUVALocations[0].fPlane < 0) {
99         *this = {};
100         SkASSERT(!this->isValid());
101         return;
102     }
103 
104     // Run each location through the proxy view's swizzle to get the actual texture format channel.
105     for (int i = 0; i < SkYUVAInfo::kYUVAChannelCount; ++i) {
106         int plane = fYUVALocations[i].fPlane;
107         if (plane >= 0) {
108             int chanAsIdx = static_cast<int>(fYUVALocations[i].fChannel);
109             switch (views[plane].swizzle()[chanAsIdx]) {
110                 case 'r': fYUVALocations[i].fChannel = SkColorChannel::kR; break;
111                 case 'g': fYUVALocations[i].fChannel = SkColorChannel::kG; break;
112                 case 'b': fYUVALocations[i].fChannel = SkColorChannel::kB; break;
113                 case 'a': fYUVALocations[i].fChannel = SkColorChannel::kA; break;
114 
115                 default:
116                     SkDEBUGFAILF("Unexpected swizzle value: %c", views[i].swizzle()[chanAsIdx]);
117                     *this = {};
118                     SkASSERT(!this->isValid());
119                     return;
120             }
121         }
122     }
123     for (int i = 0; i < n; ++i) {
124         fProxies[i] = views[i].detachProxy();
125     }
126     fTextureOrigin = views[0].origin();
127     SkASSERT(this->isValid());
128 }
129