• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 #pragma clang diagnostic ignored "-Wextra"
21 
22 #include "LayerProtoHelper.h"
23 
24 namespace android {
25 
26 using gui::WindowInfo;
27 
28 namespace surfaceflinger {
29 
writePositionToProto(const float x,const float y,std::function<PositionProto * ()> getPositionProto)30 void LayerProtoHelper::writePositionToProto(const float x, const float y,
31                                             std::function<PositionProto*()> getPositionProto) {
32     if (x != 0 || y != 0) {
33         // Use a lambda do avoid writing the object header when the object is empty
34         PositionProto* position = getPositionProto();
35         position->set_x(x);
36         position->set_y(y);
37     }
38 }
39 
writeSizeToProto(const uint32_t w,const uint32_t h,std::function<SizeProto * ()> getSizeProto)40 void LayerProtoHelper::writeSizeToProto(const uint32_t w, const uint32_t h,
41                                         std::function<SizeProto*()> getSizeProto) {
42     if (w != 0 || h != 0) {
43         // Use a lambda do avoid writing the object header when the object is empty
44         SizeProto* size = getSizeProto();
45         size->set_w(w);
46         size->set_h(h);
47     }
48 }
49 
writeToProto(const Region & region,std::function<RegionProto * ()> getRegionProto)50 void LayerProtoHelper::writeToProto(const Region& region,
51                                     std::function<RegionProto*()> getRegionProto) {
52     if (region.isEmpty()) {
53         return;
54     }
55 
56     writeToProto(region, getRegionProto());
57 }
58 
writeToProto(const Region & region,RegionProto * regionProto)59 void LayerProtoHelper::writeToProto(const Region& region, RegionProto* regionProto) {
60     if (region.isEmpty()) {
61         return;
62     }
63 
64     Region::const_iterator head = region.begin();
65     Region::const_iterator const tail = region.end();
66     // Use a lambda do avoid writing the object header when the object is empty
67     while (head != tail) {
68         writeToProto(*head, regionProto->add_rect());
69         head++;
70     }
71 }
72 
readFromProto(const RegionProto & regionProto,Region & outRegion)73 void LayerProtoHelper::readFromProto(const RegionProto& regionProto, Region& outRegion) {
74     for (int i = 0; i < regionProto.rect_size(); i++) {
75         Rect rect;
76         readFromProto(regionProto.rect(i), rect);
77         outRegion.orSelf(rect);
78     }
79 }
80 
writeToProto(const Rect & rect,std::function<RectProto * ()> getRectProto)81 void LayerProtoHelper::writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto) {
82     if (rect.left != 0 || rect.right != 0 || rect.top != 0 || rect.bottom != 0) {
83         // Use a lambda do avoid writing the object header when the object is empty
84         writeToProto(rect, getRectProto());
85     }
86 }
87 
writeToProto(const Rect & rect,RectProto * rectProto)88 void LayerProtoHelper::writeToProto(const Rect& rect, RectProto* rectProto) {
89     rectProto->set_left(rect.left);
90     rectProto->set_top(rect.top);
91     rectProto->set_bottom(rect.bottom);
92     rectProto->set_right(rect.right);
93 }
94 
readFromProto(const RectProto & proto,Rect & outRect)95 void LayerProtoHelper::readFromProto(const RectProto& proto, Rect& outRect) {
96     outRect.left = proto.left();
97     outRect.top = proto.top();
98     outRect.bottom = proto.bottom();
99     outRect.right = proto.right();
100 }
101 
writeToProto(const FloatRect & rect,std::function<FloatRectProto * ()> getFloatRectProto)102 void LayerProtoHelper::writeToProto(const FloatRect& rect,
103                                     std::function<FloatRectProto*()> getFloatRectProto) {
104     if (rect.left != 0 || rect.right != 0 || rect.top != 0 || rect.bottom != 0) {
105         // Use a lambda do avoid writing the object header when the object is empty
106         FloatRectProto* rectProto = getFloatRectProto();
107         rectProto->set_left(rect.left);
108         rectProto->set_top(rect.top);
109         rectProto->set_bottom(rect.bottom);
110         rectProto->set_right(rect.right);
111     }
112 }
113 
writeToProto(const half4 color,std::function<ColorProto * ()> getColorProto)114 void LayerProtoHelper::writeToProto(const half4 color, std::function<ColorProto*()> getColorProto) {
115     if (color.r != 0 || color.g != 0 || color.b != 0 || color.a != 0) {
116         // Use a lambda do avoid writing the object header when the object is empty
117         ColorProto* colorProto = getColorProto();
118         colorProto->set_r(color.r);
119         colorProto->set_g(color.g);
120         colorProto->set_b(color.b);
121         colorProto->set_a(color.a);
122     }
123 }
124 
writeToProtoDeprecated(const ui::Transform & transform,TransformProto * transformProto)125 void LayerProtoHelper::writeToProtoDeprecated(const ui::Transform& transform,
126                                               TransformProto* transformProto) {
127     const uint32_t type = transform.getType() | (transform.getOrientation() << 8);
128     transformProto->set_type(type);
129 
130     // Rotations that are 90/180/270 have their own type so the transform matrix can be
131     // reconstructed later. All other rotation have the type UKNOWN so we need to save the transform
132     // values in that case.
133     if (type & (ui::Transform::SCALE | ui::Transform::UNKNOWN)) {
134         transformProto->set_dsdx(transform[0][0]);
135         transformProto->set_dtdx(transform[0][1]);
136         transformProto->set_dsdy(transform[1][0]);
137         transformProto->set_dtdy(transform[1][1]);
138     }
139 }
140 
writeTransformToProto(const ui::Transform & transform,TransformProto * transformProto)141 void LayerProtoHelper::writeTransformToProto(const ui::Transform& transform,
142                                              TransformProto* transformProto) {
143     const uint32_t type = transform.getType() | (transform.getOrientation() << 8);
144     transformProto->set_type(type);
145 
146     // Rotations that are 90/180/270 have their own type so the transform matrix can be
147     // reconstructed later. All other rotation have the type UNKNOWN so we need to save the
148     // transform values in that case.
149     if (type & (ui::Transform::SCALE | ui::Transform::UNKNOWN)) {
150         transformProto->set_dsdx(transform.dsdx());
151         transformProto->set_dtdx(transform.dtdx());
152         transformProto->set_dtdy(transform.dtdy());
153         transformProto->set_dsdy(transform.dsdy());
154     }
155 }
156 
writeToProto(const renderengine::ExternalTexture & buffer,std::function<ActiveBufferProto * ()> getActiveBufferProto)157 void LayerProtoHelper::writeToProto(const renderengine::ExternalTexture& buffer,
158                                     std::function<ActiveBufferProto*()> getActiveBufferProto) {
159     if (buffer.getWidth() != 0 || buffer.getHeight() != 0 || buffer.getUsage() != 0 ||
160         buffer.getPixelFormat() != 0) {
161         // Use a lambda do avoid writing the object header when the object is empty
162         ActiveBufferProto* activeBufferProto = getActiveBufferProto();
163         activeBufferProto->set_width(buffer.getWidth());
164         activeBufferProto->set_height(buffer.getHeight());
165         activeBufferProto->set_stride(buffer.getUsage());
166         activeBufferProto->set_format(buffer.getPixelFormat());
167     }
168 }
169 
writeToProto(const WindowInfo & inputInfo,const wp<Layer> & touchableRegionBounds,std::function<InputWindowInfoProto * ()> getInputWindowInfoProto)170 void LayerProtoHelper::writeToProto(
171         const WindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
172         std::function<InputWindowInfoProto*()> getInputWindowInfoProto) {
173     if (inputInfo.token == nullptr) {
174         return;
175     }
176 
177     InputWindowInfoProto* proto = getInputWindowInfoProto();
178     proto->set_layout_params_flags(inputInfo.layoutParamsFlags.get());
179     using U = std::underlying_type_t<WindowInfo::Type>;
180     // TODO(b/129481165): This static assert can be safely removed once conversion warnings
181     // are re-enabled.
182     static_assert(std::is_same_v<U, int32_t>);
183     proto->set_layout_params_type(static_cast<U>(inputInfo.layoutParamsType));
184 
185     LayerProtoHelper::writeToProto({inputInfo.frameLeft, inputInfo.frameTop, inputInfo.frameRight,
186                                     inputInfo.frameBottom},
187                                    [&]() { return proto->mutable_frame(); });
188     LayerProtoHelper::writeToProto(inputInfo.touchableRegion,
189                                    [&]() { return proto->mutable_touchable_region(); });
190 
191     proto->set_surface_inset(inputInfo.surfaceInset);
192     using InputConfig = gui::WindowInfo::InputConfig;
193     proto->set_visible(!inputInfo.inputConfig.test(InputConfig::NOT_VISIBLE));
194     proto->set_focusable(!inputInfo.inputConfig.test(InputConfig::NOT_FOCUSABLE));
195     proto->set_has_wallpaper(inputInfo.inputConfig.test(InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
196 
197     proto->set_global_scale_factor(inputInfo.globalScaleFactor);
198     LayerProtoHelper::writeToProtoDeprecated(inputInfo.transform, proto->mutable_transform());
199     proto->set_replace_touchable_region_with_crop(inputInfo.replaceTouchableRegionWithCrop);
200     auto cropLayer = touchableRegionBounds.promote();
201     if (cropLayer != nullptr) {
202         proto->set_crop_layer_id(cropLayer->sequence);
203         LayerProtoHelper::writeToProto(cropLayer->getScreenBounds(
204                                                false /* reduceTransparentRegion */),
205                                        [&]() { return proto->mutable_touchable_region_crop(); });
206     }
207 }
208 
writeToProto(const mat4 matrix,ColorTransformProto * colorTransformProto)209 void LayerProtoHelper::writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto) {
210     for (int i = 0; i < mat4::ROW_SIZE; i++) {
211         for (int j = 0; j < mat4::COL_SIZE; j++) {
212             colorTransformProto->add_val(matrix[i][j]);
213         }
214     }
215 }
216 
readFromProto(const ColorTransformProto & colorTransformProto,mat4 & matrix)217 void LayerProtoHelper::readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix) {
218     for (int i = 0; i < mat4::ROW_SIZE; i++) {
219         for (int j = 0; j < mat4::COL_SIZE; j++) {
220             matrix[i][j] = colorTransformProto.val(i * mat4::COL_SIZE + j);
221         }
222     }
223 }
224 
writeToProto(const android::BlurRegion region,BlurRegion * proto)225 void LayerProtoHelper::writeToProto(const android::BlurRegion region, BlurRegion* proto) {
226     proto->set_blur_radius(region.blurRadius);
227     proto->set_corner_radius_tl(region.cornerRadiusTL);
228     proto->set_corner_radius_tr(region.cornerRadiusTR);
229     proto->set_corner_radius_bl(region.cornerRadiusBL);
230     proto->set_corner_radius_br(region.cornerRadiusBR);
231     proto->set_alpha(region.alpha);
232     proto->set_left(region.left);
233     proto->set_top(region.top);
234     proto->set_right(region.right);
235     proto->set_bottom(region.bottom);
236 }
237 
readFromProto(const BlurRegion & proto,android::BlurRegion & outRegion)238 void LayerProtoHelper::readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion) {
239     outRegion.blurRadius = proto.blur_radius();
240     outRegion.cornerRadiusTL = proto.corner_radius_tl();
241     outRegion.cornerRadiusTR = proto.corner_radius_tr();
242     outRegion.cornerRadiusBL = proto.corner_radius_bl();
243     outRegion.cornerRadiusBR = proto.corner_radius_br();
244     outRegion.alpha = proto.alpha();
245     outRegion.left = proto.left();
246     outRegion.top = proto.top();
247     outRegion.right = proto.right();
248     outRegion.bottom = proto.bottom();
249 }
250 } // namespace surfaceflinger
251 } // namespace android
252 
253 // TODO(b/129481165): remove the #pragma below and fix conversion issues
254 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
255