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