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