1 /*
2  * Copyright (C) 2021 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 #include <gui/SurfaceComposerClient.h>
18 #include <ui/Fence.h>
19 #include <ui/Rect.h>
20 
21 #include "FrontEnd/LayerCreationArgs.h"
22 #include "LayerProtoHelper.h"
23 #include "TransactionProtoParser.h"
24 #include "TransactionState.h"
25 #include "gui/LayerState.h"
26 
27 namespace android::surfaceflinger {
28 
29 class FakeExternalTexture : public renderengine::ExternalTexture {
30     const sp<GraphicBuffer> mEmptyBuffer = nullptr;
31     uint32_t mWidth;
32     uint32_t mHeight;
33     uint64_t mId;
34     PixelFormat mPixelFormat;
35     uint64_t mUsage;
36 
37 public:
FakeExternalTexture(uint32_t width,uint32_t height,uint64_t id,PixelFormat pixelFormat,uint64_t usage)38     FakeExternalTexture(uint32_t width, uint32_t height, uint64_t id, PixelFormat pixelFormat,
39                         uint64_t usage)
40           : mWidth(width), mHeight(height), mId(id), mPixelFormat(pixelFormat), mUsage(usage) {}
getBuffer() const41     const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
hasSameBuffer(const renderengine::ExternalTexture & other) const42     bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
43         return getId() == other.getId();
44     }
getWidth() const45     uint32_t getWidth() const override { return mWidth; }
getHeight() const46     uint32_t getHeight() const override { return mHeight; }
getId() const47     uint64_t getId() const override { return mId; }
getPixelFormat() const48     PixelFormat getPixelFormat() const override { return mPixelFormat; }
getUsage() const49     uint64_t getUsage() const override { return mUsage; }
remapBuffer()50     void remapBuffer() override {}
51     ~FakeExternalTexture() = default;
52 };
53 
toProto(const TransactionState & t)54 perfetto::protos::TransactionState TransactionProtoParser::toProto(const TransactionState& t) {
55     perfetto::protos::TransactionState proto;
56     proto.set_pid(t.originPid);
57     proto.set_uid(t.originUid);
58     proto.set_vsync_id(t.frameTimelineInfo.vsyncId);
59     proto.set_input_event_id(t.frameTimelineInfo.inputEventId);
60     proto.set_post_time(t.postTime);
61     proto.set_transaction_id(t.id);
62 
63     proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(t.states.size()));
64     for (auto& layerState : t.states) {
65         proto.mutable_layer_changes()->Add(std::move(toProto(layerState)));
66     }
67 
68     proto.mutable_display_changes()->Reserve(static_cast<int32_t>(t.displays.size()));
69     for (auto& displayState : t.displays) {
70         proto.mutable_display_changes()->Add(std::move(toProto(displayState)));
71     }
72 
73     proto.mutable_merged_transaction_ids()->Reserve(
74             static_cast<int32_t>(t.mergedTransactionIds.size()));
75     for (auto& mergedTransactionId : t.mergedTransactionIds) {
76         proto.mutable_merged_transaction_ids()->Add(mergedTransactionId);
77     }
78 
79     return proto;
80 }
81 
toProto(const std::map<uint32_t,TracingLayerState> & states)82 perfetto::protos::TransactionState TransactionProtoParser::toProto(
83         const std::map<uint32_t /* layerId */, TracingLayerState>& states) {
84     perfetto::protos::TransactionState proto;
85     proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(states.size()));
86     for (auto& [layerId, state] : states) {
87         perfetto::protos::LayerState layerProto = toProto(state);
88         layerProto.set_has_sideband_stream(state.hasSidebandStream);
89         proto.mutable_layer_changes()->Add(std::move(layerProto));
90     }
91     return proto;
92 }
93 
toProto(const ResolvedComposerState & resolvedComposerState)94 perfetto::protos::LayerState TransactionProtoParser::toProto(
95         const ResolvedComposerState& resolvedComposerState) {
96     perfetto::protos::LayerState proto;
97     auto& layer = resolvedComposerState.state;
98     proto.set_layer_id(resolvedComposerState.layerId);
99     proto.set_what(layer.what);
100 
101     if (layer.what & layer_state_t::ePositionChanged) {
102         proto.set_x(layer.x);
103         proto.set_y(layer.y);
104     }
105     if (layer.what & layer_state_t::eLayerChanged) {
106         proto.set_z(layer.z);
107     }
108 
109     if (layer.what & layer_state_t::eLayerStackChanged) {
110         proto.set_layer_stack(layer.layerStack.id);
111     }
112     if (layer.what & layer_state_t::eFlagsChanged) {
113         proto.set_flags(layer.flags);
114         proto.set_mask(layer.mask);
115     }
116     if (layer.what & layer_state_t::eMatrixChanged) {
117         perfetto::protos::LayerState_Matrix22* matrixProto = proto.mutable_matrix();
118         matrixProto->set_dsdx(layer.matrix.dsdx);
119         matrixProto->set_dsdy(layer.matrix.dsdy);
120         matrixProto->set_dtdx(layer.matrix.dtdx);
121         matrixProto->set_dtdy(layer.matrix.dtdy);
122     }
123     if (layer.what & layer_state_t::eCornerRadiusChanged) {
124         proto.set_corner_radius(layer.cornerRadius);
125     }
126     if (layer.what & layer_state_t::eBackgroundBlurRadiusChanged) {
127         proto.set_background_blur_radius(layer.backgroundBlurRadius);
128     }
129 
130     if (layer.what & layer_state_t::eAlphaChanged) {
131         proto.set_alpha(layer.color.a);
132     }
133 
134     if (layer.what & layer_state_t::eColorChanged) {
135         perfetto::protos::LayerState_Color3* colorProto = proto.mutable_color();
136         colorProto->set_r(layer.color.r);
137         colorProto->set_g(layer.color.g);
138         colorProto->set_b(layer.color.b);
139     }
140     if (layer.what & layer_state_t::eTransparentRegionChanged) {
141         LayerProtoHelper::writeToProto(layer.transparentRegion, proto.mutable_transparent_region());
142     }
143     if (layer.what & layer_state_t::eBufferTransformChanged) {
144         proto.set_transform(layer.bufferTransform);
145     }
146     if (layer.what & layer_state_t::eTransformToDisplayInverseChanged) {
147         proto.set_transform_to_display_inverse(layer.transformToDisplayInverse);
148     }
149     if (layer.what & layer_state_t::eCropChanged) {
150         LayerProtoHelper::writeToProto(layer.crop, proto.mutable_crop());
151     }
152     if (layer.what & layer_state_t::eBufferChanged) {
153         perfetto::protos::LayerState_BufferData* bufferProto = proto.mutable_buffer_data();
154         if (resolvedComposerState.externalTexture) {
155             bufferProto->set_buffer_id(resolvedComposerState.externalTexture->getId());
156             bufferProto->set_width(resolvedComposerState.externalTexture->getWidth());
157             bufferProto->set_height(resolvedComposerState.externalTexture->getHeight());
158             bufferProto->set_pixel_format(
159                     static_cast<perfetto::protos::LayerState_BufferData_PixelFormat>(
160                             resolvedComposerState.externalTexture->getPixelFormat()));
161             bufferProto->set_usage(resolvedComposerState.externalTexture->getUsage());
162         }
163         bufferProto->set_frame_number(layer.bufferData->frameNumber);
164         bufferProto->set_flags(layer.bufferData->flags.get());
165         bufferProto->set_cached_buffer_id(layer.bufferData->cachedBuffer.id);
166     }
167     if (layer.what & layer_state_t::eSidebandStreamChanged) {
168         proto.set_has_sideband_stream(layer.sidebandStream != nullptr);
169     }
170 
171     if (layer.what & layer_state_t::eApiChanged) {
172         proto.set_api(layer.api);
173     }
174 
175     if (layer.what & layer_state_t::eColorTransformChanged) {
176         LayerProtoHelper::writeToProto(layer.colorTransform, proto.mutable_color_transform());
177     }
178     if (layer.what & layer_state_t::eBlurRegionsChanged) {
179         for (auto& region : layer.blurRegions) {
180             LayerProtoHelper::writeToProto(region, proto.add_blur_regions());
181         }
182     }
183 
184     if (layer.what & layer_state_t::eReparent) {
185         proto.set_parent_id(resolvedComposerState.parentId);
186     }
187     if (layer.what & layer_state_t::eRelativeLayerChanged) {
188         proto.set_relative_parent_id(resolvedComposerState.relativeParentId);
189         proto.set_z(layer.z);
190     }
191 
192     if (layer.what & layer_state_t::eInputInfoChanged) {
193         if (layer.windowInfoHandle) {
194             const gui::WindowInfo* inputInfo = layer.windowInfoHandle->getInfo();
195             perfetto::protos::LayerState_WindowInfo* windowInfoProto =
196                     proto.mutable_window_info_handle();
197             windowInfoProto->set_layout_params_flags(inputInfo->layoutParamsFlags.get());
198             windowInfoProto->set_layout_params_type(
199                     static_cast<int32_t>(inputInfo->layoutParamsType));
200             windowInfoProto->set_input_config(inputInfo->inputConfig.get());
201             LayerProtoHelper::writeToProto(inputInfo->touchableRegion,
202                                            windowInfoProto->mutable_touchable_region());
203             windowInfoProto->set_surface_inset(inputInfo->surfaceInset);
204             windowInfoProto->set_focusable(
205                     !inputInfo->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE));
206             windowInfoProto->set_has_wallpaper(inputInfo->inputConfig.test(
207                     gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
208             windowInfoProto->set_global_scale_factor(inputInfo->globalScaleFactor);
209             perfetto::protos::Transform* transformProto = windowInfoProto->mutable_transform();
210             transformProto->set_dsdx(inputInfo->transform.dsdx());
211             transformProto->set_dtdx(inputInfo->transform.dtdx());
212             transformProto->set_dtdy(inputInfo->transform.dtdy());
213             transformProto->set_dsdy(inputInfo->transform.dsdy());
214             transformProto->set_tx(inputInfo->transform.tx());
215             transformProto->set_ty(inputInfo->transform.ty());
216             windowInfoProto->set_replace_touchable_region_with_crop(
217                     inputInfo->replaceTouchableRegionWithCrop);
218             windowInfoProto->set_crop_layer_id(resolvedComposerState.touchCropId);
219         }
220     }
221     if (layer.what & layer_state_t::eBackgroundColorChanged) {
222         proto.set_bg_color_alpha(layer.bgColor.a);
223         proto.set_bg_color_dataspace(static_cast<int32_t>(layer.bgColorDataspace));
224         perfetto::protos::LayerState_Color3* colorProto = proto.mutable_color();
225         colorProto->set_r(layer.bgColor.r);
226         colorProto->set_g(layer.bgColor.g);
227         colorProto->set_b(layer.bgColor.b);
228     }
229     if (layer.what & layer_state_t::eColorSpaceAgnosticChanged) {
230         proto.set_color_space_agnostic(layer.colorSpaceAgnostic);
231     }
232     if (layer.what & layer_state_t::eShadowRadiusChanged) {
233         proto.set_shadow_radius(layer.shadowRadius);
234     }
235     if (layer.what & layer_state_t::eFrameRateSelectionPriority) {
236         proto.set_frame_rate_selection_priority(layer.frameRateSelectionPriority);
237     }
238     if (layer.what & layer_state_t::eFrameRateChanged) {
239         proto.set_frame_rate(layer.frameRate);
240         proto.set_frame_rate_compatibility(layer.frameRateCompatibility);
241         proto.set_change_frame_rate_strategy(layer.changeFrameRateStrategy);
242     }
243     if (layer.what & layer_state_t::eFixedTransformHintChanged) {
244         proto.set_fixed_transform_hint(layer.fixedTransformHint);
245     }
246     if (layer.what & layer_state_t::eAutoRefreshChanged) {
247         proto.set_auto_refresh(layer.autoRefresh);
248     }
249     if (layer.what & layer_state_t::eTrustedOverlayChanged) {
250         proto.set_is_trusted_overlay(layer.trustedOverlay == gui::TrustedOverlay::ENABLED);
251         // TODO(b/339701674) update protos
252     }
253     if (layer.what & layer_state_t::eBufferCropChanged) {
254         LayerProtoHelper::writeToProto(layer.bufferCrop, proto.mutable_buffer_crop());
255     }
256     if (layer.what & layer_state_t::eDestinationFrameChanged) {
257         LayerProtoHelper::writeToProto(layer.destinationFrame, proto.mutable_destination_frame());
258     }
259     if (layer.what & layer_state_t::eDropInputModeChanged) {
260         proto.set_drop_input_mode(
261                 static_cast<perfetto::protos::LayerState_DropInputMode>(layer.dropInputMode));
262     }
263     return proto;
264 }
265 
toProto(const DisplayState & display)266 perfetto::protos::DisplayState TransactionProtoParser::toProto(const DisplayState& display) {
267     perfetto::protos::DisplayState proto;
268     proto.set_what(display.what);
269     proto.set_id(mMapper->getDisplayId(display.token));
270 
271     if (display.what & DisplayState::eLayerStackChanged) {
272         proto.set_layer_stack(display.layerStack.id);
273     }
274     if (display.what & DisplayState::eDisplayProjectionChanged) {
275         proto.set_orientation(static_cast<uint32_t>(display.orientation));
276         LayerProtoHelper::writeToProto(display.orientedDisplaySpaceRect,
277                                        proto.mutable_oriented_display_space_rect());
278         LayerProtoHelper::writeToProto(display.layerStackSpaceRect,
279                                        proto.mutable_layer_stack_space_rect());
280     }
281     if (display.what & DisplayState::eDisplaySizeChanged) {
282         proto.set_width(display.width);
283         proto.set_height(display.height);
284     }
285     if (display.what & DisplayState::eFlagsChanged) {
286         proto.set_flags(display.flags);
287     }
288     return proto;
289 }
290 
toProto(const LayerCreationArgs & args)291 perfetto::protos::LayerCreationArgs TransactionProtoParser::toProto(const LayerCreationArgs& args) {
292     perfetto::protos::LayerCreationArgs proto;
293     proto.set_layer_id(args.sequence);
294     proto.set_name(args.name);
295     proto.set_flags(args.flags);
296     proto.set_parent_id(args.parentId);
297     proto.set_mirror_from_id(args.layerIdToMirror);
298     proto.set_add_to_root(args.addToRoot);
299     proto.set_layer_stack_to_mirror(args.layerStackToMirror.id);
300     return proto;
301 }
302 
fromProto(const perfetto::protos::TransactionState & proto)303 TransactionState TransactionProtoParser::fromProto(
304         const perfetto::protos::TransactionState& proto) {
305     TransactionState t;
306     t.originPid = proto.pid();
307     t.originUid = proto.uid();
308     t.frameTimelineInfo.vsyncId = proto.vsync_id();
309     t.frameTimelineInfo.inputEventId = proto.input_event_id();
310     t.postTime = proto.post_time();
311     t.id = proto.transaction_id();
312 
313     int32_t layerCount = proto.layer_changes_size();
314     t.states.reserve(static_cast<size_t>(layerCount));
315     for (int i = 0; i < layerCount; i++) {
316         ResolvedComposerState s;
317         s.state.what = 0;
318         fromProto(proto.layer_changes(i), s);
319         t.states.emplace_back(s);
320     }
321 
322     int32_t displayCount = proto.display_changes_size();
323     t.displays.reserve(static_cast<size_t>(displayCount));
324     for (int i = 0; i < displayCount; i++) {
325         t.displays.add(fromProto(proto.display_changes(i)));
326     }
327     return t;
328 }
329 
fromProto(const perfetto::protos::LayerCreationArgs & proto,LayerCreationArgs & outArgs)330 void TransactionProtoParser::fromProto(const perfetto::protos::LayerCreationArgs& proto,
331                                        LayerCreationArgs& outArgs) {
332     outArgs.sequence = proto.layer_id();
333 
334     outArgs.name = proto.name();
335     outArgs.flags = proto.flags();
336     outArgs.parentId = proto.parent_id();
337     outArgs.layerIdToMirror = proto.mirror_from_id();
338     outArgs.addToRoot = proto.add_to_root();
339     outArgs.layerStackToMirror.id = proto.layer_stack_to_mirror();
340 }
341 
mergeFromProto(const perfetto::protos::LayerState & proto,TracingLayerState & outState)342 void TransactionProtoParser::mergeFromProto(const perfetto::protos::LayerState& proto,
343                                             TracingLayerState& outState) {
344     ResolvedComposerState resolvedComposerState;
345     fromProto(proto, resolvedComposerState);
346     layer_state_t& state = resolvedComposerState.state;
347     outState.state.merge(state);
348     outState.layerId = resolvedComposerState.layerId;
349 
350     if (state.what & layer_state_t::eReparent) {
351         outState.parentId = resolvedComposerState.parentId;
352     }
353     if (state.what & layer_state_t::eRelativeLayerChanged) {
354         outState.relativeParentId = resolvedComposerState.relativeParentId;
355     }
356     if (state.what & layer_state_t::eInputInfoChanged) {
357         outState.touchCropId = resolvedComposerState.touchCropId;
358     }
359     if (state.what & layer_state_t::eBufferChanged) {
360         outState.externalTexture = resolvedComposerState.externalTexture;
361     }
362     if (state.what & layer_state_t::eSidebandStreamChanged) {
363         outState.hasSidebandStream = proto.has_sideband_stream();
364     }
365 }
366 
fromProto(const perfetto::protos::LayerState & proto,ResolvedComposerState & resolvedComposerState)367 void TransactionProtoParser::fromProto(const perfetto::protos::LayerState& proto,
368                                        ResolvedComposerState& resolvedComposerState) {
369     auto& layer = resolvedComposerState.state;
370     resolvedComposerState.layerId = proto.layer_id();
371     layer.what |= proto.what();
372 
373     if (proto.what() & layer_state_t::ePositionChanged) {
374         layer.x = proto.x();
375         layer.y = proto.y();
376     }
377     if (proto.what() & layer_state_t::eLayerChanged) {
378         layer.z = proto.z();
379     }
380     if (proto.what() & layer_state_t::eLayerStackChanged) {
381         layer.layerStack.id = proto.layer_stack();
382     }
383     if (proto.what() & layer_state_t::eFlagsChanged) {
384         layer.flags = proto.flags();
385         layer.mask = proto.mask();
386     }
387     if (proto.what() & layer_state_t::eMatrixChanged) {
388         const perfetto::protos::LayerState_Matrix22& matrixProto = proto.matrix();
389         layer.matrix.dsdx = matrixProto.dsdx();
390         layer.matrix.dsdy = matrixProto.dsdy();
391         layer.matrix.dtdx = matrixProto.dtdx();
392         layer.matrix.dtdy = matrixProto.dtdy();
393     }
394     if (proto.what() & layer_state_t::eCornerRadiusChanged) {
395         layer.cornerRadius = proto.corner_radius();
396     }
397     if (proto.what() & layer_state_t::eBackgroundBlurRadiusChanged) {
398         layer.backgroundBlurRadius = proto.background_blur_radius();
399     }
400 
401     if (proto.what() & layer_state_t::eAlphaChanged) {
402         layer.color.a = proto.alpha();
403     }
404 
405     if (proto.what() & layer_state_t::eColorChanged) {
406         const perfetto::protos::LayerState_Color3& colorProto = proto.color();
407         layer.color.r = colorProto.r();
408         layer.color.g = colorProto.g();
409         layer.color.b = colorProto.b();
410     }
411     if (proto.what() & layer_state_t::eTransparentRegionChanged) {
412         LayerProtoHelper::readFromProto(proto.transparent_region(), layer.transparentRegion);
413     }
414     if (proto.what() & layer_state_t::eBufferTransformChanged) {
415         layer.bufferTransform = proto.transform();
416     }
417     if (proto.what() & layer_state_t::eTransformToDisplayInverseChanged) {
418         layer.transformToDisplayInverse = proto.transform_to_display_inverse();
419     }
420     if (proto.what() & layer_state_t::eCropChanged) {
421         LayerProtoHelper::readFromProto(proto.crop(), layer.crop);
422     }
423     if (proto.what() & layer_state_t::eBufferChanged) {
424         const perfetto::protos::LayerState_BufferData& bufferProto = proto.buffer_data();
425         layer.bufferData =
426                 std::make_shared<fake::BufferData>(bufferProto.buffer_id(), bufferProto.width(),
427                                                    bufferProto.height(), bufferProto.pixel_format(),
428                                                    bufferProto.usage());
429         resolvedComposerState.externalTexture =
430                 std::make_shared<FakeExternalTexture>(layer.bufferData->getWidth(),
431                                                       layer.bufferData->getHeight(),
432                                                       layer.bufferData->getId(),
433                                                       layer.bufferData->getPixelFormat(),
434                                                       layer.bufferData->getUsage());
435         layer.bufferData->frameNumber = bufferProto.frame_number();
436         layer.bufferData->flags = ftl::Flags<BufferData::BufferDataChange>(bufferProto.flags());
437         layer.bufferData->cachedBuffer.id = bufferProto.cached_buffer_id();
438         layer.bufferData->acquireFence = Fence::NO_FENCE;
439         layer.bufferData->dequeueTime = -1;
440     }
441 
442     if (proto.what() & layer_state_t::eApiChanged) {
443         layer.api = proto.api();
444     }
445 
446     if (proto.what() & layer_state_t::eColorTransformChanged) {
447         LayerProtoHelper::readFromProto(proto.color_transform(), layer.colorTransform);
448     }
449     if (proto.what() & layer_state_t::eBlurRegionsChanged) {
450         layer.blurRegions.reserve(static_cast<size_t>(proto.blur_regions_size()));
451         for (int i = 0; i < proto.blur_regions_size(); i++) {
452             android::BlurRegion region;
453             LayerProtoHelper::readFromProto(proto.blur_regions(i), region);
454             layer.blurRegions.push_back(region);
455         }
456     }
457 
458     if (proto.what() & layer_state_t::eReparent) {
459         resolvedComposerState.parentId = proto.parent_id();
460     }
461     if (proto.what() & layer_state_t::eRelativeLayerChanged) {
462         resolvedComposerState.relativeParentId = proto.relative_parent_id();
463         layer.z = proto.z();
464     }
465 
466     if ((proto.what() & layer_state_t::eInputInfoChanged) && proto.has_window_info_handle()) {
467         gui::WindowInfo inputInfo;
468         const perfetto::protos::LayerState_WindowInfo& windowInfoProto = proto.window_info_handle();
469 
470         inputInfo.layoutParamsFlags =
471                 static_cast<gui::WindowInfo::Flag>(windowInfoProto.layout_params_flags());
472         inputInfo.layoutParamsType =
473                 static_cast<gui::WindowInfo::Type>(windowInfoProto.layout_params_type());
474         LayerProtoHelper::readFromProto(windowInfoProto.touchable_region(),
475                                         inputInfo.touchableRegion);
476         inputInfo.inputConfig =
477                 ftl::Flags<gui::WindowInfo::InputConfig>(windowInfoProto.input_config());
478         inputInfo.surfaceInset = windowInfoProto.surface_inset();
479         inputInfo.globalScaleFactor = windowInfoProto.global_scale_factor();
480         const perfetto::protos::Transform& transformProto = windowInfoProto.transform();
481         inputInfo.transform.set(transformProto.dsdx(), transformProto.dtdx(), transformProto.dtdy(),
482                                 transformProto.dsdy());
483         inputInfo.transform.set(transformProto.tx(), transformProto.ty());
484         inputInfo.replaceTouchableRegionWithCrop =
485                 windowInfoProto.replace_touchable_region_with_crop();
486         resolvedComposerState.touchCropId = windowInfoProto.crop_layer_id();
487 
488         layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo);
489     }
490     if (proto.what() & layer_state_t::eBackgroundColorChanged) {
491         layer.bgColor.a = proto.bg_color_alpha();
492         layer.bgColorDataspace = static_cast<ui::Dataspace>(proto.bg_color_dataspace());
493         const perfetto::protos::LayerState_Color3& colorProto = proto.color();
494         layer.bgColor.r = colorProto.r();
495         layer.bgColor.g = colorProto.g();
496         layer.bgColor.b = colorProto.b();
497     }
498     if (proto.what() & layer_state_t::eColorSpaceAgnosticChanged) {
499         layer.colorSpaceAgnostic = proto.color_space_agnostic();
500     }
501     if (proto.what() & layer_state_t::eShadowRadiusChanged) {
502         layer.shadowRadius = proto.shadow_radius();
503     }
504     if (proto.what() & layer_state_t::eFrameRateSelectionPriority) {
505         layer.frameRateSelectionPriority = proto.frame_rate_selection_priority();
506     }
507     if (proto.what() & layer_state_t::eFrameRateChanged) {
508         layer.frameRate = proto.frame_rate();
509         layer.frameRateCompatibility = static_cast<int8_t>(proto.frame_rate_compatibility());
510         layer.changeFrameRateStrategy = static_cast<int8_t>(proto.change_frame_rate_strategy());
511     }
512     if (proto.what() & layer_state_t::eFixedTransformHintChanged) {
513         layer.fixedTransformHint =
514                 static_cast<ui::Transform::RotationFlags>(proto.fixed_transform_hint());
515     }
516     if (proto.what() & layer_state_t::eAutoRefreshChanged) {
517         layer.autoRefresh = proto.auto_refresh();
518     }
519     if (proto.what() & layer_state_t::eTrustedOverlayChanged) {
520         layer.trustedOverlay = proto.is_trusted_overlay() ? gui::TrustedOverlay::ENABLED
521                                                           : gui::TrustedOverlay::UNSET;
522     }
523     if (proto.what() & layer_state_t::eBufferCropChanged) {
524         LayerProtoHelper::readFromProto(proto.buffer_crop(), layer.bufferCrop);
525     }
526     if (proto.what() & layer_state_t::eDestinationFrameChanged) {
527         LayerProtoHelper::readFromProto(proto.destination_frame(), layer.destinationFrame);
528     }
529     if (proto.what() & layer_state_t::eDropInputModeChanged) {
530         layer.dropInputMode = static_cast<gui::DropInputMode>(proto.drop_input_mode());
531     }
532 }
533 
fromProto(const perfetto::protos::DisplayState & proto)534 DisplayState TransactionProtoParser::fromProto(const perfetto::protos::DisplayState& proto) {
535     DisplayState display;
536     display.what = proto.what();
537     display.token = mMapper->getDisplayHandle(proto.id());
538 
539     if (display.what & DisplayState::eLayerStackChanged) {
540         display.layerStack.id = proto.layer_stack();
541     }
542     if (display.what & DisplayState::eDisplayProjectionChanged) {
543         display.orientation = static_cast<ui::Rotation>(proto.orientation());
544         LayerProtoHelper::readFromProto(proto.oriented_display_space_rect(),
545                                         display.orientedDisplaySpaceRect);
546         LayerProtoHelper::readFromProto(proto.layer_stack_space_rect(),
547                                         display.layerStackSpaceRect);
548     }
549     if (display.what & DisplayState::eDisplaySizeChanged) {
550         display.width = proto.width();
551         display.height = proto.height();
552     }
553     if (display.what & DisplayState::eFlagsChanged) {
554         display.flags = proto.flags();
555     }
556     return display;
557 }
558 
asProto(perfetto::protos::Transform * proto,const ui::Transform & transform)559 void asProto(perfetto::protos::Transform* proto, const ui::Transform& transform) {
560     proto->set_dsdx(transform.dsdx());
561     proto->set_dtdx(transform.dtdx());
562     proto->set_dtdy(transform.dtdy());
563     proto->set_dsdy(transform.dsdy());
564     proto->set_tx(transform.tx());
565     proto->set_ty(transform.ty());
566 }
567 
toProto(const frontend::DisplayInfo & displayInfo,uint32_t layerStack)568 perfetto::protos::DisplayInfo TransactionProtoParser::toProto(
569         const frontend::DisplayInfo& displayInfo, uint32_t layerStack) {
570     perfetto::protos::DisplayInfo proto;
571     proto.set_layer_stack(layerStack);
572     proto.set_display_id(displayInfo.info.displayId.val());
573     proto.set_logical_width(displayInfo.info.logicalWidth);
574     proto.set_logical_height(displayInfo.info.logicalHeight);
575     asProto(proto.mutable_transform_inverse(), displayInfo.info.transform);
576     asProto(proto.mutable_transform(), displayInfo.transform);
577     proto.set_receives_input(displayInfo.receivesInput);
578     proto.set_is_secure(displayInfo.isSecure);
579     proto.set_is_primary(displayInfo.isPrimary);
580     proto.set_is_virtual(displayInfo.isVirtual);
581     proto.set_rotation_flags((int)displayInfo.rotationFlags);
582     proto.set_transform_hint((int)displayInfo.transformHint);
583     return proto;
584 }
585 
fromProto2(ui::Transform & outTransform,const perfetto::protos::Transform & proto)586 void fromProto2(ui::Transform& outTransform, const perfetto::protos::Transform& proto) {
587     outTransform.set(proto.dsdx(), proto.dtdx(), proto.dtdy(), proto.dsdy());
588     outTransform.set(proto.tx(), proto.ty());
589 }
590 
fromProto(const perfetto::protos::DisplayInfo & proto)591 frontend::DisplayInfo TransactionProtoParser::fromProto(
592         const perfetto::protos::DisplayInfo& proto) {
593     frontend::DisplayInfo displayInfo;
594     displayInfo.info.displayId = ui::LogicalDisplayId{proto.display_id()};
595     displayInfo.info.logicalWidth = proto.logical_width();
596     displayInfo.info.logicalHeight = proto.logical_height();
597     fromProto2(displayInfo.info.transform, proto.transform_inverse());
598     fromProto2(displayInfo.transform, proto.transform());
599     displayInfo.receivesInput = proto.receives_input();
600     displayInfo.isSecure = proto.is_secure();
601     displayInfo.isPrimary = proto.is_primary();
602     displayInfo.isVirtual = proto.is_virtual();
603     displayInfo.rotationFlags = (ui::Transform::RotationFlags)proto.rotation_flags();
604     displayInfo.transformHint = (ui::Transform::RotationFlags)proto.transform_hint();
605     return displayInfo;
606 }
607 
fromProto(const google::protobuf::RepeatedPtrField<perfetto::protos::DisplayInfo> & proto,frontend::DisplayInfos & outDisplayInfos)608 void TransactionProtoParser::fromProto(
609         const google::protobuf::RepeatedPtrField<perfetto::protos::DisplayInfo>& proto,
610         frontend::DisplayInfos& outDisplayInfos) {
611     outDisplayInfos.clear();
612     for (const perfetto::protos::DisplayInfo& displayInfo : proto) {
613         outDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(displayInfo.layer_stack()),
614                                            fromProto(displayInfo));
615     }
616 }
617 
618 } // namespace android::surfaceflinger
619