xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrYUVABackendTextures.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 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/ganesh/GrYUVABackendTextures.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkYUVAInfoLocation.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
16*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
17*c8dee2aaSAndroid Build Coastguard Worker 
num_channels(const GrBackendFormat & format)18*c8dee2aaSAndroid Build Coastguard Worker static int num_channels(const GrBackendFormat& format) {
19*c8dee2aaSAndroid Build Coastguard Worker     switch (format.channelMask()) {
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 }
30*c8dee2aaSAndroid Build Coastguard Worker 
GrYUVABackendTextureInfo(const SkYUVAInfo & yuvaInfo,const GrBackendFormat formats[kMaxPlanes],skgpu::Mipmapped mipmapped,GrSurfaceOrigin origin)31*c8dee2aaSAndroid Build Coastguard Worker GrYUVABackendTextureInfo::GrYUVABackendTextureInfo(const SkYUVAInfo& yuvaInfo,
32*c8dee2aaSAndroid Build Coastguard Worker                                                    const GrBackendFormat formats[kMaxPlanes],
33*c8dee2aaSAndroid Build Coastguard Worker                                                    skgpu::Mipmapped mipmapped,
34*c8dee2aaSAndroid Build Coastguard Worker                                                    GrSurfaceOrigin origin)
35*c8dee2aaSAndroid Build Coastguard Worker         : fYUVAInfo(yuvaInfo), fMipmapped(mipmapped), fTextureOrigin(origin) {
36*c8dee2aaSAndroid Build Coastguard Worker     if (!yuvaInfo.isValid()) {
37*c8dee2aaSAndroid Build Coastguard Worker         *this = {};
38*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->isValid());
39*c8dee2aaSAndroid Build Coastguard Worker         return;
40*c8dee2aaSAndroid Build Coastguard Worker     }
41*c8dee2aaSAndroid Build Coastguard Worker     int n = yuvaInfo.numPlanes();
42*c8dee2aaSAndroid Build Coastguard Worker     for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
43*c8dee2aaSAndroid Build Coastguard Worker         if (!formats[i].isValid() || formats[i].backend() != formats[0].backend()) {
44*c8dee2aaSAndroid Build Coastguard Worker             *this = {};
45*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(!this->isValid());
46*c8dee2aaSAndroid Build Coastguard Worker             return;
47*c8dee2aaSAndroid Build Coastguard Worker         }
48*c8dee2aaSAndroid Build Coastguard Worker         int numRequiredChannels = yuvaInfo.numChannelsInPlane(i);
49*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(numRequiredChannels > 0);
50*c8dee2aaSAndroid Build Coastguard Worker         int numActualChannels = num_channels(formats[i]);
51*c8dee2aaSAndroid Build Coastguard Worker         if (numActualChannels < numRequiredChannels) {
52*c8dee2aaSAndroid Build Coastguard Worker             *this = {};
53*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(!this->isValid());
54*c8dee2aaSAndroid Build Coastguard Worker             return;
55*c8dee2aaSAndroid Build Coastguard Worker         }
56*c8dee2aaSAndroid Build Coastguard Worker         fPlaneFormats[i] = formats[i];
57*c8dee2aaSAndroid Build Coastguard Worker     }
58*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(this->isValid());
59*c8dee2aaSAndroid Build Coastguard Worker }
60*c8dee2aaSAndroid Build Coastguard Worker 
operator ==(const GrYUVABackendTextureInfo & that) const61*c8dee2aaSAndroid Build Coastguard Worker bool GrYUVABackendTextureInfo::operator==(const GrYUVABackendTextureInfo& that) const {
62*c8dee2aaSAndroid Build Coastguard Worker     if (fYUVAInfo != that.fYUVAInfo ||
63*c8dee2aaSAndroid Build Coastguard Worker         fMipmapped != that.fMipmapped ||
64*c8dee2aaSAndroid Build Coastguard Worker         fTextureOrigin != that.fTextureOrigin) {
65*c8dee2aaSAndroid Build Coastguard Worker         return false;
66*c8dee2aaSAndroid Build Coastguard Worker     }
67*c8dee2aaSAndroid Build Coastguard Worker     int n = fYUVAInfo.numPlanes();
68*c8dee2aaSAndroid Build Coastguard Worker     return std::equal(fPlaneFormats, fPlaneFormats + n, that.fPlaneFormats);
69*c8dee2aaSAndroid Build Coastguard Worker }
70*c8dee2aaSAndroid Build Coastguard Worker 
toYUVALocations() const71*c8dee2aaSAndroid Build Coastguard Worker SkYUVAInfo::YUVALocations GrYUVABackendTextureInfo::toYUVALocations() const {
72*c8dee2aaSAndroid Build Coastguard Worker     uint32_t channelFlags[] = {fPlaneFormats[0].channelMask(),
73*c8dee2aaSAndroid Build Coastguard Worker                                fPlaneFormats[1].channelMask(),
74*c8dee2aaSAndroid Build Coastguard Worker                                fPlaneFormats[2].channelMask(),
75*c8dee2aaSAndroid Build Coastguard Worker                                fPlaneFormats[3].channelMask()};
76*c8dee2aaSAndroid Build Coastguard Worker     auto result = fYUVAInfo.toYUVALocations(channelFlags);
77*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(int numPlanes;)
78*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
79*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(numPlanes == this->numPlanes());
80*c8dee2aaSAndroid Build Coastguard Worker     return result;
81*c8dee2aaSAndroid Build Coastguard Worker }
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
84*c8dee2aaSAndroid Build Coastguard Worker 
GrYUVABackendTextures(const SkYUVAInfo & yuvaInfo,const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],GrSurfaceOrigin textureOrigin)85*c8dee2aaSAndroid Build Coastguard Worker GrYUVABackendTextures::GrYUVABackendTextures(
86*c8dee2aaSAndroid Build Coastguard Worker         const SkYUVAInfo& yuvaInfo,
87*c8dee2aaSAndroid Build Coastguard Worker         const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],
88*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceOrigin textureOrigin)
89*c8dee2aaSAndroid Build Coastguard Worker         : fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
90*c8dee2aaSAndroid Build Coastguard Worker     if (!fYUVAInfo.isValid()) {
91*c8dee2aaSAndroid Build Coastguard Worker         return;
92*c8dee2aaSAndroid Build Coastguard Worker     }
93*c8dee2aaSAndroid Build Coastguard Worker     SkISize planeDimensions[SkYUVAInfo::kMaxPlanes];
94*c8dee2aaSAndroid Build Coastguard Worker     int numPlanes = yuvaInfo.planeDimensions(planeDimensions);
95*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < numPlanes; ++i) {
96*c8dee2aaSAndroid Build Coastguard Worker         int numRequiredChannels = fYUVAInfo.numChannelsInPlane(i);
97*c8dee2aaSAndroid Build Coastguard Worker         if (!textures[i].isValid() ||
98*c8dee2aaSAndroid Build Coastguard Worker             textures[i].dimensions() != planeDimensions[i] ||
99*c8dee2aaSAndroid Build Coastguard Worker             textures[i].backend() != textures[0].backend() ||
100*c8dee2aaSAndroid Build Coastguard Worker             num_channels(textures[i].getBackendFormat()) < numRequiredChannels) {
101*c8dee2aaSAndroid Build Coastguard Worker             *this = {};
102*c8dee2aaSAndroid Build Coastguard Worker             return;
103*c8dee2aaSAndroid Build Coastguard Worker         }
104*c8dee2aaSAndroid Build Coastguard Worker         fTextures[i] = textures[i];
105*c8dee2aaSAndroid Build Coastguard Worker     }
106*c8dee2aaSAndroid Build Coastguard Worker }
107*c8dee2aaSAndroid Build Coastguard Worker 
toYUVALocations() const108*c8dee2aaSAndroid Build Coastguard Worker SkYUVAInfo::YUVALocations GrYUVABackendTextures::toYUVALocations() const {
109*c8dee2aaSAndroid Build Coastguard Worker     uint32_t channelFlags[] = {fTextures[0].getBackendFormat().channelMask(),
110*c8dee2aaSAndroid Build Coastguard Worker                                fTextures[1].getBackendFormat().channelMask(),
111*c8dee2aaSAndroid Build Coastguard Worker                                fTextures[2].getBackendFormat().channelMask(),
112*c8dee2aaSAndroid Build Coastguard Worker                                fTextures[3].getBackendFormat().channelMask()};
113*c8dee2aaSAndroid Build Coastguard Worker     auto result = fYUVAInfo.toYUVALocations(channelFlags);
114*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(int numPlanes;)
115*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
116*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(numPlanes == this->numPlanes());
117*c8dee2aaSAndroid Build Coastguard Worker     return result;
118*c8dee2aaSAndroid Build Coastguard Worker }
119