1 /*
2 * Copyright (c) 2024 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 "render/rs_high_performance_visual_engine.h"
17 #include "common/rs_optional_trace.h"
18 #include "common/rs_color_palette.h"
19
20 namespace OHOS {
21 namespace Rosen {
22
GetHveFilter()23 HveFilter& HveFilter::GetHveFilter()
24 {
25 static HveFilter filter;
26 return filter;
27 }
28
ClearSurfaceNodeInfo()29 void HveFilter::ClearSurfaceNodeInfo()
30 {
31 surfaceNodeInfo_.clear();
32 }
33
PushSurfaceNodeInfo(SurfaceNodeInfo & surfaceNodeInfo)34 void HveFilter::PushSurfaceNodeInfo(SurfaceNodeInfo& surfaceNodeInfo)
35 {
36 std::lock_guard<std::mutex> lock(hveFilterMtx_);
37 surfaceNodeInfo_.push_back(surfaceNodeInfo);
38 }
39
GetSurfaceNodeInfo() const40 std::vector<SurfaceNodeInfo> HveFilter::GetSurfaceNodeInfo() const
41 {
42 return surfaceNodeInfo_;
43 }
44
GetSurfaceNodeSize() const45 int HveFilter::GetSurfaceNodeSize() const
46 {
47 std::lock_guard<std::mutex> lock(hveFilterMtx_);
48 return surfaceNodeInfo_.size();
49 }
50
SampleLayer(RSPaintFilterCanvas & canvas,const Drawing::RectI & srcRect)51 std::shared_ptr<Drawing::Image> HveFilter::SampleLayer(RSPaintFilterCanvas& canvas, const Drawing::RectI& srcRect)
52 {
53 std::lock_guard<std::mutex> lock(hveFilterMtx_);
54 auto drawingSurface = canvas.GetSurface();
55 if (drawingSurface == nullptr) {
56 ClearSurfaceNodeInfo();
57 return nullptr;
58 }
59 int widthUI = srcRect.GetWidth();
60 int heightUI = srcRect.GetHeight();
61 auto offscreenSurface = drawingSurface->MakeSurface(widthUI, heightUI);
62 if (offscreenSurface == nullptr) {
63 ClearSurfaceNodeInfo();
64 return nullptr;
65 }
66 auto offscreenCanvas = std::make_shared<RSPaintFilterCanvas>(offscreenSurface.get());
67 if (offscreenCanvas == nullptr) {
68 ClearSurfaceNodeInfo();
69 return nullptr;
70 }
71
72 std::shared_ptr<Drawing::Image> snapshot;
73 std::vector<SurfaceNodeInfo> vecSurfaceNode = GetSurfaceNodeInfo();
74 size_t surfaceNodeSize = vecSurfaceNode.size();
75 RS_TRACE_NAME_FMT("surfaceNodeSize:%d", surfaceNodeSize);
76 Drawing::RectI dstRect = Drawing::RectI(0, 0, widthUI, heightUI);
77
78 for (size_t i = 0; i < surfaceNodeSize; i++) {
79 auto surfaceImage = vecSurfaceNode[i].surfaceImage_;
80 Drawing::Matrix rotateMatrix = vecSurfaceNode[i].matrix_;
81 Drawing::Rect parmSrcRect = vecSurfaceNode[i].srcRect_;
82 Drawing::Rect parmDstRect = vecSurfaceNode[i].dstRect_;
83 // Get the color of solidlayer
84 Color solidLayerColor = vecSurfaceNode[i].solidLayerColor_;
85 if (surfaceImage == nullptr) {
86 continue;
87 }
88 // A valid solidlayer color exists.
89 if (solidLayerColor != RgbPalette::Transparent()) {
90 offscreenCanvas->Clear(static_cast<Drawing::ColorQuad>(solidLayerColor.AsArgbInt()));
91 }
92 offscreenCanvas->Save();
93 offscreenCanvas->Translate(-srcRect.GetLeft(), -srcRect.GetTop());
94 offscreenCanvas->ConcatMatrix(rotateMatrix);
95 offscreenCanvas->DrawImageRect(*surfaceImage, parmSrcRect, parmDstRect, Drawing::SamplingOptions(),
96 Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
97 offscreenCanvas->Restore();
98 }
99 ClearSurfaceNodeInfo();
100
101 auto inputImage = drawingSurface->GetImageSnapshot();
102 if (inputImage != nullptr) {
103 offscreenCanvas->DrawImageRect(*inputImage, srcRect, dstRect, Drawing::SamplingOptions(),
104 Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
105 }
106
107 snapshot = offscreenSurface->GetImageSnapshot();
108 return snapshot;
109 }
110 } // namespace Rosen
111 } // namespace OHOS