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