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 "common/rs_singleton.h"
17 #include "info_collection/rs_layer_compose_collection.h"
18 #include "luminance/rs_luminance_control.h"
19 #include "pipeline/rs_uni_render_engine.h"
20 #include "pipeline/rs_uni_render_util.h"
21 #include "pipeline/round_corner_display/rs_round_corner_display_manager.h"
22 #ifdef USE_VIDEO_PROCESSING_ENGINE
23 #include "metadata_helper.h"
24 #endif
25
26 #include "drawable/rs_display_render_node_drawable.h"
27 #include "drawable/rs_surface_render_node_drawable.h"
28
29 namespace OHOS {
30 namespace Rosen {
31
32 using RSRcdManager = RSSingleton<RoundCornerDisplayManager>;
33 namespace {
34 const float REDRAW_DFX_ALPHA = 0.4f; // redraw dfx drawrect alpha
35 }
DrawSurfaceNodeWithParams(RSPaintFilterCanvas & canvas,RSSurfaceRenderNode & node,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)36 void RSUniRenderEngine::DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas, RSSurfaceRenderNode& node,
37 BufferDrawParam& params, PreProcessFunc preProcess, PostProcessFunc postProcess)
38 {
39 RS_LOGE("RSUniRenderEngine::DrawSurfaceNodeWithParams is not support");
40 }
41
DrawSurfaceNodeWithParams(RSPaintFilterCanvas & canvas,DrawableV2::RSSurfaceRenderNodeDrawable & surfaceDrawable,BufferDrawParam & params,PreProcessFunc preProcess,PostProcessFunc postProcess)42 void RSUniRenderEngine::DrawSurfaceNodeWithParams(RSPaintFilterCanvas& canvas,
43 DrawableV2::RSSurfaceRenderNodeDrawable& surfaceDrawable, BufferDrawParam& params, PreProcessFunc preProcess,
44 PostProcessFunc postProcess)
45 {
46 canvas.Save();
47 canvas.ConcatMatrix(params.matrix);
48 if (!params.useCPU) {
49 RegisterDeleteBufferListener(surfaceDrawable.GetConsumerOnDraw());
50 DrawImage(canvas, params);
51 } else {
52 DrawBuffer(canvas, params);
53 }
54 canvas.Restore();
55 }
56
57 #ifdef USE_VIDEO_PROCESSING_ENGINE
DrawLayers(RSPaintFilterCanvas & canvas,const std::vector<LayerInfoPtr> & layers,bool forceCPU,const ScreenInfo & screenInfo,GraphicColorGamut colorGamut)58 void RSUniRenderEngine::DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU,
59 const ScreenInfo& screenInfo, GraphicColorGamut colorGamut)
60 #else
61 void RSUniRenderEngine::DrawLayers(RSPaintFilterCanvas& canvas, const std::vector<LayerInfoPtr>& layers, bool forceCPU,
62 const ScreenInfo& screenInfo)
63 #endif
64 {
65 for (const auto& layer : layers) {
66 if (layer == nullptr) {
67 continue;
68 }
69 if (layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE ||
70 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE_CLEAR ||
71 layer->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_SOLID_COLOR) {
72 continue;
73 }
74 GraphicLayerColor layerBlackColor = {
75 .r = 0,
76 .g = 0,
77 .b = 0,
78 .a = 0
79 };
80 auto layerSurface = layer->GetSurface();
81 if (layerSurface == nullptr) {
82 const auto& layerColor = layer->GetLayerColor();
83 if (layerColor.a != layerBlackColor.a || layerColor.r != layerBlackColor.r ||
84 layerColor.g != layerBlackColor.g || layerColor.b != layerBlackColor.b) {
85 Drawing::AutoCanvasRestore acr(canvas, true);
86 const auto& dstRect = layer->GetLayerSize();
87 auto color = Drawing::Color::ColorQuadSetARGB(layerColor.a, layerColor.r, layerColor.g, layerColor.b);
88 Drawing::Rect clipRect = Drawing::Rect(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
89 static_cast<float>(dstRect.w) + static_cast<float>(dstRect.x),
90 static_cast<float>(dstRect.h) + static_cast<float>(dstRect.y));
91 canvas.ClipRect(clipRect, Drawing::ClipOp::INTERSECT, false);
92 canvas.DrawColor(color);
93 }
94 continue;
95 } else if (RSRcdManager::GetInstance().CheckLayerIsRCD(layerSurface->GetName())) {
96 continue; // current flow should skip rcd layer which not have correct resource for canvas draw
97 }
98 Drawing::AutoCanvasRestore acr(canvas, true);
99 DrawLayerPreProcess(canvas, layer);
100 // prepare BufferDrawParam
101 auto params = RSUniRenderUtil::CreateLayerBufferDrawParam(layer, forceCPU);
102 params.matrix.PostScale(screenInfo.GetRogWidthRatio(), screenInfo.GetRogHeightRatio());
103 params.screenId = screenInfo.id;
104 #ifdef USE_VIDEO_PROCESSING_ENGINE
105 params.targetColorGamut = colorGamut;
106 auto screenManager = CreateOrGetScreenManager();
107 if (screenManager != nullptr) {
108 params.sdrNits = layer->GetSdrNit();
109 params.tmoNits = layer->GetDisplayNit();
110 params.displayNits = params.tmoNits / std::pow(layer->GetBrightnessRatio(), 2.2f); // gamma 2.2
111 }
112 if (!CheckIsHdrSurfaceBuffer(layer->GetBuffer())) {
113 params.brightnessRatio = layer->GetBrightnessRatio();
114 } else {
115 params.isHdrRedraw = true;
116 }
117 #endif
118 DrawHdiLayerWithParams(canvas, layer, params);
119 // Dfx for redraw region
120 auto dstRect = layer->GetLayerSize();
121 if (RSSystemProperties::GetHwcRegionDfxEnabled()) {
122 RectI dst(dstRect.x, dstRect.y, dstRect.w, dstRect.h);
123 RSUniRenderUtil::DrawRectForDfx(canvas, dst, Drawing::Color::COLOR_YELLOW, REDRAW_DFX_ALPHA,
124 layerSurface->GetName());
125 }
126 }
127
128 LayerComposeCollection::GetInstance().UpdateRedrawFrameNumberForDFX();
129 }
130
DrawLayerPreProcess(RSPaintFilterCanvas & canvas,const LayerInfoPtr & layer)131 void RSUniRenderEngine::DrawLayerPreProcess(RSPaintFilterCanvas& canvas, const LayerInfoPtr& layer)
132 {
133 const auto& dstRect = layer->GetLayerSize();
134 const auto& drmCornerRadiusInfo = layer->GetCornerRadiusInfoForDRM();
135 const auto& layerBackgroundColor = layer->GetBackgroundColor();
136 Color backgroundColor = {
137 layerBackgroundColor.r,
138 layerBackgroundColor.g,
139 layerBackgroundColor.b,
140 layerBackgroundColor.a
141 };
142 // clip round rect when drm has radius info
143 if (!drmCornerRadiusInfo.empty()) {
144 auto rect = RectF();
145 rect = {drmCornerRadiusInfo[0], drmCornerRadiusInfo[1], // 0 and 1 represent rect left and top
146 drmCornerRadiusInfo[2], drmCornerRadiusInfo[3]}; // 2 and 3 represent rect width and height
147 Vector4f radiusVector {drmCornerRadiusInfo[4], drmCornerRadiusInfo[5], // 4 and 5 represent corner radius
148 drmCornerRadiusInfo[6], drmCornerRadiusInfo[7]}; // 6 and 7 represent corner radius
149 RRect rrect = RRect(rect, radiusVector);
150 canvas.ClipRoundRect(RSPropertiesPainter::RRect2DrawingRRect(rrect), Drawing::ClipOp::INTERSECT, true);
151 if (backgroundColor != RgbPalette::Transparent()) {
152 canvas.DrawColor(backgroundColor.AsArgbInt());
153 }
154 return;
155 }
156 // draw background color for DRM buffer and then draw layer size image when surface has scaling mode
157 if (layer->GetBuffer() && (layer->GetBuffer()->GetUsage() & BUFFER_USAGE_PROTECTED) &&
158 backgroundColor != RgbPalette::Transparent()) {
159 const auto& boundsRect = layer->GetBoundSize();
160 const auto& layerMatrix = layer->GetMatrix();
161 auto skMatrix = Drawing::Matrix();
162 skMatrix.SetMatrix(layerMatrix.scaleX, layerMatrix.skewX, layerMatrix.transX, layerMatrix.skewY,
163 layerMatrix.scaleY, layerMatrix.transY, layerMatrix.pers0, layerMatrix.pers1, layerMatrix.pers2);
164 Drawing::AutoCanvasRestore acr(canvas, true);
165 canvas.ConcatMatrix(skMatrix);
166 Drawing::Rect drawRect = Drawing::Rect(0.f, 0.f,
167 static_cast<float>(boundsRect.w), static_cast<float>(boundsRect.h));
168 Drawing::Brush rectBrush;
169 rectBrush.SetColor(backgroundColor.AsArgbInt());
170 canvas.AttachBrush(rectBrush);
171 canvas.DrawRect(drawRect);
172 canvas.DetachBrush();
173 }
174 Drawing::Rect clipRect = Drawing::Rect(static_cast<float>(dstRect.x), static_cast<float>(dstRect.y),
175 static_cast<float>(dstRect.w) + static_cast<float>(dstRect.x),
176 static_cast<float>(dstRect.h) + static_cast<float>(dstRect.y));
177 canvas.ClipRect(clipRect, Drawing::ClipOp::INTERSECT, false);
178 }
179
DrawHdiLayerWithParams(RSPaintFilterCanvas & canvas,const LayerInfoPtr & layer,BufferDrawParam & params)180 void RSUniRenderEngine::DrawHdiLayerWithParams(RSPaintFilterCanvas& canvas, const LayerInfoPtr& layer,
181 BufferDrawParam& params)
182 {
183 canvas.ConcatMatrix(params.matrix);
184 if (!params.useCPU) {
185 RegisterDeleteBufferListener(layer->GetSurface(), true);
186 DrawImage(canvas, params);
187 } else {
188 DrawBuffer(canvas, params);
189 }
190 }
191
DrawUIFirstCacheWithParams(RSPaintFilterCanvas & canvas,BufferDrawParam & params)192 void RSUniRenderEngine::DrawUIFirstCacheWithParams(RSPaintFilterCanvas& canvas, BufferDrawParam& params)
193 {
194 if (!params.useCPU) {
195 DrawImage(canvas, params);
196 } else {
197 DrawBuffer(canvas, params);
198 }
199 }
200 } // namespace Rosen
201 } // namespace OHOS
202