blob: 66743df0b31fc1a320605d75ba6f6207b48eed3a [file] [log] [blame]
Brian Salomonc1a249d2020-10-19 10:55:45 -04001/*
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
Brian Salomon0c0b5a62021-01-11 14:40:44 -050010#include "src/core/SkYUVAInfoLocation.h"
11
Brian Salomonc1a249d2020-10-19 10:55:45 -040012static int num_channels(const GrBackendFormat& format) {
13 switch (format.channelMask()) {
Brian Salomon01ff5382020-12-15 16:06:26 -050014 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;
Brian Salomonc1a249d2020-10-19 10:55:45 -040022 }
23}
24
Brian Salomonbd3792d2020-11-10 14:17:58 -050025GrYUVABackendTextureInfo::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 }
49 fPlaneFormats[i] = formats[i];
50 }
51 SkASSERT(this->isValid());
52}
53
54bool GrYUVABackendTextureInfo::operator==(const GrYUVABackendTextureInfo& that) const {
55 if (fYUVAInfo != that.fYUVAInfo ||
56 fMipmapped != that.fMipmapped ||
57 fTextureOrigin != that.fTextureOrigin) {
58 return false;
59 }
60 int n = fYUVAInfo.numPlanes();
61 return std::equal(fPlaneFormats, fPlaneFormats + n, that.fPlaneFormats);
62}
63
Brian Salomon0c0b5a62021-01-11 14:40:44 -050064SkYUVAInfo::YUVALocations GrYUVABackendTextureInfo::toYUVALocations() const {
Brian Salomonbd3792d2020-11-10 14:17:58 -050065 uint32_t channelFlags[] = {fPlaneFormats[0].channelMask(),
66 fPlaneFormats[1].channelMask(),
67 fPlaneFormats[2].channelMask(),
68 fPlaneFormats[3].channelMask()};
Brian Salomon0c0b5a62021-01-11 14:40:44 -050069 auto result = fYUVAInfo.toYUVALocations(channelFlags);
70 SkDEBUGCODE(int numPlanes;)
71 SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
72 SkASSERT(numPlanes == this->numPlanes());
73 return result;
Brian Salomonbd3792d2020-11-10 14:17:58 -050074}
75
76//////////////////////////////////////////////////////////////////////////////
77
Brian Salomonc1a249d2020-10-19 10:55:45 -040078GrYUVABackendTextures::GrYUVABackendTextures(
79 const SkYUVAInfo& yuvaInfo,
80 const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],
81 GrSurfaceOrigin textureOrigin)
82 : fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
83 if (!fYUVAInfo.isValid()) {
84 return;
85 }
86 SkISize planeDimensions[SkYUVAInfo::kMaxPlanes];
87 int numPlanes = yuvaInfo.planeDimensions(planeDimensions);
88 for (int i = 0; i < numPlanes; ++i) {
89 int numRequiredChannels = fYUVAInfo.numChannelsInPlane(i);
90 if (!textures[i].isValid() ||
91 textures[i].dimensions() != planeDimensions[i] ||
92 textures[i].backend() != textures[0].backend() ||
93 num_channels(textures[i].getBackendFormat()) < numRequiredChannels) {
94 *this = {};
95 return;
96 }
97 fTextures[i] = textures[i];
98 }
99}
100
Brian Salomon0c0b5a62021-01-11 14:40:44 -0500101SkYUVAInfo::YUVALocations GrYUVABackendTextures::toYUVALocations() const {
Brian Salomonc1a249d2020-10-19 10:55:45 -0400102 uint32_t channelFlags[] = {fTextures[0].getBackendFormat().channelMask(),
103 fTextures[1].getBackendFormat().channelMask(),
104 fTextures[2].getBackendFormat().channelMask(),
105 fTextures[3].getBackendFormat().channelMask()};
Brian Salomon0c0b5a62021-01-11 14:40:44 -0500106 auto result = fYUVAInfo.toYUVALocations(channelFlags);
107 SkDEBUGCODE(int numPlanes;)
108 SkASSERT(SkYUVAInfo::YUVALocation::AreValidLocations(result, &numPlanes));
109 SkASSERT(numPlanes == this->numPlanes());
110 return result;
Brian Salomonc1a249d2020-10-19 10:55:45 -0400111}