1 /* 2 * Copyright (c) 2022-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 RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_EXTENDED_MODIFIER_H 17 #define RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_EXTENDED_MODIFIER_H 18 19 #include "command/rs_node_command.h" 20 #include "common/rs_common_def.h" 21 #include "common/rs_macros.h" 22 #include "modifier/rs_modifier.h" 23 #include "pipeline/rs_draw_cmd_list.h" 24 #include "transaction/rs_transaction_proxy.h" 25 #include "ui/rs_canvas_node.h" 26 27 28 namespace OHOS { 29 namespace Rosen { 30 struct RSDrawingContext { 31 Drawing::Canvas* canvas; 32 float width; 33 float height; 34 }; 35 36 class RSC_EXPORT RSExtendedModifierHelper { 37 public: 38 static RSDrawingContext CreateDrawingContext(std::weak_ptr<RSCanvasNode> canvasnode); 39 static std::shared_ptr<RSRenderModifier> CreateRenderModifier( 40 RSDrawingContext& ctx, PropertyId id, RSModifierType type); 41 static std::shared_ptr<Drawing::DrawCmdList> FinishDrawing(RSDrawingContext& ctx); 42 }; 43 44 class RSC_EXPORT RSExtendedModifier : public RSModifier { 45 public: 46 RSExtendedModifier(const std::shared_ptr<RSPropertyBase>& property = {}) RSModifier(property,RSModifierType::EXTENDED)47 : RSModifier(property, RSModifierType::EXTENDED) 48 { 49 property_->SetIsCustom(true); 50 } 51 virtual ~RSExtendedModifier() = default; 52 GetModifierType()53 RSModifierType GetModifierType() const override 54 { 55 return RSModifierType::EXTENDED; 56 } 57 virtual void Draw(RSDrawingContext& context) const = 0; 58 SetNoNeedUICaptured(bool noNeedUICaptured)59 void SetNoNeedUICaptured(bool noNeedUICaptured) 60 { 61 noNeedUICaptured_ = noNeedUICaptured; 62 } 63 64 protected: 65 explicit RSExtendedModifier(const RSModifierType type, const std::shared_ptr<RSPropertyBase>& property = {}) RSModifier(property,type)66 : RSModifier(property, type) 67 { 68 property_->SetIsCustom(true); 69 } 70 GetPropertyModifierType()71 RSPropertyModifierType GetPropertyModifierType() const override 72 { 73 return RSPropertyModifierType::CUSTOM; 74 } 75 CreateRenderModifier()76 std::shared_ptr<RSRenderModifier> CreateRenderModifier() const override 77 { 78 auto node = property_->target_.lock(); 79 if (node == nullptr) { 80 return nullptr; 81 } 82 std::weak_ptr<RSCanvasNode> canvasnode = RSBaseNode::ReinterpretCast<RSCanvasNode>(node); 83 RSDrawingContext ctx = RSExtendedModifierHelper::CreateDrawingContext(canvasnode); 84 Draw(ctx); 85 return RSExtendedModifierHelper::CreateRenderModifier(ctx, property_->GetId(), GetModifierType()); 86 } 87 UpdateToRender()88 void UpdateToRender() override 89 { 90 auto node = property_->target_.lock(); 91 if (node == nullptr) { 92 return; 93 } 94 std::weak_ptr<RSCanvasNode> canvasnode = RSBaseNode::ReinterpretCast<RSCanvasNode>(node); 95 RSDrawingContext ctx = RSExtendedModifierHelper::CreateDrawingContext(canvasnode); 96 Draw(ctx); 97 auto drawCmdList = RSExtendedModifierHelper::FinishDrawing(ctx); 98 bool isEmpty = drawCmdList == nullptr; 99 if (lastDrawCmdListEmpty_ && isEmpty) { 100 return; 101 } 102 if (drawCmdList) { 103 drawCmdList->SetNoNeedUICaptured(noNeedUICaptured_); 104 drawCmdList->SetIsNeedUnmarshalOnDestruct(!node->IsRenderServiceNode()); 105 } 106 lastDrawCmdListEmpty_ = isEmpty; 107 108 std::unique_ptr<RSCommand> command = std::make_unique<RSUpdatePropertyDrawCmdList>( 109 node->GetId(), drawCmdList, property_->id_, UPDATE_TYPE_OVERWRITE); 110 node->AddCommand(command, node->IsRenderServiceNode()); 111 if (node->NeedForcedSendToRemote()) { 112 std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSUpdatePropertyDrawCmdList>( 113 node->GetId(), drawCmdList, property_->id_, UPDATE_TYPE_OVERWRITE); 114 node->AddCommand(commandForRemote, true, node->GetFollowType(), node->GetId()); 115 } 116 } 117 private: 118 bool lastDrawCmdListEmpty_ = false; 119 bool noNeedUICaptured_ = false; 120 }; 121 122 class RS_EXPORT RSGeometryTransModifier : public RSExtendedModifier { 123 public: RSGeometryTransModifier()124 RSGeometryTransModifier() : RSExtendedModifier(RSModifierType::GEOMETRYTRANS) 125 {} 126 virtual ~RSGeometryTransModifier() = default; 127 GetModifierType()128 RSModifierType GetModifierType() const override 129 { 130 return RSModifierType::GEOMETRYTRANS; 131 } 132 Draw(RSDrawingContext & context)133 void Draw(RSDrawingContext& context) const override {}; 134 135 virtual Drawing::Matrix GeometryEffect(float width, float height) const = 0; 136 137 protected: CreateRenderModifier()138 std::shared_ptr<RSRenderModifier> CreateRenderModifier() const override 139 { 140 auto node = property_->target_.lock(); 141 if (node == nullptr) { 142 return nullptr; 143 } 144 std::shared_ptr<RSCanvasNode> canvasnode; 145 auto uiContext = node->GetRSUIContext(); 146 if (uiContext == nullptr) { 147 canvasnode = RSNodeMap::Instance().GetNode<RSCanvasNode>(node->GetId()); 148 } else { 149 canvasnode = uiContext->GetNodeMap().GetNode<RSCanvasNode>(node->GetId()); 150 } 151 if (canvasnode == nullptr) { 152 return nullptr; 153 } 154 auto renderProperty = std::make_shared<RSRenderProperty<Drawing::Matrix>>( 155 GeometryEffect(canvasnode->GetPaintWidth(), canvasnode->GetPaintHeight()), property_->GetId()); 156 auto renderModifier = std::make_shared<RSGeometryTransRenderModifier>(renderProperty); 157 return renderModifier; 158 } 159 UpdateToRender()160 void UpdateToRender() override 161 { 162 auto node = property_->target_.lock(); 163 if (node == nullptr) { 164 return; 165 } 166 std::shared_ptr<RSCanvasNode> canvasnode; 167 auto uiContext = node->GetRSUIContext(); 168 if (uiContext == nullptr) { 169 canvasnode = RSNodeMap::Instance().GetNode<RSCanvasNode>(node->GetId()); 170 } else { 171 canvasnode = uiContext->GetNodeMap().GetNode<RSCanvasNode>(node->GetId()); 172 } 173 if (canvasnode == nullptr) { 174 return; 175 } 176 auto matrix = GeometryEffect(canvasnode->GetPaintWidth(), canvasnode->GetPaintHeight()); 177 std::unique_ptr<RSCommand> command = std::make_unique<RSUpdatePropertyDrawingMatrix>( 178 node->GetId(), matrix, property_->id_, UPDATE_TYPE_OVERWRITE); 179 node->AddCommand(command, node->IsRenderServiceNode()); 180 if (node->NeedForcedSendToRemote()) { 181 std::unique_ptr<RSCommand> commandForRemote = std::make_unique<RSUpdatePropertyDrawingMatrix>( 182 node->GetId(), matrix, property_->id_, UPDATE_TYPE_OVERWRITE); 183 node->AddCommand(commandForRemote, true, node->GetFollowType(), node->GetId()); 184 } 185 } 186 }; 187 188 class RSC_EXPORT RSTransitionModifier : public RSExtendedModifier { 189 public: RSTransitionModifier()190 RSTransitionModifier() : RSExtendedModifier(RSModifierType::TRANSITION) 191 {} 192 GetModifierType()193 RSModifierType GetModifierType() const override 194 { 195 return RSModifierType::TRANSITION; 196 } 197 198 virtual void Active() = 0; 199 200 virtual void Identity() = 0; 201 }; 202 203 class RSC_EXPORT RSBackgroundStyleModifier : public RSExtendedModifier { 204 public: RSBackgroundStyleModifier()205 RSBackgroundStyleModifier() : RSExtendedModifier(RSModifierType::BACKGROUND_STYLE) 206 {} 207 GetModifierType()208 RSModifierType GetModifierType() const override 209 { 210 return RSModifierType::BACKGROUND_STYLE; 211 } 212 }; 213 214 class RSC_EXPORT RSContentStyleModifier : public RSExtendedModifier { 215 public: RSContentStyleModifier()216 RSContentStyleModifier() : RSExtendedModifier(RSModifierType::CONTENT_STYLE) 217 {} 218 GetModifierType()219 RSModifierType GetModifierType() const override 220 { 221 return RSModifierType::CONTENT_STYLE; 222 } 223 }; 224 225 class RSC_EXPORT RSForegroundStyleModifier : public RSExtendedModifier { 226 public: RSForegroundStyleModifier()227 RSForegroundStyleModifier() : RSExtendedModifier(RSModifierType::FOREGROUND_STYLE) 228 {} 229 GetModifierType()230 RSModifierType GetModifierType() const override 231 { 232 return RSModifierType::FOREGROUND_STYLE; 233 } 234 }; 235 236 class RSC_EXPORT RSOverlayStyleModifier : public RSExtendedModifier { 237 public: RSOverlayStyleModifier()238 RSOverlayStyleModifier() : RSExtendedModifier(RSModifierType::OVERLAY_STYLE) 239 {} 240 GetModifierType()241 RSModifierType GetModifierType() const override 242 { 243 return RSModifierType::OVERLAY_STYLE; 244 } 245 }; 246 247 class RSC_EXPORT RSNodeModifier : public RSExtendedModifier { 248 public: RSNodeModifier()249 RSNodeModifier() : RSExtendedModifier(RSModifierType::NODE_MODIFIER) 250 {} 251 GetModifierType()252 RSModifierType GetModifierType() const override 253 { 254 return RSModifierType::NODE_MODIFIER; 255 } 256 257 virtual void Modify(RSNode& target) const = 0; 258 259 private: OnAttachToNode(const std::weak_ptr<RSNode> & target)260 void OnAttachToNode(const std::weak_ptr<RSNode>& target) override 261 { 262 target_ = target; 263 } 264 UpdateToRender()265 void UpdateToRender() override 266 { 267 auto node = target_.lock(); 268 if (node == nullptr) { 269 return; 270 } 271 Modify(*node); 272 } 273 Draw(RSDrawingContext & context)274 void Draw(RSDrawingContext& context) const override final {} 275 276 std::weak_ptr<RSNode> target_; 277 }; 278 } // namespace Rosen 279 } // namespace OHOS 280 281 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_EXTENDED_MODIFIER_H 282