1 /*
2 * Copyright (c) 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 #include "property/rs_property_drawable_utilities.h"
17 #include "pipeline/rs_render_node.h"
18 #include "pipeline/rs_single_frame_composer.h"
19 #include "property/rs_properties.h"
20 #include "property/rs_properties_painter.h"
21
22 namespace OHOS::Rosen {
23 // ============================================================================
24 // alias (reference or soft link) of another drawable
RSAliasDrawable(RSPropertyDrawableSlot slot)25 RSAliasDrawable::RSAliasDrawable(RSPropertyDrawableSlot slot) : slot_(slot) {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const26 void RSAliasDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
27 {
28 content.DrawPropertyDrawable(slot_, canvas);
29 }
30
31 // ============================================================================
32 // Save and Restore
RSSaveDrawable(std::shared_ptr<uint32_t> content)33 RSSaveDrawable::RSSaveDrawable(std::shared_ptr<uint32_t> content) : content_(std::move(content)) {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const34 void RSSaveDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
35 {
36 *content_ = canvas.Save();
37 }
38
RSRestoreDrawable(std::shared_ptr<uint32_t> content)39 RSRestoreDrawable::RSRestoreDrawable(std::shared_ptr<uint32_t> content) : content_(std::move(content)) {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const40 void RSRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
41 {
42 canvas.RestoreToCount(*content_);
43 }
44
RSCustomSaveDrawable(std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content,RSPaintFilterCanvas::SaveType type)45 RSCustomSaveDrawable::RSCustomSaveDrawable(
46 std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content, RSPaintFilterCanvas::SaveType type)
47 : content_(std::move(content)), type_(type)
48 {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const49 void RSCustomSaveDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
50 {
51 *content_ = canvas.SaveAllStatus(type_);
52 }
53
RSCustomRestoreDrawable(std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content)54 RSCustomRestoreDrawable::RSCustomRestoreDrawable(std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content)
55 : content_(std::move(content))
56 {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const57 void RSCustomRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
58 {
59 canvas.RestoreStatus(*content_);
60 }
61
62 // ============================================================================
63 // Adapter for RSRenderModifier
RSModifierDrawable(RSModifierType type)64 RSModifierDrawable::RSModifierDrawable(RSModifierType type) : type_(type) {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const65 void RSModifierDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
66 {
67 // single-frame-compose needs to access render node & mutable draw cmd list during the render process
68 // PLANNING: this is a temporarily workaround, should refactor later
69 auto nodePtr = content.GetRenderProperties().backref_.lock();
70 if (nodePtr == nullptr) {
71 return;
72 }
73 auto& drawCmdModifiers = const_cast<RSRenderContent::DrawCmdContainer&>(content.drawCmdModifiers_);
74 auto itr = drawCmdModifiers.find(type_);
75 if (itr == drawCmdModifiers.end() || itr->second.empty()) {
76 return;
77 }
78 // temporary fix, will refactor RSRenderModifier::Apply to workaround this issue
79 RSModifierContext context = { const_cast<RSRenderContent&>(content).renderProperties_, &canvas };
80 if (RSSystemProperties::GetSingleFrameComposerEnabled()) {
81 bool needSkip = false;
82 if (nodePtr->GetNodeIsSingleFrameComposer() && nodePtr->singleFrameComposer_ != nullptr) {
83 needSkip = nodePtr->singleFrameComposer_->SingleFrameModifierAddToList(type_, itr->second);
84 }
85 for (const auto& modifier : itr->second) {
86 if (nodePtr->singleFrameComposer_ != nullptr &&
87 nodePtr->singleFrameComposer_->SingleFrameIsNeedSkip(needSkip, modifier)) {
88 continue;
89 }
90 modifier->Apply(context);
91 }
92 } else {
93 for (const auto& modifier : itr->second) {
94 if (modifier) {
95 modifier->Apply(context);
96 }
97 }
98 }
99 }
100
101 // ============================================================================
102 // Alpha
RSAlphaDrawable(float alpha)103 RSAlphaDrawable::RSAlphaDrawable(float alpha) : RSPropertyDrawable(), alpha_(alpha) {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const104 void RSAlphaDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
105 {
106 canvas.MultiplyAlpha(alpha_);
107 }
Generate(const RSRenderContent & content)108 RSPropertyDrawable::DrawablePtr RSAlphaDrawable::Generate(const RSRenderContent& content)
109 {
110 auto alpha = content.GetRenderProperties().GetAlpha();
111 if (alpha == 1) {
112 return nullptr;
113 }
114 return content.GetRenderProperties().GetAlphaOffscreen() ? std::make_unique<RSAlphaOffscreenDrawable>(alpha)
115 : std::make_unique<RSAlphaDrawable>(alpha);
116 }
117
RSAlphaOffscreenDrawable(float alpha)118 RSAlphaOffscreenDrawable::RSAlphaOffscreenDrawable(float alpha) : RSAlphaDrawable(alpha) {}
Draw(const RSRenderContent & content,RSPaintFilterCanvas & canvas) const119 void RSAlphaOffscreenDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
120 {
121 auto rect = RSPropertiesPainter::Rect2DrawingRect(content.GetRenderProperties().GetBoundsRect());
122 Drawing::Brush brush;
123 brush.SetAlpha(std::clamp(alpha_, 0.f, 1.f) * UINT8_MAX);
124 Drawing::SaveLayerOps slr(&rect, &brush);
125 canvas.SaveLayer(slr);
126 }
127 } // namespace OHOS::Rosen
128