• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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