blob: a29e7001ca2267c340ecd4a3d016a6ed2f4ea280 [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
10static int num_channels(const GrBackendFormat& format) {
11 switch (format.channelMask()) {
Brian Salomon01ff5382020-12-15 16:06:26 -050012 case kRed_SkColorChannelFlag : return 1;
13 case kAlpha_SkColorChannelFlag : return 1;
14 case kGray_SkColorChannelFlag : return 1;
15 case kGrayAlpha_SkColorChannelFlags : return 2;
16 case kRG_SkColorChannelFlags : return 2;
17 case kRGB_SkColorChannelFlags : return 3;
18 case kRGBA_SkColorChannelFlags : return 4;
19 default : return 0;
Brian Salomonc1a249d2020-10-19 10:55:45 -040020 }
21}
22
Brian Salomonbd3792d2020-11-10 14:17:58 -050023GrYUVABackendTextureInfo::GrYUVABackendTextureInfo(const SkYUVAInfo& yuvaInfo,
24 const GrBackendFormat formats[kMaxPlanes],
25 GrMipmapped mipmapped,
26 GrSurfaceOrigin origin)
27 : fYUVAInfo(yuvaInfo), fMipmapped(mipmapped), fTextureOrigin(origin) {
28 if (!yuvaInfo.isValid()) {
29 *this = {};
30 SkASSERT(!this->isValid());
31 return;
32 }
33 int n = yuvaInfo.numPlanes();
34 for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
35 if (!formats[i].isValid() || formats[i].backend() != formats[0].backend()) {
36 *this = {};
37 SkASSERT(!this->isValid());
38 return;
39 }
40 int numRequiredChannels = yuvaInfo.numChannelsInPlane(i);
41 SkASSERT(numRequiredChannels > 0);
42 int numActualChannels = num_channels(formats[i]);
43 if (numActualChannels < numRequiredChannels) {
44 *this = {};
45 SkASSERT(!this->isValid());
46 }
47 fPlaneFormats[i] = formats[i];
48 }
49 SkASSERT(this->isValid());
50}
51
52bool GrYUVABackendTextureInfo::operator==(const GrYUVABackendTextureInfo& that) const {
53 if (fYUVAInfo != that.fYUVAInfo ||
54 fMipmapped != that.fMipmapped ||
55 fTextureOrigin != that.fTextureOrigin) {
56 return false;
57 }
58 int n = fYUVAInfo.numPlanes();
59 return std::equal(fPlaneFormats, fPlaneFormats + n, that.fPlaneFormats);
60}
61
62bool GrYUVABackendTextureInfo::toYUVAIndices(SkYUVAIndex indices[SkYUVAIndex::kIndexCount]) const {
63 SkASSERT(indices);
64 uint32_t channelFlags[] = {fPlaneFormats[0].channelMask(),
65 fPlaneFormats[1].channelMask(),
66 fPlaneFormats[2].channelMask(),
67 fPlaneFormats[3].channelMask()};
68 return fYUVAInfo.toYUVAIndices(channelFlags, indices);
69}
70
71//////////////////////////////////////////////////////////////////////////////
72
Brian Salomonc1a249d2020-10-19 10:55:45 -040073GrYUVABackendTextures::GrYUVABackendTextures(
74 const SkYUVAInfo& yuvaInfo,
75 const GrBackendTexture textures[SkYUVAInfo::kMaxPlanes],
76 GrSurfaceOrigin textureOrigin)
77 : fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
78 if (!fYUVAInfo.isValid()) {
79 return;
80 }
81 SkISize planeDimensions[SkYUVAInfo::kMaxPlanes];
82 int numPlanes = yuvaInfo.planeDimensions(planeDimensions);
83 for (int i = 0; i < numPlanes; ++i) {
84 int numRequiredChannels = fYUVAInfo.numChannelsInPlane(i);
85 if (!textures[i].isValid() ||
86 textures[i].dimensions() != planeDimensions[i] ||
87 textures[i].backend() != textures[0].backend() ||
88 num_channels(textures[i].getBackendFormat()) < numRequiredChannels) {
89 *this = {};
90 return;
91 }
92 fTextures[i] = textures[i];
93 }
94}
95
96bool GrYUVABackendTextures::toYUVAIndices(SkYUVAIndex indices[SkYUVAIndex::kIndexCount]) const {
97 SkASSERT(indices);
98 uint32_t channelFlags[] = {fTextures[0].getBackendFormat().channelMask(),
99 fTextures[1].getBackendFormat().channelMask(),
100 fTextures[2].getBackendFormat().channelMask(),
101 fTextures[3].getBackendFormat().channelMask()};
102 return fYUVAInfo.toYUVAIndices(channelFlags, indices);
103}