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