• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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/GrYUVABackendTextures.h"
9 
10 #include "src/core/SkYUVAInfoLocation.h"
11 
num_channels(const GrBackendFormat & format)12 static int num_channels(const GrBackendFormat& format) {
13     switch (format.channelMask()) {
14         case kRed_SkColorChannelFlag        : return 1;
15         case kAlpha_SkColorChannelFlag      : return 1;
16         case kGray_SkColorChannelFlag       : return 1;
17         case kGrayAlpha_SkColorChannelFlags : return 2;
18         case kRG_SkColorChannelFlags        : return 2;
19         case kRGB_SkColorChannelFlags       : return 3;
20         case kRGBA_SkColorChannelFlags      : return 4;
21         default                             : return 0;
22     }
23 }
24 
GrYUVABackendTextureInfo(const SkYUVAInfo & yuvaInfo,const GrBackendFormat formats[kMaxPlanes],GrMipmapped mipmapped,GrSurfaceOrigin origin)25 GrYUVABackendTextureInfo::GrYUVABackendTextureInfo(const SkYUVAInfo& yuvaInfo,
26                                                    const GrBackendFormat formats[kMaxPlanes],
27                                                    GrMipmapped mipmapped,
28                                                    GrSurfaceOrigin origin)
29         : fYUVAInfo(yuvaInfo), fMipmapped(mipmapped), fTextureOrigin(origin) {
30     if (!yuvaInfo.isValid()) {
31         *this = {};
32         SkASSERT(!this->isValid());
33         return;
34     }
35     int n = yuvaInfo.numPlanes();
36     for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
37         if (!formats[i].isValid() || formats[i].backend() != formats[0].backend()) {
38             *this = {};
39             SkASSERT(!this->isValid());
40             return;
41         }
42         int numRequiredChannels = yuvaInfo.numChannelsInPlane(i);
43         SkASSERT(numRequiredChannels > 0);
44         int numActualChannels = num_channels(formats[i]);
45         if (numActualChannels < numRequiredChannels) {
46             *this = {};
47             SkASSERT(!this->isValid());
48             return;
49         }
50         fPlaneFormats[i] = formats[i];
51     }
52     SkASSERT(this->isValid());
53 }
54 
operator ==(const GrYUVABackendTextureInfo & that) const55 bool GrYUVABackendTextureInfo::operator==(const GrYUVABackendTextureInfo& that) const {
56     if (fYUVAInfo != that.fYUVAInfo ||
57         fMipmapped != that.fMipmapped ||
58         fTextureOrigin != that.fTextureOrigin) {
59         return false;
60     }
61     int n = fYUVAInfo.numPlanes();
62     return std::equal(fPlaneFormats, fPlaneFormats + n, that.fPlaneFormats);
63 }
64 
toYUVALocations() const65 SkYUVAInfo::YUVALocations GrYUVABackendTextureInfo::toYUVALocations() const {
66     uint32_t channelFlags[] = {fPlaneFormats[0].channelMask(),
67                                fPlaneFormats[1].channelMask(),
68                                fPlaneFormats[2].channelMask(),
69                                fPlaneFormats[3].channelMask()};
70     auto result = fYUVAInfo.toYUVALocations(channelFlags);
71     SkDEBUGCODE(int numPlanes;)
72     SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
73     SkASSERT(numPlanes == this->numPlanes());
74     return result;
75 }
76 
77 //////////////////////////////////////////////////////////////////////////////
78 
GrYUVABackendTextures(const SkYUVAInfo & yuvaInfo,const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],GrSurfaceOrigin textureOrigin)79 GrYUVABackendTextures::GrYUVABackendTextures(
80         const SkYUVAInfo& yuvaInfo,
81         const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],
82         GrSurfaceOrigin textureOrigin)
83         : fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
84     if (!fYUVAInfo.isValid()) {
85         return;
86     }
87     SkISize planeDimensions[SkYUVAInfo::kMaxPlanes];
88     int numPlanes = yuvaInfo.planeDimensions(planeDimensions);
89     for (int i = 0; i < numPlanes; ++i) {
90         int numRequiredChannels = fYUVAInfo.numChannelsInPlane(i);
91         if (!textures[i].isValid() ||
92             textures[i].dimensions() != planeDimensions[i] ||
93             textures[i].backend() != textures[0].backend() ||
94             num_channels(textures[i].getBackendFormat()) < numRequiredChannels) {
95             *this = {};
96             return;
97         }
98         fTextures[i] = textures[i];
99     }
100 }
101 
toYUVALocations() const102 SkYUVAInfo::YUVALocations GrYUVABackendTextures::toYUVALocations() const {
103     uint32_t channelFlags[] = {fTextures[0].getBackendFormat().channelMask(),
104                                fTextures[1].getBackendFormat().channelMask(),
105                                fTextures[2].getBackendFormat().channelMask(),
106                                fTextures[3].getBackendFormat().channelMask()};
107     auto result = fYUVAInfo.toYUVALocations(channelFlags);
108     SkDEBUGCODE(int numPlanes;)
109     SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
110     SkASSERT(numPlanes == this->numPlanes());
111     return result;
112 }
113