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