1 /*
2 * Copyright (c) 2021-2022 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 "pipeline/rs_render_thread_visitor.h"
17
18 #include <include/core/SkColor.h>
19 #include <include/core/SkFont.h>
20 #include <include/core/SkPaint.h>
21
22 #include "pipeline/rs_canvas_render_node.h"
23 #include "pipeline/rs_dirty_region_manager.h"
24 #include "pipeline/rs_node_map.h"
25 #include "pipeline/rs_render_thread.h"
26 #include "pipeline/rs_root_render_node.h"
27 #include "pipeline/rs_surface_render_node.h"
28 #include "platform/common/rs_log.h"
29 #include "platform/drawing/rs_surface.h"
30 #include "rs_trace.h"
31 #include "transaction/rs_transaction_proxy.h"
32 #include "ui/rs_surface_extractor.h"
33 #include "ui/rs_surface_node.h"
34
35 namespace OHOS {
36 namespace Rosen {
RSRenderThreadVisitor()37 RSRenderThreadVisitor::RSRenderThreadVisitor() : canvas_(nullptr) {}
38
~RSRenderThreadVisitor()39 RSRenderThreadVisitor::~RSRenderThreadVisitor() {}
40
PrepareBaseRenderNode(RSBaseRenderNode & node)41 void RSRenderThreadVisitor::PrepareBaseRenderNode(RSBaseRenderNode& node)
42 {
43 for (auto& child : node.GetSortedChildren()) {
44 child->Prepare(shared_from_this());
45 }
46 }
47
PrepareRootRenderNode(RSRootRenderNode & node)48 void RSRenderThreadVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
49 {
50 if (isIdle_) {
51 curTreeRoot_ = &node;
52 curTreeRoot_->ClearSurfaceNodeInRS();
53
54 dirtyManager_.Clear();
55 parent_ = nullptr;
56 dirtyFlag_ = false;
57 isIdle_ = false;
58 PrepareCanvasRenderNode(node);
59 isIdle_ = true;
60 } else {
61 PrepareCanvasRenderNode(node);
62 }
63 }
64
PrepareCanvasRenderNode(RSCanvasRenderNode & node)65 void RSRenderThreadVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode& node)
66 {
67 bool dirtyFlag = dirtyFlag_;
68 dirtyFlag_ = node.Update(dirtyManager_, parent_ ? &(parent_->GetRenderProperties()) : nullptr, dirtyFlag_);
69 PrepareBaseRenderNode(node);
70 dirtyFlag_ = dirtyFlag;
71 }
72
PrepareSurfaceRenderNode(RSSurfaceRenderNode & node)73 void RSRenderThreadVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
74 {
75 curTreeRoot_->AddSurfaceRenderNode(node.GetId());
76 bool dirtyFlag = dirtyFlag_;
77 dirtyFlag_ = node.Update(dirtyManager_, parent_ ? &(parent_->GetRenderProperties()) : nullptr, dirtyFlag_);
78 PrepareBaseRenderNode(node);
79 dirtyFlag_ = dirtyFlag;
80 }
81
ProcessBaseRenderNode(RSBaseRenderNode & node)82 void RSRenderThreadVisitor::ProcessBaseRenderNode(RSBaseRenderNode& node)
83 {
84 for (auto& child : node.GetSortedChildren()) {
85 child->Process(shared_from_this());
86 }
87 // clear SortedChildren, it will be generated again in next frame
88 node.ResetSortedChildren();
89 }
90
ProcessRootRenderNode(RSRootRenderNode & node)91 void RSRenderThreadVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
92 {
93 if (!isIdle_) {
94 ProcessCanvasRenderNode(node);
95 return;
96 }
97 if (!node.GetRenderProperties().GetVisible() || node.GetSurfaceWidth() <= 0 || node.GetSurfaceHeight() <= 0) {
98 ROSEN_LOGE("No valid RSRootRenderNode");
99 return;
100 }
101 auto ptr = RSNodeMap::Instance().GetNode<RSSurfaceNode>(node.GetRSSurfaceNodeId());
102 if (ptr == nullptr) {
103 ROSEN_LOGE("No valid RSSurfaceNode");
104 return;
105 }
106
107 auto surfaceNodeColorSpace = ptr->GetColorSpace();
108
109 std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(ptr);
110 if (rsSurface == nullptr) {
111 ROSEN_LOGE("No RSSurface found");
112 return;
113 }
114
115 auto rsSurfaceColorSpace = rsSurface->GetColorSpace();
116
117 if (surfaceNodeColorSpace != rsSurfaceColorSpace) {
118 ROSEN_LOGD("Set new colorspace %d to rsSurface", surfaceNodeColorSpace);
119 rsSurface->SetColorSpace(surfaceNodeColorSpace);
120 }
121
122 #ifdef ACE_ENABLE_GL
123 RenderContext* rc = RSRenderThread::Instance().GetRenderContext();
124 rsSurface->SetRenderContext(rc);
125 #endif
126 RS_TRACE_BEGIN("rsSurface->RequestFrame");
127 auto surfaceFrame = rsSurface->RequestFrame(node.GetSurfaceWidth(), node.GetSurfaceHeight());
128 RS_TRACE_END();
129 if (surfaceFrame == nullptr) {
130 ROSEN_LOGE("Request Frame Failed");
131 return;
132 }
133
134 sk_sp<SkSurface> skSurface = nullptr;
135 if (RSRootRenderNode::NeedForceRaster()) {
136 ROSEN_LOGD("Force Raster draw");
137 RSRootRenderNode::MarkForceRaster(false);
138 SkImageInfo imageInfo = SkImageInfo::Make(node.GetSurfaceWidth(), node.GetSurfaceHeight(),
139 kRGBA_8888_SkColorType, kOpaque_SkAlphaType, SkColorSpace::MakeSRGB());
140 skSurface = SkSurface::MakeRaster(imageInfo);
141 canvas_ = new RSPaintFilterCanvas(skSurface->getCanvas());
142 } else {
143 canvas_ = new RSPaintFilterCanvas(surfaceFrame->GetCanvas());
144 }
145 canvas_->clear(SK_ColorTRANSPARENT);
146
147
148 isIdle_ = false;
149 ProcessCanvasRenderNode(node);
150
151 if (skSurface) {
152 canvas_->flush();
153 surfaceFrame->GetCanvas()->clear(SK_ColorTRANSPARENT);
154 skSurface->draw(surfaceFrame->GetCanvas(), 0.f, 0.f, nullptr);
155 } else if (RSRootRenderNode::NeedForceRaster()) {
156 RSRenderThread::Instance().RequestNextVSync();
157 }
158
159 RS_TRACE_BEGIN("rsSurface->FlushFrame");
160 rsSurface->FlushFrame(surfaceFrame);
161 RS_TRACE_END();
162
163 delete canvas_;
164 canvas_ = nullptr;
165
166 isIdle_ = true;
167 }
168
ProcessCanvasRenderNode(RSCanvasRenderNode & node)169 void RSRenderThreadVisitor::ProcessCanvasRenderNode(RSCanvasRenderNode& node)
170 {
171 if (!node.GetRenderProperties().GetVisible()) {
172 return;
173 }
174 if (!canvas_) {
175 ROSEN_LOGE("RSRenderThreadVisitor::ProcessCanvasRenderNode, canvas is nullptr");
176 return;
177 }
178 node.ProcessRenderBeforeChildren(*canvas_);
179 ProcessBaseRenderNode(node);
180 node.ProcessRenderAfterChildren(*canvas_);
181 }
182
ProcessSurfaceRenderNode(RSSurfaceRenderNode & node)183 void RSRenderThreadVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
184 {
185 if (!canvas_) {
186 ROSEN_LOGE("RSRenderThreadVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
187 return;
188 }
189 // RSSurfaceRenderNode in RSRenderThreadVisitor do not have information of property.
190 // We only get parent's matrix and send it to RenderService
191 #ifdef ROSEN_OHOS
192 node.SetMatrix(canvas_->getTotalMatrix());
193 node.SetAlpha(canvas_->GetAlpha());
194 node.SetParentId(node.GetParent().lock()->GetId());
195 auto clipRect = canvas_->getDeviceClipBounds();
196 node.SetClipRegion({clipRect.left(), clipRect.top(), clipRect.width(), clipRect.height()});
197
198 auto x = node.GetRenderProperties().GetBoundsPositionX();
199 auto y = node.GetRenderProperties().GetBoundsPositionY();
200 auto width = node.GetRenderProperties().GetBoundsWidth();
201 auto height = node.GetRenderProperties().GetBoundsHeight();
202 canvas_->save();
203 canvas_->clipRect(SkRect::MakeXYWH(x, y, width, height));
204 if (node.IsBufferAvailable() == true) {
205 ROSEN_LOGI("RSRenderThreadVisitor::ProcessSurfaceRenderNode CILP (set transparent) [%f, %f, %f, %f]",
206 x, y, width, height);
207 canvas_->clear(SK_ColorTRANSPARENT);
208 } else {
209 ROSEN_LOGI("RSRenderThreadVisitor::ProcessSurfaceRenderNode NOT CILP (set black) [%f, %f, %f, %f]",
210 x, y, width, height);
211 if (node.NeedSetCallbackForRenderThreadRefresh() == true) {
212 node.SetCallbackForRenderThreadRefresh([] {
213 RSRenderThread::Instance().RequestNextVSync();
214 });
215 }
216 auto backgroundColor = node.GetRenderProperties().GetBackgroundColor();
217 if (backgroundColor != RgbPalette::Transparent()) {
218 canvas_->clear(backgroundColor.AsArgbInt());
219 } else {
220 canvas_->clear(SK_ColorBLACK);
221 }
222 }
223 canvas_->restore();
224
225 #endif
226 ProcessBaseRenderNode(node);
227 }
228
229 } // namespace Rosen
230 } // namespace OHOS
231