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, ¶ms.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