xref: /aosp_15_r20/external/skia/src/core/SkYUVAInfoLocation.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 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 #ifndef SkYUVAInfoLocation_DEFINED
9 #define SkYUVAInfoLocation_DEFINED
10 
11 #include "include/core/SkColor.h"
12 #include "include/core/SkYUVAInfo.h"
13 
14 #include <algorithm>
15 
16 /**
17  * The location of Y, U, V, or A values within the planes described by SkYUVAInfo. Computed from a
18  * SkYUVAInfo and the set of channels present in a set of pixmaps/textures.
19  */
20 struct SkYUVAInfo::YUVALocation {
21     /** The index of the plane where the Y, U, V, or A value is to be found. */
22     int fPlane = -1;
23     /** The channel in the plane that contains the Y, U, V, or A value. */
24     SkColorChannel fChannel = SkColorChannel::kA;
25 
26     bool operator==(const YUVALocation& that) const {
27         return fPlane == that.fPlane && fChannel == that.fChannel;
28     }
29     bool operator!=(const YUVALocation& that) const { return !(*this == that); }
30 
31     static bool AreValidLocations(const SkYUVAInfo::YUVALocations& locations,
32                                   int* numPlanes = nullptr) {
33         int maxSlotUsed = -1;
34         bool used[SkYUVAInfo::kMaxPlanes] = {};
35         bool valid = true;
36         for (int i = 0; i < SkYUVAInfo::kYUVAChannelCount; ++i) {
37             if (locations[i].fPlane < 0) {
38                 if (i != SkYUVAInfo::YUVAChannels::kA) {
39                     valid = false;  // only the 'A' plane can be omitted
40                 }
41             } else if (locations[i].fPlane >= SkYUVAInfo::kMaxPlanes) {
42                 valid = false;  // A maximum of four input textures is allowed
43             } else {
44                 maxSlotUsed = std::max(locations[i].fPlane, maxSlotUsed);
45                 used[i] = true;
46             }
47         }
48 
49         // All the used slots should be packed starting at 0 with no gaps
50         for (int i = 0; i <= maxSlotUsed; ++i) {
51             if (!used[i]) {
52                 valid = false;
53             }
54         }
55 
56         if (numPlanes) {
57             *numPlanes = valid ? maxSlotUsed + 1 : 0;
58         }
59         return valid;
60     }
61 };
62 
63 #endif
64