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