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 "pipeline/rs_main_thread.h"
19 #include "string_utils.h"
20 #include "render/rs_drawing_filter.h"
21 #include "render/rs_skia_filter.h"
22 #include "rs_trace.h"
23 #include "platform/common/rs_log.h"
24
25 #include "image/image.h"
26
27 namespace OHOS {
28 namespace Rosen {
29 namespace {
30 constexpr float GAMMA2_2 = 2.2f;
31 }
DrawSurfaceNodeWithParams(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)32 void RSRenderEngine::DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
33 BufferDrawParam& params, PreProcessFunc preProcess, PostProcessFunc postProcess)
34 {
35 if (!params.useCPU) {
36 RegisterDeleteBufferListener(node.GetRSSurfaceHandler()->GetConsumer());
37 }
38
39 auto nodePreProcessFunc = [&preProcess, &node](RSPaintFilterCanvas& canvas, BufferDrawParam& params) {
40 // call the preprocess func passed in first.
41 if (preProcess != nullptr) {
42 preProcess(canvas, params);
43 }
44
45 // call RSSurfaceNode's common preprocess func.
46 RSRenderEngine::RSSurfaceNodeCommonPreProcess(node, canvas, params);
47 };
48
49 auto nodePostProcessFunc = [&postProcess, &node](RSPaintFilterCanvas& canvas, BufferDrawParam& params) {
50 // call the postProcess func passed in first.
51 if (postProcess != nullptr) {
52 postProcess(canvas, params);
53 }
54
55 // call RSSurfaceNode's common postProcess func.
56 RSRenderEngine::RSSurfaceNodeCommonPostProcess(node, canvas, params);
57 };
58
59 // draw shadow(should before canvas.clipRect in DrawWithParams()).
60 const auto& property = node.GetRenderProperties();
61 RSPropertiesPainter::DrawShadow(property, canvas, ¶ms.clipRRect);
62 RSPropertiesPainter::DrawOutline(property, canvas);
63
64 DrawWithParams(canvas, params, nodePreProcessFunc, nodePostProcessFunc);
65 }
66
67 #ifdef USE_VIDEO_PROCESSING_ENGINE
DrawLayers(RSPaintFilterCanvas & canvas,const std::vector<LayerInfoPtr> & layers,bool forceCPU,const ScreenInfo & screenInfo,GraphicColorGamut colorGamut)68 void RSRenderEngine::DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU,
69 const ScreenInfo& screenInfo, GraphicColorGamut colorGamut)
70 #else
71 void RSRenderEngine::DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU,
72 const ScreenInfo& screenInfo)
73 #endif
74 {
75 (void) screenInfo;
76 #ifdef USE_VIDEO_PROCESSING_ENGINE
77 (void) colorGamut;
78 #endif
79 const auto& nodeMap = RSMainThread::Instance()->GetContext().GetNodeMap();
80 for (const auto& layer : layers) {
81 if (layer == nullptr) {
82 continue;
83 }
84 if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE ||
85 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE_CLEAR) {
86 continue;
87 }
88 auto nodePtr = nodeMap.GetRenderNode<RSRenderNode>(layer->GetNodeId());
89 if (nodePtr == nullptr) {
90 RS_LOGE("RSRenderEngine::DrawLayers: node is nullptr!");
91 continue;
92 }
93
94 auto saveCount = canvas.GetSaveCount();
95 if (nodePtr->IsInstanceOf<RSSurfaceRenderNode>()) {
96 RSSurfaceRenderNode& node = *(static_cast<RSSurfaceRenderNode*>(nodePtr.get()));
97 if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT_CLEAR ||
98 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_TUNNEL) {
99 ClipHoleForLayer(canvas, node);
100 canvas.RestoreToCount(saveCount);
101 continue;
102 }
103 RS_LOGD("RSRenderEngine::DrawLayers dstRect[%{public}d %{public}d %{public}d %{public}d]",
104 layer->GetLayerSize().x, layer->GetLayerSize().y, layer->GetLayerSize().w, layer->GetLayerSize().h);
105 const std::vector<GraphicIRect>& dirtyRegions = layer->GetDirtyRegions();
106 for (auto iter = dirtyRegions.begin(); iter != dirtyRegions.end(); iter++) {
107 RS_LOGD("RSRenderEngine::DrawLayers SrcRect[%{public}d %{public}d %{public}d %{public}d]",
108 iter->x, iter->y, iter->w, iter->h);
109 }
110 auto params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, false, forceCPU);
111 #ifdef USE_VIDEO_PROCESSING_ENGINE
112 params.tmoNits = layer->GetDisplayNit();
113 params.displayNits = params.tmoNits / std::pow(layer->GetBrightnessRatio(), GAMMA2_2); // gamma 2.2
114 if (node.GetRSSurfaceHandler() != nullptr &&
115 !CheckIsHdrSurfaceBuffer(node.GetRSSurfaceHandler()->GetBuffer())) {
116 params.brightnessRatio = layer->GetBrightnessRatio();
117 } else {
118 params.isHdrRedraw = true;
119 }
120 #endif
121 DrawSurfaceNode(canvas, node, params);
122 } else {
123 // Probably never reach this branch.
124 RS_LOGE("RSRenderEngine::DrawLayers: unexpected node type!");
125 continue;
126 }
127 canvas.RestoreToCount(saveCount);
128 }
129 }
130
DrawWithParams(RSPaintFilterCanvas & canvas,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)131 void RSRenderEngine::DrawWithParams(RSPaintFilterCanvas& canvas, BufferDrawParam& params,
132 PreProcessFunc preProcess, PostProcessFunc postProcess)
133 {
134 if (params.setColorFilter) {
135 SetColorFilterModeToPaint(params.paint);
136 }
137
138 canvas.Save();
139
140 RSBaseRenderUtil::SetPropertiesForCanvas(canvas, params);
141
142 if (preProcess != nullptr) {
143 preProcess(canvas, params);
144 }
145
146 if (params.useCPU) {
147 RSBaseRenderEngine::DrawBuffer(canvas, params);
148 } else {
149 RSBaseRenderEngine::DrawImage(canvas, params);
150 }
151
152 if (postProcess != nullptr) {
153 postProcess(canvas, params);
154 }
155
156 canvas.Restore();
157 }
158
RSSurfaceNodeCommonPreProcess(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,BufferDrawParam & params)159 void RSRenderEngine::RSSurfaceNodeCommonPreProcess(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
160 BufferDrawParam& params)
161 {
162 const auto& property = node.GetRenderProperties();
163
164 // draw mask.
165 RectF maskBounds(0, 0, params.dstRect.GetWidth(), params.dstRect.GetHeight());
166 RSPropertiesPainter::DrawMask(
167 node.GetRenderProperties(), canvas, RSPropertiesPainter::Rect2DrawingRect(maskBounds));
168
169 // draw background filter (should execute this filter before drawing buffer/image).
170 RSPropertiesPainter::DrawFilter(property, canvas, FilterType::BACKGROUND_FILTER,
171 Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight()));
172 }
173
RSSurfaceNodeCommonPostProcess(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,BufferDrawParam & params)174 void RSRenderEngine::RSSurfaceNodeCommonPostProcess(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
175 BufferDrawParam& params)
176 {
177 const auto& property = node.GetRenderProperties();
178
179 // draw preprocess filter (should execute this filter after drawing buffer/image).
180 RSPropertiesPainter::DrawFilter(property, canvas, FilterType::FOREGROUND_FILTER,
181 Drawing::Rect(0, 0, params.srcRect.GetWidth(), params.srcRect.GetHeight()));
182 }
183
DrawSurfaceNode(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,BufferDrawParam & params)184 void RSRenderEngine::DrawSurfaceNode(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
185 BufferDrawParam& params)
186 {
187 const float adaptiveDstWidth = params.dstRect.GetWidth() * mirrorAdaptiveCoefficient_;
188 const float adaptiveDstHeight = params.dstRect.GetHeight() * mirrorAdaptiveCoefficient_;
189 params.dstRect = Drawing::Rect(0, 0, adaptiveDstWidth, adaptiveDstHeight);
190 const float translateX = params.matrix.Get(Drawing::Matrix::Index::TRANS_X) * mirrorAdaptiveCoefficient_;
191 const float translateY = params.matrix.Get(Drawing::Matrix::Index::TRANS_Y) * mirrorAdaptiveCoefficient_;
192 params.matrix.Set(Drawing::Matrix::Index::TRANS_X, translateX);
193 params.matrix.Set(Drawing::Matrix::Index::TRANS_Y, translateY);
194 const auto& clipRect = params.clipRect;
195 auto clipLeft = clipRect.GetLeft() * mirrorAdaptiveCoefficient_;
196 auto clipTop = clipRect.GetTop() * mirrorAdaptiveCoefficient_;
197 params.clipRect = Drawing::Rect(
198 clipLeft, clipTop, clipLeft + clipRect.GetWidth() * mirrorAdaptiveCoefficient_,
199 clipTop + clipRect.GetHeight() * mirrorAdaptiveCoefficient_);
200
201 DrawSurfaceNodeWithParams(canvas, node, params, nullptr, nullptr);
202 }
203
ClipHoleForLayer(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node)204 void RSRenderEngine::ClipHoleForLayer(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node)
205 {
206 BufferDrawParam params = RSDividedRenderUtil::CreateBufferDrawParam(node, false, true);
207
208 std::string traceInfo;
209 AppendFormat(traceInfo, "Node name:%s ClipHole[%d %d %d %d]", node.GetName().c_str(),
210 params.clipRect.GetLeft(), params.clipRect.GetTop(), params.clipRect.GetWidth(), params.clipRect.GetHeight());
211 RS_LOGD("RSRenderEngine::Redraw layer composition ClipHoleForLayer, %{public}s.", traceInfo.c_str());
212 RS_TRACE_NAME(traceInfo);
213
214 canvas.Save();
215 canvas.ClipRect(params.clipRect, Drawing::ClipOp::INTERSECT, false);
216 canvas.Clear(Drawing::Color::COLOR_TRANSPARENT);
217 canvas.Restore();
218 return;
219 }
220
SetColorFilterModeToPaint(Drawing::Brush & paint)221 void RSRenderEngine::SetColorFilterModeToPaint(Drawing::Brush& paint)
222 {
223 // for test automation
224 if (colorFilterMode_ != ColorFilterMode::COLOR_FILTER_END) {
225 RS_LOGD("RSRenderEngine::SetColorFilterModeToPaint mode:%{public}d", static_cast<int32_t>(colorFilterMode_));
226 }
227 RSBaseRenderUtil::SetColorFilterModeToPaint(colorFilterMode_, paint);
228 }
229 } // namespace Rosen
230 } // namespace OHOS
231