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