1 /* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ROSEN_RENDER_SERVICE_BASE_COMMAND_RS_COMMAND_TEMPLATES_H 17 #define ROSEN_RENDER_SERVICE_BASE_COMMAND_RS_COMMAND_TEMPLATES_H 18 19 #include <cinttypes> 20 #include "command/rs_command.h" 21 #include "command/rs_command_factory.h" 22 #include "transaction/rs_marshalling_helper.h" 23 24 namespace OHOS { 25 namespace Rosen { 26 class RSUIDirector; 27 28 // avoiding C++ macros spliting parameters 29 #ifndef ARG 30 #define ARG(...) __VA_ARGS__ 31 #endif 32 33 // Add new RSCommand as alias of template class 34 // Explicit instantiating templates will register the unmarshalling function into RSCommandFactory. 35 // To avoid redundant registry, make sure templates only instantiated once. 36 #ifdef ROSEN_INSTANTIATE_COMMAND_TEMPLATE 37 #define ADD_COMMAND(ALIAS, TYPE) \ 38 using ALIAS = RSCommandTemplate<TYPE>; \ 39 template class RSCommandTemplate<TYPE>; 40 #else 41 #define ADD_COMMAND(ALIAS, TYPE) using ALIAS = RSCommandTemplate<TYPE>; 42 #endif 43 44 template<uint16_t commandType, uint16_t commandSubType, auto processFunc, typename... Params> 45 class RSCommandTemplate : public RSCommand { 46 public: RSCommandTemplate(const Params &...params)47 RSCommandTemplate(const Params&... params) : params_(params...) {} RSCommandTemplate(std::tuple<Params...> && params)48 RSCommandTemplate(std::tuple<Params...>&& params) : params_(std::move(params)) {} 49 ~RSCommandTemplate() override = default; 50 GetType()51 uint16_t GetType() const override 52 { 53 return commandType; 54 } GetSubType()55 uint16_t GetSubType() const override 56 { 57 return commandSubType; 58 } 59 GetDrawCmdList()60 std::shared_ptr<Drawing::DrawCmdList> GetDrawCmdList() const override 61 { 62 if constexpr (std::tuple_size<decltype(params_)>::value > 1) { 63 using ptrType = typename std::tuple_element<1, decltype(params_)>::type; 64 if constexpr (std::is_same<std::shared_ptr<Drawing::DrawCmdList>, ptrType>::value) { 65 return std::get<1>(params_); 66 } else if constexpr (std::is_same<std::shared_ptr<RSRenderModifier>, ptrType>::value) { 67 auto& modifier = std::get<1>(params_); 68 if (modifier) { 69 return modifier->GetPropertyDrawCmdList(); 70 } 71 } 72 } 73 return nullptr; 74 } 75 GetNodeId()76 NodeId GetNodeId() const override 77 { 78 using idType = typename std::tuple_element<0, decltype(params_)>::type; 79 if (std::is_same<NodeId, idType>::value) { 80 return std::get<0>(params_); 81 } 82 return 0; // invalidId 83 } 84 Process(RSContext & context)85 void Process(RSContext& context) override 86 { 87 // expand the tuple to function parameters 88 std::apply([&context](auto&... args) { return (*processFunc)(context, args...); }, params_); 89 } 90 Marshalling(Parcel & parcel)91 bool Marshalling(Parcel& parcel) const override 92 { 93 return RSMarshallingHelper::Marshalling(parcel, commandType) && 94 RSMarshallingHelper::Marshalling(parcel, commandSubType) && 95 std::apply([&parcel](const auto&... args) { return RSMarshallingHelper::Marshalling(parcel, args...); }, 96 params_); 97 }; 98 Unmarshalling(Parcel & parcel)99 [[nodiscard]] static RSCommand* Unmarshalling(Parcel& parcel) 100 { 101 std::tuple<Params...> params; 102 if (!std::apply( 103 [&parcel](auto&... args) { return RSMarshallingHelper::Unmarshalling(parcel, args...); }, params)) { 104 return nullptr; 105 } 106 return new RSCommandTemplate(std::move(params)); 107 } 108 109 static inline RSCommandRegister<commandType, commandSubType, Unmarshalling> registry; 110 111 private: 112 std::tuple<Params...> params_; 113 114 #ifdef RS_PROFILER_ENABLED Patch(PatchFunction function)115 void Patch(PatchFunction function) override 116 { 117 PatchParameters(function, params_, std::make_index_sequence<std::tuple_size_v<decltype(params_)>> {}); 118 } 119 120 template<typename T, std::size_t... Index> PatchParameters(PatchFunction function,T & params,std::index_sequence<Index...>)121 static void PatchParameters(PatchFunction function, T& params, std::index_sequence<Index...>) 122 { 123 (PatchParameter(function, std::get<Index>(params)), ...); 124 } 125 126 template<typename T> PatchParameter(PatchFunction function,T & value)127 static void PatchParameter(PatchFunction function, T& value) 128 { 129 if (std::is_same<NodeId, T>::value || std::is_same<AnimationId, T>::value || 130 std::is_same<PropertyId, T>::value) { 131 auto& id = reinterpret_cast<NodeId&>(value); 132 id = function(id); 133 } 134 } 135 #endif 136 }; 137 } // namespace Rosen 138 } // namespace OHOS 139 140 #endif // ROSEN_RENDER_SERVICE_BASE_COMMAND_RS_COMMAND_TEMPLATES_H 141