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 
26 namespace arm
27 {
28 namespace mapper
29 {
30 namespace common
31 {
32 
33 using aidl::android::hardware::graphics::common::Rect;
34 using aidl::android::hardware::graphics::common::Smpte2086;
35 using aidl::android::hardware::graphics::common::Cta861_3;
36 using aidl::android::hardware::graphics::common::BlendMode;
37 using aidl::android::hardware::graphics::common::Dataspace;
38 
39 template <typename T>
40 struct aligned_optional
41 {
42 	enum class state : uint32_t
43 	{
44 		vacant,
45 		occupied,
46 	};
47 
48 	state item_state { state::vacant };
49 	T item {};
50 
51 	aligned_optional() = default;
52 
aligned_optionalaligned_optional53 	aligned_optional(T initial_value)
54 	    : item_state(state::occupied)
55 	    , item(initial_value)
56 	{
57 	}
58 
aligned_optionalaligned_optional59 	aligned_optional(std::optional<T> std_optional)
60 	    : item_state(std_optional ? state::occupied : state::vacant)
61 	{
62 		if (std_optional)
63 		{
64 			item = *std_optional;
65 		}
66 	}
67 
to_std_optionalaligned_optional68 	std::optional<T> to_std_optional() const
69 	{
70 		switch (item_state)
71 		{
72 		case state::vacant: return std::nullopt;
73 		case state::occupied: return std::make_optional(item);
74 		}
75 	}
76 };
77 
78 template <typename T, size_t N>
79 struct aligned_inline_vector
80 {
81 	uint32_t size;
82 	T contents[N];
83 
capacityaligned_inline_vector84 	constexpr uint32_t capacity() const
85 	{
86 		return N;
87 	}
88 
dataaligned_inline_vector89 	const T *data() const
90 	{
91 		return &contents[0];
92 	}
93 
dataaligned_inline_vector94 	T *data()
95 	{
96 		return &contents[0];
97 	}
98 };
99 
100 struct shared_metadata
101 {
102 	ExynosVideoMeta video_private_data;
103 
104 	aligned_optional<BlendMode> blend_mode {};
105 	aligned_optional<Rect> crop {};
106 	aligned_optional<Cta861_3> cta861_3 {};
107 	aligned_optional<Dataspace> dataspace {};
108 	aligned_optional<Smpte2086> smpte2086 {};
109 	aligned_inline_vector<uint8_t, 2048> smpte2094_40 {};
110 	aligned_inline_vector<char, 256> name {};
111 
112 	shared_metadata() = default;
113 
shared_metadatashared_metadata114 	shared_metadata(std::string_view in_name)
115 	{
116 		name.size = std::min(name.capacity(), static_cast<uint32_t>(in_name.size()));
117 		std::memcpy(name.data(), in_name.data(), name.size);
118 	}
119 
get_nameshared_metadata120 	std::string_view get_name() const
121 	{
122 		return name.size > 0
123 		    ? std::string_view(name.data(), name.size)
124 		    : std::string_view();
125 	}
126 };
127 
128 /* TODO: convert alignment assert taking video metadata into account */
129 #if 0
130 static_assert(offsetof(shared_metadata, blend_mode) == 0, "bad alignment");
131 static_assert(sizeof(shared_metadata::blend_mode) == 8, "bad size");
132 
133 static_assert(offsetof(shared_metadata, crop) == 8, "bad alignment");
134 static_assert(sizeof(shared_metadata::crop) == 20, "bad size");
135 
136 static_assert(offsetof(shared_metadata, cta861_3) == 28, "bad alignment");
137 static_assert(sizeof(shared_metadata::cta861_3) == 12, "bad size");
138 
139 static_assert(offsetof(shared_metadata, dataspace) == 40, "bad alignment");
140 static_assert(sizeof(shared_metadata::dataspace) == 8, "bad size");
141 
142 static_assert(offsetof(shared_metadata, smpte2086) == 48, "bad alignment");
143 static_assert(sizeof(shared_metadata::smpte2086) == 44, "bad size");
144 
145 static_assert(offsetof(shared_metadata, smpte2094_40) == 92, "bad alignment");
146 static_assert(sizeof(shared_metadata::smpte2094_40) == 2052, "bad size");
147 
148 static_assert(offsetof(shared_metadata, name) == 2144, "bad alignment");
149 static_assert(sizeof(shared_metadata::name) == 260, "bad size");
150 
151 static_assert(alignof(shared_metadata) == 4, "bad alignment");
152 static_assert(sizeof(shared_metadata) == 2404, "bad size");
153 #endif
154 
155 } // namespace common
156 } // namespace mapper
157 } // namespace arm
158 
159