1 /*
2  * Copyright (C) 2020 Arm Limited.
3  *
4  * Copyright 2016 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #pragma once
20 
21 #include <optional>
22 #include <vector>
23 #include <VendorVideoAPI.h>
24 #include "gralloctypes/Gralloc4.h"
25 #include <pixel-gralloc/metadata.h>
26 
27 namespace arm
28 {
29 namespace mapper
30 {
31 namespace common
32 {
33 
34 using aidl::android::hardware::graphics::common::Rect;
35 using aidl::android::hardware::graphics::common::Smpte2086;
36 using aidl::android::hardware::graphics::common::Cta861_3;
37 using aidl::android::hardware::graphics::common::BlendMode;
38 using aidl::android::hardware::graphics::common::Dataspace;
39 using ::pixel::graphics::VideoGMV;
40 
41 template <typename T>
42 struct aligned_optional
43 {
44 	enum class state : uint32_t
45 	{
46 		vacant,
47 		occupied,
48 	};
49 
50 	state item_state { state::vacant };
51 	T item {};
52 
53 	aligned_optional() = default;
54 
aligned_optionalaligned_optional55 	aligned_optional(T initial_value)
56 	    : item_state(state::occupied)
57 	    , item(initial_value)
58 	{
59 	}
60 
aligned_optionalaligned_optional61 	aligned_optional(std::optional<T> std_optional)
62 	    : item_state(std_optional ? state::occupied : state::vacant)
63 	{
64 		if (std_optional)
65 		{
66 			item = *std_optional;
67 		}
68 	}
69 
to_std_optionalaligned_optional70 	std::optional<T> to_std_optional() const
71 	{
72 		switch (item_state)
73 		{
74 		case state::vacant: return std::nullopt;
75 		case state::occupied: return std::make_optional(item);
76 		}
77 	}
78 };
79 
80 template <typename T, size_t N>
81 struct aligned_inline_vector
82 {
83 	uint32_t size;
84 	T contents[N];
85 
capacityaligned_inline_vector86 	constexpr uint32_t capacity() const
87 	{
88 		return N;
89 	}
90 
dataaligned_inline_vector91 	const T *data() const
92 	{
93 		return &contents[0];
94 	}
95 
dataaligned_inline_vector96 	T *data()
97 	{
98 		return &contents[0];
99 	}
100 };
101 
102 struct shared_metadata
103 {
104 	ExynosVideoMeta video_private_data;
105 	VideoGMV video_gmv_data;
106 
107 	aligned_optional<BlendMode> blend_mode {};
108 	aligned_optional<Rect> crop {};
109 	aligned_optional<Cta861_3> cta861_3 {};
110 	aligned_optional<Dataspace> dataspace {};
111 	aligned_optional<Smpte2086> smpte2086 {};
112 	aligned_inline_vector<uint8_t, 2048> smpte2094_40 {};
113 	aligned_inline_vector<char, 256> name {};
114 
115 	shared_metadata() = default;
116 
shared_metadatashared_metadata117 	shared_metadata(std::string_view in_name)
118 	{
119 		name.size = std::min(name.capacity(), static_cast<uint32_t>(in_name.size()));
120 		std::memcpy(name.data(), in_name.data(), name.size);
121 	}
122 
get_nameshared_metadata123 	std::string_view get_name() const
124 	{
125 		return name.size > 0
126 		    ? std::string_view(name.data(), name.size)
127 		    : std::string_view();
128 	}
129 };
130 
131 /* TODO: convert alignment assert taking video metadata into account */
132 #if 0
133 static_assert(offsetof(shared_metadata, blend_mode) == 0, "bad alignment");
134 static_assert(sizeof(shared_metadata::blend_mode) == 8, "bad size");
135 
136 static_assert(offsetof(shared_metadata, crop) == 8, "bad alignment");
137 static_assert(sizeof(shared_metadata::crop) == 20, "bad size");
138 
139 static_assert(offsetof(shared_metadata, cta861_3) == 28, "bad alignment");
140 static_assert(sizeof(shared_metadata::cta861_3) == 12, "bad size");
141 
142 static_assert(offsetof(shared_metadata, dataspace) == 40, "bad alignment");
143 static_assert(sizeof(shared_metadata::dataspace) == 8, "bad size");
144 
145 static_assert(offsetof(shared_metadata, smpte2086) == 48, "bad alignment");
146 static_assert(sizeof(shared_metadata::smpte2086) == 44, "bad size");
147 
148 static_assert(offsetof(shared_metadata, smpte2094_40) == 92, "bad alignment");
149 static_assert(sizeof(shared_metadata::smpte2094_40) == 2052, "bad size");
150 
151 static_assert(offsetof(shared_metadata, name) == 2144, "bad alignment");
152 static_assert(sizeof(shared_metadata::name) == 260, "bad size");
153 
154 static_assert(alignof(shared_metadata) == 4, "bad alignment");
155 static_assert(sizeof(shared_metadata) == 2404, "bad size");
156 #endif
157 
158 } // namespace common
159 } // namespace mapper
160 } // namespace arm
161 
162