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