• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_engine.h"
17 #include "pipeline/rs_divided_render_util.h"
18 #include "string_utils.h"
19 #include "render/rs_skia_filter.h"
20 #include "rs_trace.h"
21 
22 #ifdef USE_ROSEN_DRAWING
23 #include "image/image.h"
24 #endif
25 
26 namespace OHOS {
27 namespace Rosen {
DrawSurfaceNodeWithParams(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)28 void RSRenderEngine::DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
29     BufferDrawParam& params, PreProcessFunc preProcess, PostProcessFunc postProcess)
30 {
31     if (!params.useCPU) {
32         RegisterDeleteBufferListener(node.GetConsumer());
33     }
34 
35     auto nodePreProcessFunc = [&preProcess, &node](RSPaintFilterCanvas& canvas, BufferDrawParam& params) {
36         // call the preprocess func passed in first.
37         if (preProcess != nullptr) {
38             preProcess(canvas, params);
39         }
40 
41         // call RSSurfaceNode's common preprocess func.
42         RSRenderEngine::RSSurfaceNodeCommonPreProcess(node, canvas, params);
43     };
44 
45     auto nodePostProcessFunc = [&postProcess, &node](RSPaintFilterCanvas& canvas, BufferDrawParam& params) {
46         // call the postProcess func passed in first.
47         if (postProcess != nullptr) {
48             postProcess(canvas, params);
49         }
50 
51         // call RSSurfaceNode's common postProcess func.
52         RSRenderEngine::RSSurfaceNodeCommonPostProcess(node, canvas, params);
53     };
54 
55     // draw shadow(should before canvas.clipRect in DrawWithParams()).
56     const auto& property = node.GetRenderProperties();
57     RSPropertiesPainter::DrawShadow(property, canvas, &params.clipRRect, node.IsLeashWindow());
58 
59     DrawWithParams(canvas, params, nodePreProcessFunc, nodePostProcessFunc);
60 }
61 
DrawLayers(RSPaintFilterCanvas & canvas,const std::vector<LayerInfoPtr> & layers,bool forceCPU,float mirrorAdaptiveCoefficient)62 void RSRenderEngine::DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU,
63     float mirrorAdaptiveCoefficient)
64 {
65     for (const auto& layer : layers) {
66         if (layer == nullptr) {
67             continue;
68         }
69         if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE ||
70             layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE_CLEAR) {
71             continue;
72         }
73         auto nodePtr = static_cast<RSBaseRenderNode*>(layer->GetLayerAdditionalInfo());
74         if (nodePtr == nullptr) {
75             RS_LOGE("RSRenderEngine::DrawLayers: node is nullptr!");
76             continue;
77         }
78 
79 #ifndef USE_ROSEN_DRAWING
80         auto saveCount = canvas.getSaveCount();
81 #else
82         auto saveCount = canvas.GetSaveCount();
83 #endif
84         if (nodePtr->IsInstanceOf<RSSurfaceRenderNode>()) {
85             RSSurfaceRenderNode& node = *(static_cast<RSSurfaceRenderNode*>(nodePtr));
86             if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT_CLEAR ||
87                 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_TUNNEL) {
88                 ClipHoleForLayer(canvas, node);
89 #ifndef USE_ROSEN_DRAWING
90                 canvas.restoreToCount(saveCount);
91 #else
92                 canvas.RestoreToCount(saveCount);
93 #endif
94                 continue;
95             }
96             RS_LOGD("RSRenderEngine::DrawLayers dstRect[%d %d %d %d]", layer->GetLayerSize().x,
97                     layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
98             const std::vector<GraphicIRect>& dirtyRegions = layer->GetDirtyRegions();
99             for (auto iter = dirtyRegions.begin(); iter != dirtyRegions.end(); iter++) {
100                 RS_LOGD("RSRenderEngine::DrawLayers SrcRect[%d %d %d %d]", iter->x, iter->y, iter->w, iter->h);
101             }
102             DrawSurfaceNode(canvas, node, mirrorAdaptiveCoefficient, forceCPU);
103         } else {
104             // Probably never reach this branch.
105             RS_LOGE("RSRenderEngine::DrawLayers: unexpected node type!");
106             continue;
107         }
108 #ifndef USE_ROSEN_DRAWING
109         canvas.restoreToCount(saveCount);
110 #else
111         canvas.RestoreToCount(saveCount);
112 #endif
113     }
114 }
115 
DrawWithParams(RSPaintFilterCanvas & canvas,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)116 void RSRenderEngine::DrawWithParams(RSPaintFilterCanvas& canvas, BufferDrawParam& params,
117     PreProcessFunc preProcess, PostProcessFunc postProcess)
118 {
119     if (params.setColorFilter) {
120         SetColorFilterModeToPaint(params.paint);
121     }
122 
123 #ifndef USE_ROSEN_DRAWING
124     canvas.save();
125 #else
126     canvas.Save();
127 #endif
128 
129     RSBaseRenderUtil::SetPropertiesForCanvas(canvas, params);
130 
131     if (preProcess != nullptr) {
132         preProcess(canvas, params);
133     }
134 
135     if (params.useCPU) {
136         RSBaseRenderEngine::DrawBuffer(canvas, params);
137     } else {
138         RSBaseRenderEngine::DrawImage(canvas, params);
139     }
140 
141     if (postProcess != nullptr) {
142         postProcess(canvas, params);
143     }
144 
145 #ifndef USE_ROSEN_DRAWING
146     canvas.restore();
147 #else
148     canvas.Restore();
149 #endif
150 }
151 
RSSurfaceNodeCommonPreProcess(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,BufferDrawParam & params)152 void RSRenderEngine::RSSurfaceNodeCommonPreProcess(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
153     BufferDrawParam& params)
154 {
155     const auto& property = node.GetRenderProperties();
156 
157     // draw mask.
158 #ifndef USE_ROSEN_DRAWING
159     RectF maskBounds(0, 0, params.dstRect.width(), params.dstRect.height());
160     RSPropertiesPainter::DrawMask(
161         node.GetRenderProperties(), canvas, RSPropertiesPainter::Rect2SkRect(maskBounds));
162 
163     // draw background filter (should execute this filter before drawing buffer/image).
164     RSPropertiesPainter::DrawFilter(property, canvas, FilterType::BACKGROUND_FILTER,
165         SkRect::MakeWH(params.srcRect.width(), params.srcRect.height()));
166 #else
167     RectF maskBounds(0, 0, params.dstRect.GetWidth(), params.dstRect.GetHeight());
168     RSPropertiesPainter::DrawMask(
169         node.GetRenderProperties(), canvas, RSPropertiesPainter::Rect2DrawingRect(maskBounds));
170 
171     // draw background filter (should execute this filter before drawing buffer/image).
172     RSPropertiesPainter::DrawFilter(property, canvas, FilterType::BACKGROUND_FILTER,
173         Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight()));
174 #endif
175 }
176 
RSSurfaceNodeCommonPostProcess(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,BufferDrawParam & params)177 void RSRenderEngine::RSSurfaceNodeCommonPostProcess(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
178     BufferDrawParam& params)
179 {
180     const auto& property = node.GetRenderProperties();
181 
182     // draw preprocess filter (should execute this filter after drawing buffer/image).
183 #ifndef USE_ROSEN_DRAWING
184     RSPropertiesPainter::DrawFilter(property, canvas, FilterType::FOREGROUND_FILTER,
185         SkRect::MakeWH(params.srcRect.width(), params.srcRect.height()));
186     RSPropertiesPainter::DrawLinearGradientBlurFilter(
187         property, canvas, SkRect::MakeWH(params.srcRect.width(), params.srcRect.height()));
188 #else
189     RSPropertiesPainter::DrawFilter(property, canvas, FilterType::FOREGROUND_FILTER,
190         Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight()));
191     RSPropertiesPainter::DrawLinearGradientBlurFilter(
192         property, canvas, Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight()));
193 #endif
194 }
195 
DrawSurfaceNode(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,float mirrorAdaptiveCoefficient,bool forceCPU)196 void RSRenderEngine::DrawSurfaceNode(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
197     float mirrorAdaptiveCoefficient, bool forceCPU)
198 {
199     // prepare BufferDrawParam
200     auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, false, forceCPU); // in display's coordinate.
201 #ifndef USE_ROSEN_DRAWING
202     const float adaptiveDstWidth = params.dstRect.width() * mirrorAdaptiveCoefficient;
203     const float adaptiveDstHeight = params.dstRect.height() * mirrorAdaptiveCoefficient;
204     params.dstRect.setWH(adaptiveDstWidth, adaptiveDstHeight);
205     const float translateX = params.matrix.getTranslateX() * mirrorAdaptiveCoefficient;
206     const float translateY = params.matrix.getTranslateY() * mirrorAdaptiveCoefficient;
207     params.matrix.setTranslateX(translateX);
208     params.matrix.setTranslateY(translateY);
209     const auto& clipRect = params.clipRect;
210     params.clipRect = SkRect::MakeXYWH(
211         clipRect.left() * mirrorAdaptiveCoefficient, clipRect.top() * mirrorAdaptiveCoefficient,
212         clipRect.width() * mirrorAdaptiveCoefficient, clipRect.height() * mirrorAdaptiveCoefficient);
213 #else
214     const float adaptiveDstWidth = params.dstRect.GetWidth() * mirrorAdaptiveCoefficient;
215     const float adaptiveDstHeight = params.dstRect.GetHeight() * mirrorAdaptiveCoefficient;
216     params.dstRect = Drawing::Rect(0, 0, adaptiveDstWidth, adaptiveDstHeight);
217     const float translateX = params.matrix.Get(Drawing::Matrix::Index::TRANS_X) * mirrorAdaptiveCoefficient;
218     const float translateY = params.matrix.Get(Drawing::Matrix::Index::TRANS_Y) * mirrorAdaptiveCoefficient;
219     params.matrix.Set(Drawing::Matrix::Index::TRANS_X, translateX);
220     params.matrix.Set(Drawing::Matrix::Index::TRANS_Y, translateY);
221     const auto& clipRect = params.clipRect;
222     auto clipLeft = clipRect.GetLeft() * mirrorAdaptiveCoefficient;
223     auto clipTop = clipRect.GetTop() * mirrorAdaptiveCoefficient;
224     params.clipRect = Drawing::Rect(
225         clipLeft, clipTop, clipLeft + clipRect.GetWidth() * mirrorAdaptiveCoefficient,
226         clipTop + clipRect.GetHeight() * mirrorAdaptiveCoefficient);
227 #endif
228 
229     DrawSurfaceNodeWithParams(canvas, node, params, nullptr, nullptr);
230 }
231 
ClipHoleForLayer(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node)232 void RSRenderEngine::ClipHoleForLayer(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node)
233 {
234     BufferDrawParam params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, true);
235 
236     std::string traceInfo;
237 #ifndef USE_ROSEN_DRAWING
238     AppendFormat(traceInfo, "Node name:%s ClipHole[%d %d %d %d]", node.GetName().c_str(),
239         params.clipRect.x(), params.clipRect.y(), params.clipRect.width(), params.clipRect.height());
240     RS_LOGD("RSRenderEngine::Redraw layer composition ClipHoleForLayer, %s.", traceInfo.c_str());
241     RS_TRACE_NAME(traceInfo);
242 
243     canvas.save();
244     canvas.clipRect(params.clipRect);
245     canvas.clear(SK_ColorTRANSPARENT);
246     canvas.restore();
247 #else
248     AppendFormat(traceInfo, "Node name:%s ClipHole[%d %d %d %d]", node.GetName().c_str(),
249         params.clipRect.GetLeft(), params.clipRect.GetTop(), params.clipRect.GetWidth(), params.clipRect.GetHeight());
250     RS_LOGD("RSRenderEngine::Redraw layer composition ClipHoleForLayer, %s.", traceInfo.c_str());
251     RS_TRACE_NAME(traceInfo);
252 
253     canvas.Save();
254     canvas.ClipRect(params.clipRect, Drawing::ClipOp::INTERSECT, false);
255     canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
256     canvas.Restore();
257 #endif
258     return;
259 }
260 
261 #ifndef USE_ROSEN_DRAWING
SetColorFilterModeToPaint(SkPaint & paint)262 void RSRenderEngine::SetColorFilterModeToPaint(SkPaint& paint)
263 #else
264 void RSRenderEngine::SetColorFilterModeToPaint(Drawing::Brush& paint)
265 #endif
266 {
267     // for test automation
268     if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
269         RS_LOGD("RSRenderEngine::SetColorFilterModeToPaint mode:%d", static_cast<int32_t>(colorFilterMode_));
270     }
271     RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode_, paint);
272 }
273 } // namespace Rosen
274 } // namespace OHOS
275