xref: /aosp_15_r20/external/skia/src/gpu/graphite/YUVABackendTextures.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/YUVABackendTextures.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Recorder.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkYUVAInfoLocation.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Caps.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RecorderPriv.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
16*c8dee2aaSAndroid Build Coastguard Worker 
17*c8dee2aaSAndroid Build Coastguard Worker namespace {
num_channels(uint32_t ChannelMasks)18*c8dee2aaSAndroid Build Coastguard Worker int num_channels(uint32_t ChannelMasks) {
19*c8dee2aaSAndroid Build Coastguard Worker     switch (ChannelMasks) {
20*c8dee2aaSAndroid Build Coastguard Worker         case kRed_SkColorChannelFlag        : return 1;
21*c8dee2aaSAndroid Build Coastguard Worker         case kAlpha_SkColorChannelFlag      : return 1;
22*c8dee2aaSAndroid Build Coastguard Worker         case kGray_SkColorChannelFlag       : return 1;
23*c8dee2aaSAndroid Build Coastguard Worker         case kGrayAlpha_SkColorChannelFlags : return 2;
24*c8dee2aaSAndroid Build Coastguard Worker         case kRG_SkColorChannelFlags        : return 2;
25*c8dee2aaSAndroid Build Coastguard Worker         case kRGB_SkColorChannelFlags       : return 3;
26*c8dee2aaSAndroid Build Coastguard Worker         case kRGBA_SkColorChannelFlags      : return 4;
27*c8dee2aaSAndroid Build Coastguard Worker         default                             : return 0;
28*c8dee2aaSAndroid Build Coastguard Worker     }
29*c8dee2aaSAndroid Build Coastguard Worker     SkUNREACHABLE;
30*c8dee2aaSAndroid Build Coastguard Worker }
31*c8dee2aaSAndroid Build Coastguard Worker }
32*c8dee2aaSAndroid Build Coastguard Worker 
YUVABackendTextureInfo(const Recorder * recorder,const SkYUVAInfo & yuvaInfo,SkSpan<const TextureInfo> textureInfo,Mipmapped mipmapped)33*c8dee2aaSAndroid Build Coastguard Worker YUVABackendTextureInfo::YUVABackendTextureInfo(const Recorder* recorder,
34*c8dee2aaSAndroid Build Coastguard Worker                                                const SkYUVAInfo& yuvaInfo,
35*c8dee2aaSAndroid Build Coastguard Worker                                                SkSpan<const TextureInfo> textureInfo,
36*c8dee2aaSAndroid Build Coastguard Worker                                                Mipmapped mipmapped)
37*c8dee2aaSAndroid Build Coastguard Worker         : fYUVAInfo(yuvaInfo)
38*c8dee2aaSAndroid Build Coastguard Worker         , fMipmapped(mipmapped) {
39*c8dee2aaSAndroid Build Coastguard Worker     int numPlanes = yuvaInfo.numPlanes();
40*c8dee2aaSAndroid Build Coastguard Worker     if (!yuvaInfo.isValid() ||
41*c8dee2aaSAndroid Build Coastguard Worker         numPlanes == 0 ||
42*c8dee2aaSAndroid Build Coastguard Worker         (size_t)numPlanes > textureInfo.size()) {
43*c8dee2aaSAndroid Build Coastguard Worker         *this = {};
44*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->isValid());
45*c8dee2aaSAndroid Build Coastguard Worker         return;
46*c8dee2aaSAndroid Build Coastguard Worker     }
47*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < numPlanes; ++i) {
48*c8dee2aaSAndroid Build Coastguard Worker         int numRequiredChannels = yuvaInfo.numChannelsInPlane(i);
49*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(numRequiredChannels > 0);
50*c8dee2aaSAndroid Build Coastguard Worker         fPlaneChannelMasks[i] = recorder->priv().caps()->channelMask(textureInfo[i]);
51*c8dee2aaSAndroid Build Coastguard Worker         if (!textureInfo[i].isValid() ||
52*c8dee2aaSAndroid Build Coastguard Worker             textureInfo[i].backend() != textureInfo[0].backend() ||
53*c8dee2aaSAndroid Build Coastguard Worker             num_channels(fPlaneChannelMasks[i]) < numRequiredChannels) {
54*c8dee2aaSAndroid Build Coastguard Worker             *this = {};
55*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(!this->isValid());
56*c8dee2aaSAndroid Build Coastguard Worker             return;
57*c8dee2aaSAndroid Build Coastguard Worker         }
58*c8dee2aaSAndroid Build Coastguard Worker         fPlaneTextureInfos[i] = textureInfo[i];
59*c8dee2aaSAndroid Build Coastguard Worker     }
60*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(this->isValid());
61*c8dee2aaSAndroid Build Coastguard Worker }
62*c8dee2aaSAndroid Build Coastguard Worker 
operator ==(const YUVABackendTextureInfo & that) const63*c8dee2aaSAndroid Build Coastguard Worker bool YUVABackendTextureInfo::operator==(const YUVABackendTextureInfo& that) const {
64*c8dee2aaSAndroid Build Coastguard Worker     if (fYUVAInfo != that.fYUVAInfo || fMipmapped != that.fMipmapped) {
65*c8dee2aaSAndroid Build Coastguard Worker         return false;
66*c8dee2aaSAndroid Build Coastguard Worker     }
67*c8dee2aaSAndroid Build Coastguard Worker     return fPlaneTextureInfos == that.fPlaneTextureInfos;
68*c8dee2aaSAndroid Build Coastguard Worker }
69*c8dee2aaSAndroid Build Coastguard Worker 
toYUVALocations() const70*c8dee2aaSAndroid Build Coastguard Worker SkYUVAInfo::YUVALocations YUVABackendTextureInfo::toYUVALocations() const {
71*c8dee2aaSAndroid Build Coastguard Worker     auto result = fYUVAInfo.toYUVALocations(fPlaneChannelMasks.data());
72*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(int numPlanes;)
73*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
74*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(numPlanes == this->numPlanes());
75*c8dee2aaSAndroid Build Coastguard Worker     return result;
76*c8dee2aaSAndroid Build Coastguard Worker }
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
79*c8dee2aaSAndroid Build Coastguard Worker 
YUVABackendTextures(const Recorder * recorder,const SkYUVAInfo & yuvaInfo,SkSpan<const BackendTexture> textures)80*c8dee2aaSAndroid Build Coastguard Worker YUVABackendTextures::YUVABackendTextures(const Recorder* recorder,
81*c8dee2aaSAndroid Build Coastguard Worker                                          const SkYUVAInfo& yuvaInfo,
82*c8dee2aaSAndroid Build Coastguard Worker                                          SkSpan<const BackendTexture> textures)
83*c8dee2aaSAndroid Build Coastguard Worker         : fYUVAInfo(yuvaInfo) {
84*c8dee2aaSAndroid Build Coastguard Worker     if (!yuvaInfo.isValid()) {
85*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->isValid());
86*c8dee2aaSAndroid Build Coastguard Worker         return;
87*c8dee2aaSAndroid Build Coastguard Worker     }
88*c8dee2aaSAndroid Build Coastguard Worker     SkISize planeDimensions[kMaxPlanes];
89*c8dee2aaSAndroid Build Coastguard Worker     int numPlanes = yuvaInfo.planeDimensions(planeDimensions);
90*c8dee2aaSAndroid Build Coastguard Worker     if (numPlanes == 0 || (size_t)numPlanes > textures.size()) {
91*c8dee2aaSAndroid Build Coastguard Worker         fYUVAInfo = {};
92*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->isValid());
93*c8dee2aaSAndroid Build Coastguard Worker         return;
94*c8dee2aaSAndroid Build Coastguard Worker     }
95*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < numPlanes; ++i) {
96*c8dee2aaSAndroid Build Coastguard Worker         int numRequiredChannels = yuvaInfo.numChannelsInPlane(i);
97*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(numRequiredChannels > 0);
98*c8dee2aaSAndroid Build Coastguard Worker         fPlaneChannelMasks[i] = recorder->priv().caps()->channelMask(textures[i].info());
99*c8dee2aaSAndroid Build Coastguard Worker         if (!textures[i].isValid() ||
100*c8dee2aaSAndroid Build Coastguard Worker             textures[i].dimensions() != planeDimensions[i] ||
101*c8dee2aaSAndroid Build Coastguard Worker             textures[i].backend() != textures[0].backend() ||
102*c8dee2aaSAndroid Build Coastguard Worker             num_channels(fPlaneChannelMasks[i]) < numRequiredChannels) {
103*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(!this->isValid());
104*c8dee2aaSAndroid Build Coastguard Worker             return;
105*c8dee2aaSAndroid Build Coastguard Worker         }
106*c8dee2aaSAndroid Build Coastguard Worker         fPlaneTextures[i] = textures[i];
107*c8dee2aaSAndroid Build Coastguard Worker     }
108*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(this->isValid());
109*c8dee2aaSAndroid Build Coastguard Worker }
110*c8dee2aaSAndroid Build Coastguard Worker 
toYUVALocations() const111*c8dee2aaSAndroid Build Coastguard Worker SkYUVAInfo::YUVALocations YUVABackendTextures::toYUVALocations() const {
112*c8dee2aaSAndroid Build Coastguard Worker     auto result = fYUVAInfo.toYUVALocations(fPlaneChannelMasks.data());
113*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(int numPlanes;)
114*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
115*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(numPlanes == this->numPlanes());
116*c8dee2aaSAndroid Build Coastguard Worker     return result;
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker 
119*c8dee2aaSAndroid Build Coastguard Worker }  // End of namespace skgpu::graphite
120