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