blob: bf37e1e15619fa88cf0ca9f89e112f1c9a53b7d6 [file] [log] [blame]
chaviw1d044282017-09-27 12:19:28 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
chaviw5bf9d682017-10-25 16:31:08 -070017#include <android-base/stringprintf.h>
chaviw1d044282017-09-27 12:19:28 -070018#include <layerproto/LayerProtoParser.h>
chaviw5bf9d682017-10-25 16:31:08 -070019#include <ui/DebugUtils.h>
20
21using android::base::StringAppendF;
22using android::base::StringPrintf;
chaviw1d044282017-09-27 12:19:28 -070023
24namespace android {
25namespace surfaceflinger {
chaviw5bf9d682017-10-25 16:31:08 -070026
chaviw1d044282017-09-27 12:19:28 -070027bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) {
28 uint32_t ls = lhs->layerStack;
29 uint32_t rs = rhs->layerStack;
30 if (ls != rs) return ls < rs;
31
Robert Carr83f8e4d2017-11-15 14:37:37 -080032 int32_t lz = lhs->z;
33 int32_t rz = rhs->z;
34 if (lz != rz) {
35 return (lz > rz) ? 1 : -1;
36 }
chaviw1d044282017-09-27 12:19:28 -070037
38 return lhs->id < rhs->id;
39}
40
41std::vector<const LayerProtoParser::Layer*> LayerProtoParser::generateLayerTree(
42 const LayersProto& layersProto) {
43 auto layerMap = generateMap(layersProto);
44
45 std::vector<const Layer*> layers;
46 std::for_each(layerMap.begin(), layerMap.end(),
47 [&](const std::pair<const int32_t, Layer*>& ref) {
48 if (ref.second->parent == nullptr) {
49 // only save top level layers
50 layers.push_back(ref.second);
51 }
52 });
53
54 std::sort(layers.begin(), layers.end(), sortLayers);
55 return layers;
56}
57
58std::unordered_map<int32_t, LayerProtoParser::Layer*> LayerProtoParser::generateMap(
59 const LayersProto& layersProto) {
60 std::unordered_map<int32_t, Layer*> layerMap;
61
62 for (int i = 0; i < layersProto.layers_size(); i++) {
63 const LayerProto& layerProto = layersProto.layers(i);
64 layerMap[layerProto.id()] = generateLayer(layerProto);
65 }
66
67 for (int i = 0; i < layersProto.layers_size(); i++) {
68 const LayerProto& layerProto = layersProto.layers(i);
69 updateChildrenAndRelative(layerProto, layerMap);
70 }
71
72 return layerMap;
73}
74
75LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layerProto) {
76 Layer* layer = new Layer();
77 layer->id = layerProto.id();
78 layer->name = layerProto.name();
79 layer->type = layerProto.type();
80 layer->transparentRegion = generateRegion(layerProto.transparent_region());
81 layer->visibleRegion = generateRegion(layerProto.visible_region());
82 layer->damageRegion = generateRegion(layerProto.damage_region());
83 layer->layerStack = layerProto.layer_stack();
84 layer->z = layerProto.z();
85 layer->position = {layerProto.position().x(), layerProto.position().y()};
86 layer->requestedPosition = {layerProto.requested_position().x(),
87 layerProto.requested_position().y()};
88 layer->size = {layerProto.size().w(), layerProto.size().h()};
89 layer->crop = generateRect(layerProto.crop());
90 layer->finalCrop = generateRect(layerProto.final_crop());
91 layer->isOpaque = layerProto.is_opaque();
92 layer->invalidate = layerProto.invalidate();
93 layer->dataspace = layerProto.dataspace();
94 layer->pixelFormat = layerProto.pixel_format();
95 layer->color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
96 layerProto.color().a()};
97 layer->requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
98 layerProto.requested_color().b(), layerProto.requested_color().a()};
99 layer->flags = layerProto.flags();
100 layer->transform = generateTransform(layerProto.transform());
101 layer->requestedTransform = generateTransform(layerProto.requested_transform());
102 layer->activeBuffer = generateActiveBuffer(layerProto.active_buffer());
103 layer->queuedFrames = layerProto.queued_frames();
104 layer->refreshPending = layerProto.refresh_pending();
105
106 return layer;
107}
108
109LayerProtoParser::Region LayerProtoParser::generateRegion(const RegionProto& regionProto) {
110 LayerProtoParser::Region region;
111 region.id = regionProto.id();
112 for (int i = 0; i < regionProto.rect_size(); i++) {
113 const RectProto& rectProto = regionProto.rect(i);
114 region.rects.push_back(generateRect(rectProto));
115 }
116
117 return region;
118}
119
120LayerProtoParser::Rect LayerProtoParser::generateRect(const RectProto& rectProto) {
121 LayerProtoParser::Rect rect;
122 rect.left = rectProto.left();
123 rect.top = rectProto.top();
124 rect.right = rectProto.right();
125 rect.bottom = rectProto.bottom();
126
127 return rect;
128}
129
130LayerProtoParser::Transform LayerProtoParser::generateTransform(
131 const TransformProto& transformProto) {
132 LayerProtoParser::Transform transform;
133 transform.dsdx = transformProto.dsdx();
134 transform.dtdx = transformProto.dtdx();
135 transform.dsdy = transformProto.dsdy();
136 transform.dtdy = transformProto.dtdy();
137
138 return transform;
139}
140
141LayerProtoParser::ActiveBuffer LayerProtoParser::generateActiveBuffer(
142 const ActiveBufferProto& activeBufferProto) {
143 LayerProtoParser::ActiveBuffer activeBuffer;
144 activeBuffer.width = activeBufferProto.width();
145 activeBuffer.height = activeBufferProto.height();
146 activeBuffer.stride = activeBufferProto.stride();
147 activeBuffer.format = activeBufferProto.format();
148
149 return activeBuffer;
150}
151
152void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto,
153 std::unordered_map<int32_t, Layer*>& layerMap) {
154 auto currLayer = layerMap[layerProto.id()];
155
156 for (int i = 0; i < layerProto.children_size(); i++) {
157 if (layerMap.count(layerProto.children(i)) > 0) {
158 auto childLayer = layerMap[layerProto.children(i)];
159 currLayer->children.push_back(childLayer);
160 }
161 }
162
163 for (int i = 0; i < layerProto.relatives_size(); i++) {
164 if (layerMap.count(layerProto.relatives(i)) > 0) {
165 auto relativeLayer = layerMap[layerProto.relatives(i)];
166 currLayer->relatives.push_back(relativeLayer);
167 }
168 }
169
170 if (layerProto.has_parent()) {
171 if (layerMap.count(layerProto.parent()) > 0) {
172 auto parentLayer = layerMap[layerProto.parent()];
173 currLayer->parent = parentLayer;
174 }
175 }
176
177 if (layerProto.has_z_order_relative_of()) {
178 if (layerMap.count(layerProto.z_order_relative_of()) > 0) {
179 auto relativeLayer = layerMap[layerProto.z_order_relative_of()];
180 currLayer->zOrderRelativeOf = relativeLayer;
181 }
182 }
183}
184
185std::string LayerProtoParser::layersToString(
186 const std::vector<const LayerProtoParser::Layer*> layers) {
187 std::string result;
188 for (const LayerProtoParser::Layer* layer : layers) {
189 if (layer->zOrderRelativeOf != nullptr) {
190 continue;
191 }
192 result.append(layerToString(layer).c_str());
193 }
194
195 return result;
196}
197
198std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
199 std::string result;
200
201 std::vector<const Layer*> traverse(layer->relatives);
202 for (const LayerProtoParser::Layer* child : layer->children) {
203 if (child->zOrderRelativeOf != nullptr) {
204 continue;
205 }
206
207 traverse.push_back(child);
208 }
209
210 std::sort(traverse.begin(), traverse.end(), sortLayers);
211
212 size_t i = 0;
213 for (; i < traverse.size(); i++) {
214 const auto& relative = traverse[i];
215 if (relative->z >= 0) {
216 break;
217 }
218 result.append(layerToString(relative).c_str());
219 }
220 result.append(layer->to_string().c_str());
221 result.append("\n");
222 for (; i < traverse.size(); i++) {
223 const auto& relative = traverse[i];
224 result.append(layerToString(relative).c_str());
225 }
226
227 return result;
228}
229
chaviw5bf9d682017-10-25 16:31:08 -0700230std::string LayerProtoParser::ActiveBuffer::to_string() const {
231 return StringPrintf("[%4ux%4u:%4u,%s]", width, height, stride,
232 decodePixelFormat(format).c_str());
233}
234
235std::string LayerProtoParser::Transform::to_string() const {
236 return StringPrintf("[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(dsdx),
237 static_cast<double>(dtdx), static_cast<double>(dsdy),
238 static_cast<double>(dtdy));
239}
240
241std::string LayerProtoParser::Rect::to_string() const {
242 return StringPrintf("[%3d, %3d, %3d, %3d]", left, top, right, bottom);
243}
244
245std::string LayerProtoParser::Region::to_string(const char* what) const {
246 std::string result =
247 StringPrintf(" Region %s (this=%lx count=%d)\n", what, static_cast<unsigned long>(id),
248 static_cast<int>(rects.size()));
249
250 for (auto& rect : rects) {
251 StringAppendF(&result, " %s\n", rect.to_string().c_str());
252 }
253
254 return result;
255}
256
257std::string LayerProtoParser::Layer::to_string() const {
258 std::string result;
259 StringAppendF(&result, "+ %s (%s)\n", type.c_str(), name.c_str());
260 result.append(transparentRegion.to_string("TransparentRegion").c_str());
261 result.append(visibleRegion.to_string("VisibleRegion").c_str());
262 result.append(damageRegion.to_string("SurfaceDamageRegion").c_str());
263
264 StringAppendF(&result, " layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ", layerStack,
265 z, static_cast<double>(position.x), static_cast<double>(position.y), size.x,
266 size.y);
267
268 StringAppendF(&result, "crop=%s, finalCrop=%s, ", crop.to_string().c_str(),
269 finalCrop.to_string().c_str());
270 StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
271 StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
272 StringAppendF(&result, "pixelformat=%s, ", pixelFormat.c_str());
273 StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
274 static_cast<double>(color.r), static_cast<double>(color.g),
275 static_cast<double>(color.b), static_cast<double>(color.a), flags);
276 StringAppendF(&result, "tr=%s", transform.to_string().c_str());
277 result.append("\n");
278 StringAppendF(&result, " parent=%s\n", parent == nullptr ? "none" : parent->name.c_str());
279 StringAppendF(&result, " zOrderRelativeOf=%s\n",
280 zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
281 StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str());
282 StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d", queuedFrames, refreshPending);
283
284 return result;
285}
286
chaviw1d044282017-09-27 12:19:28 -0700287} // namespace surfaceflinger
288} // namespace android