blob: e4545e4494dbd2f9a3b2d29888138e312c1727c2 [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
Yiwei Zhang7124ad32018-02-21 13:02:45 -080041const LayerProtoParser::LayerGlobal LayerProtoParser::generateLayerGlobalInfo(
42 const LayersProto& layersProto) {
43 return {{layersProto.resolution().w(), layersProto.resolution().h()}};
44}
45
46void LayerProtoParser::destroyLayerTree(
47 const std::vector<const LayerProtoParser::Layer*>& layerTree) {
48 for (auto layer : layerTree) {
49 destroyLayerTree(layer->children);
50 delete layer;
51 }
52}
53
chaviw1d044282017-09-27 12:19:28 -070054std::vector<const LayerProtoParser::Layer*> LayerProtoParser::generateLayerTree(
55 const LayersProto& layersProto) {
56 auto layerMap = generateMap(layersProto);
57
58 std::vector<const Layer*> layers;
59 std::for_each(layerMap.begin(), layerMap.end(),
60 [&](const std::pair<const int32_t, Layer*>& ref) {
61 if (ref.second->parent == nullptr) {
62 // only save top level layers
63 layers.push_back(ref.second);
64 }
65 });
66
67 std::sort(layers.begin(), layers.end(), sortLayers);
68 return layers;
69}
70
71std::unordered_map<int32_t, LayerProtoParser::Layer*> LayerProtoParser::generateMap(
72 const LayersProto& layersProto) {
73 std::unordered_map<int32_t, Layer*> layerMap;
74
75 for (int i = 0; i < layersProto.layers_size(); i++) {
76 const LayerProto& layerProto = layersProto.layers(i);
77 layerMap[layerProto.id()] = generateLayer(layerProto);
78 }
79
80 for (int i = 0; i < layersProto.layers_size(); i++) {
81 const LayerProto& layerProto = layersProto.layers(i);
82 updateChildrenAndRelative(layerProto, layerMap);
83 }
84
85 return layerMap;
86}
87
88LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layerProto) {
89 Layer* layer = new Layer();
90 layer->id = layerProto.id();
91 layer->name = layerProto.name();
92 layer->type = layerProto.type();
93 layer->transparentRegion = generateRegion(layerProto.transparent_region());
94 layer->visibleRegion = generateRegion(layerProto.visible_region());
95 layer->damageRegion = generateRegion(layerProto.damage_region());
96 layer->layerStack = layerProto.layer_stack();
97 layer->z = layerProto.z();
98 layer->position = {layerProto.position().x(), layerProto.position().y()};
99 layer->requestedPosition = {layerProto.requested_position().x(),
100 layerProto.requested_position().y()};
101 layer->size = {layerProto.size().w(), layerProto.size().h()};
102 layer->crop = generateRect(layerProto.crop());
103 layer->finalCrop = generateRect(layerProto.final_crop());
104 layer->isOpaque = layerProto.is_opaque();
105 layer->invalidate = layerProto.invalidate();
106 layer->dataspace = layerProto.dataspace();
107 layer->pixelFormat = layerProto.pixel_format();
108 layer->color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
109 layerProto.color().a()};
110 layer->requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
111 layerProto.requested_color().b(), layerProto.requested_color().a()};
112 layer->flags = layerProto.flags();
113 layer->transform = generateTransform(layerProto.transform());
114 layer->requestedTransform = generateTransform(layerProto.requested_transform());
115 layer->activeBuffer = generateActiveBuffer(layerProto.active_buffer());
116 layer->queuedFrames = layerProto.queued_frames();
117 layer->refreshPending = layerProto.refresh_pending();
Yiwei Zhang7124ad32018-02-21 13:02:45 -0800118 layer->hwcFrame = generateRect(layerProto.hwc_frame());
119 layer->hwcCrop = generateFloatRect(layerProto.hwc_crop());
120 layer->hwcTransform = layerProto.hwc_transform();
rongliucfb187b2018-03-14 12:26:23 -0700121 layer->windowType = layerProto.window_type();
122 layer->appId = layerProto.app_id();
chaviw1d044282017-09-27 12:19:28 -0700123
124 return layer;
125}
126
127LayerProtoParser::Region LayerProtoParser::generateRegion(const RegionProto& regionProto) {
128 LayerProtoParser::Region region;
129 region.id = regionProto.id();
130 for (int i = 0; i < regionProto.rect_size(); i++) {
131 const RectProto& rectProto = regionProto.rect(i);
132 region.rects.push_back(generateRect(rectProto));
133 }
134
135 return region;
136}
137
138LayerProtoParser::Rect LayerProtoParser::generateRect(const RectProto& rectProto) {
139 LayerProtoParser::Rect rect;
140 rect.left = rectProto.left();
141 rect.top = rectProto.top();
142 rect.right = rectProto.right();
143 rect.bottom = rectProto.bottom();
144
145 return rect;
146}
147
Yiwei Zhang7124ad32018-02-21 13:02:45 -0800148LayerProtoParser::FloatRect LayerProtoParser::generateFloatRect(const FloatRectProto& rectProto) {
149 LayerProtoParser::FloatRect rect;
150 rect.left = rectProto.left();
151 rect.top = rectProto.top();
152 rect.right = rectProto.right();
153 rect.bottom = rectProto.bottom();
154
155 return rect;
156}
157
chaviw1d044282017-09-27 12:19:28 -0700158LayerProtoParser::Transform LayerProtoParser::generateTransform(
159 const TransformProto& transformProto) {
160 LayerProtoParser::Transform transform;
161 transform.dsdx = transformProto.dsdx();
162 transform.dtdx = transformProto.dtdx();
163 transform.dsdy = transformProto.dsdy();
164 transform.dtdy = transformProto.dtdy();
165
166 return transform;
167}
168
169LayerProtoParser::ActiveBuffer LayerProtoParser::generateActiveBuffer(
170 const ActiveBufferProto& activeBufferProto) {
171 LayerProtoParser::ActiveBuffer activeBuffer;
172 activeBuffer.width = activeBufferProto.width();
173 activeBuffer.height = activeBufferProto.height();
174 activeBuffer.stride = activeBufferProto.stride();
175 activeBuffer.format = activeBufferProto.format();
176
177 return activeBuffer;
178}
179
180void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto,
181 std::unordered_map<int32_t, Layer*>& layerMap) {
182 auto currLayer = layerMap[layerProto.id()];
183
184 for (int i = 0; i < layerProto.children_size(); i++) {
185 if (layerMap.count(layerProto.children(i)) > 0) {
186 auto childLayer = layerMap[layerProto.children(i)];
187 currLayer->children.push_back(childLayer);
188 }
189 }
190
191 for (int i = 0; i < layerProto.relatives_size(); i++) {
192 if (layerMap.count(layerProto.relatives(i)) > 0) {
193 auto relativeLayer = layerMap[layerProto.relatives(i)];
194 currLayer->relatives.push_back(relativeLayer);
195 }
196 }
197
198 if (layerProto.has_parent()) {
199 if (layerMap.count(layerProto.parent()) > 0) {
200 auto parentLayer = layerMap[layerProto.parent()];
201 currLayer->parent = parentLayer;
202 }
203 }
204
205 if (layerProto.has_z_order_relative_of()) {
206 if (layerMap.count(layerProto.z_order_relative_of()) > 0) {
207 auto relativeLayer = layerMap[layerProto.z_order_relative_of()];
208 currLayer->zOrderRelativeOf = relativeLayer;
209 }
210 }
211}
212
213std::string LayerProtoParser::layersToString(
214 const std::vector<const LayerProtoParser::Layer*> layers) {
215 std::string result;
216 for (const LayerProtoParser::Layer* layer : layers) {
217 if (layer->zOrderRelativeOf != nullptr) {
218 continue;
219 }
220 result.append(layerToString(layer).c_str());
221 }
222
223 return result;
224}
225
226std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
227 std::string result;
228
229 std::vector<const Layer*> traverse(layer->relatives);
230 for (const LayerProtoParser::Layer* child : layer->children) {
231 if (child->zOrderRelativeOf != nullptr) {
232 continue;
233 }
234
235 traverse.push_back(child);
236 }
237
238 std::sort(traverse.begin(), traverse.end(), sortLayers);
239
240 size_t i = 0;
241 for (; i < traverse.size(); i++) {
242 const auto& relative = traverse[i];
243 if (relative->z >= 0) {
244 break;
245 }
246 result.append(layerToString(relative).c_str());
247 }
248 result.append(layer->to_string().c_str());
249 result.append("\n");
250 for (; i < traverse.size(); i++) {
251 const auto& relative = traverse[i];
252 result.append(layerToString(relative).c_str());
253 }
254
255 return result;
256}
257
chaviw5bf9d682017-10-25 16:31:08 -0700258std::string LayerProtoParser::ActiveBuffer::to_string() const {
259 return StringPrintf("[%4ux%4u:%4u,%s]", width, height, stride,
260 decodePixelFormat(format).c_str());
261}
262
263std::string LayerProtoParser::Transform::to_string() const {
264 return StringPrintf("[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(dsdx),
265 static_cast<double>(dtdx), static_cast<double>(dsdy),
266 static_cast<double>(dtdy));
267}
268
269std::string LayerProtoParser::Rect::to_string() const {
270 return StringPrintf("[%3d, %3d, %3d, %3d]", left, top, right, bottom);
271}
272
Yiwei Zhang7124ad32018-02-21 13:02:45 -0800273std::string LayerProtoParser::FloatRect::to_string() const {
274 return StringPrintf("[%.2f, %.2f, %.2f, %.2f]", left, top, right, bottom);
275}
276
chaviw5bf9d682017-10-25 16:31:08 -0700277std::string LayerProtoParser::Region::to_string(const char* what) const {
278 std::string result =
279 StringPrintf(" Region %s (this=%lx count=%d)\n", what, static_cast<unsigned long>(id),
280 static_cast<int>(rects.size()));
281
282 for (auto& rect : rects) {
283 StringAppendF(&result, " %s\n", rect.to_string().c_str());
284 }
285
286 return result;
287}
288
289std::string LayerProtoParser::Layer::to_string() const {
290 std::string result;
291 StringAppendF(&result, "+ %s (%s)\n", type.c_str(), name.c_str());
292 result.append(transparentRegion.to_string("TransparentRegion").c_str());
293 result.append(visibleRegion.to_string("VisibleRegion").c_str());
294 result.append(damageRegion.to_string("SurfaceDamageRegion").c_str());
295
296 StringAppendF(&result, " layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ", layerStack,
297 z, static_cast<double>(position.x), static_cast<double>(position.y), size.x,
298 size.y);
299
300 StringAppendF(&result, "crop=%s, finalCrop=%s, ", crop.to_string().c_str(),
301 finalCrop.to_string().c_str());
302 StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
303 StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
304 StringAppendF(&result, "pixelformat=%s, ", pixelFormat.c_str());
305 StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
306 static_cast<double>(color.r), static_cast<double>(color.g),
307 static_cast<double>(color.b), static_cast<double>(color.a), flags);
308 StringAppendF(&result, "tr=%s", transform.to_string().c_str());
309 result.append("\n");
310 StringAppendF(&result, " parent=%s\n", parent == nullptr ? "none" : parent->name.c_str());
311 StringAppendF(&result, " zOrderRelativeOf=%s\n",
312 zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
313 StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str());
rongliucfb187b2018-03-14 12:26:23 -0700314 StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d,", queuedFrames, refreshPending);
315 StringAppendF(&result, " windowType=%d, appId=%d", windowType, appId);
chaviw5bf9d682017-10-25 16:31:08 -0700316
317 return result;
318}
319
chaviw1d044282017-09-27 12:19:28 -0700320} // namespace surfaceflinger
321} // namespace android