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