• 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 "rs_uni_render_util.h"
17 
18 #include "pipeline/rs_base_render_util.h"
19 #include "pipeline/rs_main_thread.h"
20 #include "platform/common/rs_log.h"
21 
22 namespace OHOS {
23 namespace Rosen {
UpdateRenderNodeDstRect(RSRenderNode & node,const SkMatrix & matrix)24 void RSUniRenderUtil::UpdateRenderNodeDstRect(RSRenderNode& node, const SkMatrix& matrix)
25 {
26     // [planning] use RSRenderNode::Update instead
27     auto parentNode = node.GetParent().lock();
28     if (!parentNode) {
29         RS_LOGE("RSUniRenderUtil::UpdateDstRect: fail to get parent dstRect.");
30         return;
31     }
32     auto rsParent = parentNode->ReinterpretCastTo<RSRenderNode>();
33     auto parentProp = rsParent ? &(rsParent->GetRenderProperties()) : nullptr;
34     auto& property = node.GetMutableRenderProperties();
35     auto surfaceNode = node.ReinterpretCastTo<RSSurfaceRenderNode>();
36     auto isSelfDrawingNode = surfaceNode &&
37         (surfaceNode->GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE ||
38         surfaceNode->GetSurfaceNodeType() == RSSurfaceNodeType::ABILITY_COMPONENT_NODE);
39     Vector2f offset(0.f, 0.f);
40     if (isSelfDrawingNode) {
41         offset = { parentProp->GetFrameOffsetX(), parentProp->GetFrameOffsetY() };
42     }
43     property.UpdateGeometry(parentProp, true, offset);
44     auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(property.GetBoundsGeometry());
45     if (geoPtr && node.IsInstanceOf<RSSurfaceRenderNode>()) {
46         if (!isSelfDrawingNode) {
47             geoPtr->ConcatMatrix(matrix);
48         }
49         RS_LOGD("RSUniRenderUtil::UpdateDstRect: nodeName: %s, dstRect[%s].",
50             surfaceNode->GetName().c_str(), surfaceNode->GetDstRect().ToString().c_str());
51     }
52 }
53 
MergeDirtyHistory(std::shared_ptr<RSDisplayRenderNode> & node,int32_t bufferAge)54 void RSUniRenderUtil::MergeDirtyHistory(std::shared_ptr<RSDisplayRenderNode>& node, int32_t bufferAge)
55 {
56     // update all child surfacenode history
57     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
58         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
59         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
60             continue;
61         }
62         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
63         if (!surfaceDirtyManager->SetBufferAge(bufferAge)) {
64             ROSEN_LOGE("RSUniRenderUtil::MergeVisibleDirtyRegion with invalid buffer age %d", bufferAge);
65         }
66         surfaceDirtyManager->IntersectDirtyRect(surfaceNode->GetOldDirtyInSurface());
67         surfaceDirtyManager->UpdateDirty();
68         if (surfaceNode->GetDstRect().IsInsideOf(surfaceDirtyManager->GetDirtyRegion())
69             && surfaceNode->HasContainerWindow()) {
70             node->GetDirtyManager()->MergeDirtyRect(surfaceNode->GetDstRect());
71         }
72     }
73     // update display dirtymanager
74     node->UpdateDisplayDirtyManager(bufferAge);
75 }
76 
MergeVisibleDirtyRegion(std::shared_ptr<RSDisplayRenderNode> & node)77 Occlusion::Region RSUniRenderUtil::MergeVisibleDirtyRegion(std::shared_ptr<RSDisplayRenderNode>& node)
78 {
79     Occlusion::Region allSurfaceVisibleDirtyRegion;
80     for (auto it = node->GetCurAllSurfaces().rbegin(); it != node->GetCurAllSurfaces().rend(); ++it) {
81         auto surfaceNode = RSBaseRenderNode::ReinterpretCast<RSSurfaceRenderNode>(*it);
82         if (surfaceNode == nullptr || !surfaceNode->IsAppWindow()) {
83             continue;
84         }
85         auto surfaceDirtyManager = surfaceNode->GetDirtyManager();
86         auto surfaceDirtyRect = surfaceDirtyManager->GetDirtyRegion();
87         Occlusion::Rect dirtyRect { surfaceDirtyRect.left_, surfaceDirtyRect.top_,
88             surfaceDirtyRect.GetRight(), surfaceDirtyRect.GetBottom() };
89         auto visibleRegion = surfaceNode->GetVisibleRegion();
90         Occlusion::Region surfaceDirtyRegion { dirtyRect };
91         Occlusion::Region surfaceVisibleDirtyRegion = surfaceDirtyRegion.And(visibleRegion);
92         surfaceNode->SetVisibleDirtyRegion(surfaceVisibleDirtyRegion);
93         allSurfaceVisibleDirtyRegion = allSurfaceVisibleDirtyRegion.Or(surfaceVisibleDirtyRegion);
94     }
95     return allSurfaceVisibleDirtyRegion;
96 }
97 
CreateBufferDrawParam(const RSSurfaceRenderNode & node,bool forceCPU)98 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSSurfaceRenderNode& node, bool forceCPU)
99 {
100     BufferDrawParam params;
101 #ifdef RS_ENABLE_EGLIMAGE
102     params.useCPU = forceCPU;
103 #else // RS_ENABLE_EGLIMAGE
104     params.useCPU = true;
105 #endif // RS_ENABLE_EGLIMAGE
106     params.paint.setAntiAlias(true);
107     params.paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
108 
109     const RSProperties& property = node.GetRenderProperties();
110     params.dstRect = SkRect::MakeWH(property.GetBoundsWidth(), property.GetBoundsHeight());
111 
112     const sptr<SurfaceBuffer>& buffer = node.GetBuffer();
113     params.buffer = buffer;
114     params.acquireFence = node.GetAcquireFence();
115     params.srcRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
116 
117     RectF localBounds = {0.0f, 0.0f, property.GetBoundsWidth(), property.GetBoundsHeight()};
118     RSBaseRenderUtil::FlipMatrix(node, params);
119     RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(node, localBounds, params);
120     return params;
121 }
122 
CreateBufferDrawParam(const RSDisplayRenderNode & node,bool forceCPU)123 BufferDrawParam RSUniRenderUtil::CreateBufferDrawParam(const RSDisplayRenderNode& node, bool forceCPU)
124 {
125     BufferDrawParam params;
126 #ifdef RS_ENABLE_EGLIMAGE
127     params.useCPU = forceCPU;
128 #else // RS_ENABLE_EGLIMAGE
129     params.useCPU = true;
130 #endif // RS_ENABLE_EGLIMAGE
131     params.paint.setAntiAlias(true);
132     params.paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
133 
134     const sptr<SurfaceBuffer>& buffer = node.GetBuffer();
135     params.buffer = buffer;
136     params.acquireFence = node.GetAcquireFence();
137     params.srcRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
138     params.dstRect = SkRect::MakeWH(buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight());
139     return params;
140 }
141 
DrawCachedSurface(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,sk_sp<SkSurface> surface)142 void RSUniRenderUtil::DrawCachedSurface(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas,
143     sk_sp<SkSurface> surface)
144 {
145     if (surface == nullptr) {
146         return;
147     }
148     canvas.save();
149     canvas.scale(node.GetRenderProperties().GetBoundsWidth() / surface->width(),
150         node.GetRenderProperties().GetBoundsHeight() / surface->height());
151     SkPaint paint;
152     surface->draw(&canvas, 0.0, 0.0, &paint);
153     canvas.restore();
154 }
155 
DrawCachedImage(RSSurfaceRenderNode & node,RSPaintFilterCanvas & canvas,sk_sp<SkImage> image)156 void RSUniRenderUtil::DrawCachedImage(RSSurfaceRenderNode& node, RSPaintFilterCanvas& canvas, sk_sp<SkImage> image)
157 {
158     if (image == nullptr) {
159         return;
160     }
161     canvas.save();
162     canvas.scale(node.GetRenderProperties().GetBoundsWidth() / image->width(),
163         node.GetRenderProperties().GetBoundsHeight() / image->height());
164     SkPaint paint;
165     canvas.drawImage(image.get(), 0.0, 0.0, &paint);
166     canvas.restore();
167 }
168 
ReleaseBuffer(RSSurfaceHandler & surfaceHandler)169 bool RSUniRenderUtil::ReleaseBuffer(RSSurfaceHandler& surfaceHandler)
170 {
171     auto& consumer = surfaceHandler.GetConsumer();
172     if (consumer == nullptr) {
173         return false;
174     }
175 
176     auto& preBuffer = surfaceHandler.GetPreBuffer();
177     if (preBuffer.buffer != nullptr) {
178         static bool firstEntry = true;
179         static std::function<void()> firstBufferRelease = nullptr;
180         if (firstEntry) {
181             // In order to avoid waiting for buffers' fence, we delay the first ReleaseBuffer to alloc 3 buffers.
182             // [planning] delete this function after Repaint parallelization.
183             firstEntry = false;
184             firstBufferRelease = [consumer, buffer = preBuffer.buffer, fence = preBuffer.releaseFence]() mutable {
185                 auto ret = consumer->ReleaseBuffer(buffer, fence);
186                 if (ret != OHOS::SURFACE_ERROR_OK) {
187                     RS_LOGE("RsDebug firstBufferRelease failed(ret: %d)!", ret);
188                 }
189             };
190             preBuffer.Reset();
191             return true;
192         }
193         if (firstBufferRelease) {
194             firstBufferRelease();
195             firstBufferRelease = nullptr;
196         }
197         auto ret = consumer->ReleaseBuffer(preBuffer.buffer, preBuffer.releaseFence);
198         if (ret != OHOS::SURFACE_ERROR_OK) {
199             RS_LOGE("RsDebug surfaceHandler(id: %" PRIu64 ") ReleaseBuffer failed(ret: %d)!",
200                 surfaceHandler.GetNodeId(), ret);
201             return false;
202         }
203         // reset prevBuffer if we release it successfully,
204         // to avoid releasing the same buffer next frame in some situations.
205         preBuffer.Reset();
206     }
207 
208     return true;
209 }
210 } // namespace Rosen
211 } // namespace OHOS
212