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 namespace OHOS {
23 namespace Rosen {
DrawSurfaceNodeWithParams(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)24 void RSRenderEngine::DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
25 BufferDrawParam& params, PreProcessFunc preProcess, PostProcessFunc postProcess)
26 {
27 if (!params.useCPU) {
28 RegisterDeleteBufferListener(node.GetConsumer());
29 }
30
31 auto nodePreProcessFunc = [&preProcess, &node](RSPaintFilterCanvas& canvas, BufferDrawParam& params) {
32 // call the preprocess func passed in first.
33 if (preProcess != nullptr) {
34 preProcess(canvas, params);
35 }
36
37 // call RSSurfaceNode's common preprocess func.
38 RSRenderEngine::RSSurfaceNodeCommonPreProcess(node, canvas, params);
39 };
40
41 auto nodePostProcessFunc = [&postProcess, &node](RSPaintFilterCanvas& canvas, BufferDrawParam& params) {
42 // call the postProcess func passed in first.
43 if (postProcess != nullptr) {
44 postProcess(canvas, params);
45 }
46
47 // call RSSurfaceNode's common postProcess func.
48 RSRenderEngine::RSSurfaceNodeCommonPostProcess(node, canvas, params);
49 };
50
51 // draw shadow(should before canvas.clipRect in DrawWithParams()).
52 const auto& property = node.GetRenderProperties();
53 RSPropertiesPainter::DrawShadow(property, canvas, ¶ms.clipRRect);
54
55 DrawWithParams(canvas, params, nodePreProcessFunc, nodePostProcessFunc);
56 }
57
DrawLayers(RSPaintFilterCanvas & canvas,const std::vector<LayerInfoPtr> & layers,bool forceCPU,float mirrorAdaptiveCoefficient)58 void RSRenderEngine::DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU,
59 float mirrorAdaptiveCoefficient)
60 {
61 for (const auto& layer : layers) {
62 if (layer == nullptr) {
63 continue;
64 }
65 if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE ||
66 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE_CLEAR) {
67 continue;
68 }
69 auto nodePtr = static_cast<RSBaseRenderNode*>(layer->GetLayerAdditionalInfo());
70 if (nodePtr == nullptr) {
71 RS_LOGE("RSRenderEngine::DrawLayers: node is nullptr!");
72 continue;
73 }
74
75 auto saveCount = canvas.getSaveCount();
76 if (nodePtr->IsInstanceOf<RSSurfaceRenderNode>()) {
77 RSSurfaceRenderNode& node = *(static_cast<RSSurfaceRenderNode*>(nodePtr));
78 if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT_CLEAR ||
79 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_TUNNEL) {
80 ClipHoleForLayer(canvas, node);
81 canvas.restoreToCount(saveCount);
82 continue;
83 }
84 RS_LOGD("RSRenderEngine::DrawLayers dstRect[%d %d %d %d] SrcRect[%d %d %d %d]",
85 layer->GetLayerSize().x, layer->GetLayerSize().y,
86 layer->GetLayerSize().w, layer->GetLayerSize().h,
87 layer->GetDirtyRegion().x, layer->GetDirtyRegion().y,
88 layer->GetDirtyRegion().w, layer->GetDirtyRegion().h);
89 DrawSurfaceNode(canvas, node, mirrorAdaptiveCoefficient, forceCPU);
90 } else {
91 // Probably never reach this branch.
92 RS_LOGE("RSRenderEngine::DrawLayers: unexpected node type!");
93 continue;
94 }
95 canvas.restoreToCount(saveCount);
96 }
97 }
98
DrawWithParams(RSPaintFilterCanvas & canvas,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)99 void RSRenderEngine::DrawWithParams(RSPaintFilterCanvas& canvas, BufferDrawParam& params,
100 PreProcessFunc preProcess, PostProcessFunc postProcess)
101 {
102 if (params.setColorFilter) {
103 SetColorFilterModeToPaint(params.paint);
104 }
105
106 canvas.save();
107
108 RSBaseRenderUtil::SetPropertiesForCanvas(canvas, params);
109
110 if (preProcess != nullptr) {
111 preProcess(canvas, params);
112 }
113
114 if (params.useCPU) {
115 RSBaseRenderEngine::DrawBuffer(canvas, params);
116 } else {
117 RSBaseRenderEngine::DrawImage(canvas, params);
118 }
119
120 if (postProcess != nullptr) {
121 postProcess(canvas, params);
122 }
123
124 canvas.restore();
125 }
126
RSSurfaceNodeCommonPreProcess(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,BufferDrawParam & params)127 void RSRenderEngine::RSSurfaceNodeCommonPreProcess(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
128 BufferDrawParam& params)
129 {
130 const auto& property = node.GetRenderProperties();
131
132 // draw mask.
133 RectF maskBounds(0, 0, params.dstRect.width(), params.dstRect.height());
134 RSPropertiesPainter::DrawMask(
135 node.GetRenderProperties(), canvas, RSPropertiesPainter::Rect2SkRect(maskBounds));
136
137 // draw background filter (should execute this filter before drawing buffer/image).
138 auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetBackgroundFilter());
139 if (filter != nullptr) {
140 auto skRectPtr = std::make_unique<SkRect>();
141 skRectPtr->setXYWH(0, 0, params.srcRect.width(), params.srcRect.height());
142 RSPropertiesPainter::DrawFilter(property, canvas, filter, skRectPtr, canvas.GetSurface());
143 }
144 }
145
RSSurfaceNodeCommonPostProcess(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,BufferDrawParam & params)146 void RSRenderEngine::RSSurfaceNodeCommonPostProcess(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
147 BufferDrawParam& params)
148 {
149 const auto& property = node.GetRenderProperties();
150
151 // draw preprocess filter (should execute this filter after drawing buffer/image).
152 auto filter = std::static_pointer_cast<RSSkiaFilter>(property.GetFilter());
153 if (filter != nullptr) {
154 auto skRectPtr = std::make_unique<SkRect>();
155 skRectPtr->setXYWH(0, 0, params.srcRect.width(), params.srcRect.height());
156 RSPropertiesPainter::DrawFilter(property, canvas, filter, skRectPtr, canvas.GetSurface());
157 }
158 }
159
DrawSurfaceNode(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,float mirrorAdaptiveCoefficient,bool forceCPU)160 void RSRenderEngine::DrawSurfaceNode(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
161 float mirrorAdaptiveCoefficient, bool forceCPU)
162 {
163 // prepare BufferDrawParam
164 auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, false); // in display's coordinate.
165 const float adaptiveDstWidth = params.dstRect.width() * mirrorAdaptiveCoefficient;
166 const float adaptiveDstHeight = params.dstRect.height() * mirrorAdaptiveCoefficient;
167 params.dstRect.setWH(adaptiveDstWidth, adaptiveDstHeight);
168 const float translateX = params.matrix.getTranslateX() * mirrorAdaptiveCoefficient;
169 const float translateY = params.matrix.getTranslateY() * mirrorAdaptiveCoefficient;
170 params.matrix.setTranslateX(translateX);
171 params.matrix.setTranslateY(translateY);
172 const auto& clipRect = params.clipRect;
173 params.clipRect = SkRect::MakeXYWH(
174 clipRect.left() * mirrorAdaptiveCoefficient, clipRect.top() * mirrorAdaptiveCoefficient,
175 clipRect.width() * mirrorAdaptiveCoefficient, clipRect.height() * mirrorAdaptiveCoefficient);
176
177 DrawSurfaceNodeWithParams(canvas, node, params, nullptr, nullptr);
178 }
179
ClipHoleForLayer(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node)180 void RSRenderEngine::ClipHoleForLayer(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node)
181 {
182 BufferDrawParam params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, true);
183
184 std::string traceInfo;
185 AppendFormat(traceInfo, "Node name:%s ClipHole[%d %d %d %d]", node.GetName().c_str(),
186 params.clipRect.x(), params.clipRect.y(), params.clipRect.width(), params.clipRect.height());
187 RS_LOGD("RSRenderEngine::Redraw layer composition ClipHoleForLayer, %s.", traceInfo.c_str());
188 RS_TRACE_NAME(traceInfo);
189
190 canvas.save();
191 canvas.clipRect(params.clipRect);
192 canvas.clear(SK_ColorTRANSPARENT);
193 canvas.restore();
194 return;
195 }
196
SetColorFilterModeToPaint(SkPaint & paint)197 void RSRenderEngine::SetColorFilterModeToPaint(SkPaint& paint)
198 {
199 // for test automation
200 if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
201 RS_LOGD("RSRenderEngine::SetColorFilterModeToPaint mode:%d", static_cast<int32_t>(colorFilterMode_));
202 }
203 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode_, paint);
204 }
205 } // namespace Rosen
206 } // namespace OHOS
207