• 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 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, &params.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