!10250 修复阴影脏区残留&修复自绘制节点脏区使能后,节点变化时增加上一帧节点脏区

Merge pull request !10250 from chenlushen/0419
This commit is contained in:
openharmony_ci 2024-04-21 07:12:57 +00:00 committed by Gitee
commit 17a0b03606
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 42 additions and 8 deletions

View File

@ -738,7 +738,7 @@ private:
void FallbackAnimationsToRoot();
void FilterModifiersByPid(pid_t pid);
void UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRegion);
bool UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRegion);
void CollectAndUpdateLocalShadowRect();
void CollectAndUpdateLocalOutlineRect();
void CollectAndUpdateLocalPixelStretchRect();
@ -834,6 +834,13 @@ private:
float boundsHeight_ = 0.0f;
bool hasCacheableAnim_ = false;
bool geometryChangeNotPerceived_ = false;
// node region, only used in selfdrawing node dirty
bool isSelfDrawingNode_ = false;
RectF selfDrawingNodeDirtyRect_;
RectI selfDrawingNodeAbsDirtyRect_;
RectI oldAbsDrawRect_;
// used in old pipline
RectI oldRectFromRenderProperties_;
// including enlarged draw region
RectF selfDrawRect_;
RectI localShadowRect_;

View File

@ -1143,6 +1143,7 @@ void RSRenderNode::CollectAndUpdateLocalPixelStretchRect()
void RSRenderNode::UpdateBufferDirtyRegion()
{
#ifndef ROSEN_CROSS_PLATFORM
isSelfDrawingNode_ = false;
if (GetType() != RSRenderNodeType::SURFACE_NODE) {
return;
}
@ -1152,6 +1153,7 @@ void RSRenderNode::UpdateBufferDirtyRegion()
}
auto buffer = surfaceNode->GetBuffer();
if (buffer != nullptr) {
isSelfDrawingNode_ = true;
// Use the matrix from buffer to relative coordinate and the absolute matrix
// to calculate the buffer damageRegion's absolute rect
auto rect = surfaceNode->GetDamageRegion();
@ -1159,7 +1161,11 @@ void RSRenderNode::UpdateBufferDirtyRegion()
auto bufferDirtyRect = GetRenderProperties().GetBoundsGeometry()->MapRect(
RectF(rect.x, rect.y, rect.w, rect.h), matrix).ConvertTo<float>();
// The buffer's dirtyRect should not be out of the scope of the node's dirtyRect
selfDrawRect_ = bufferDirtyRect.IntersectRect(selfDrawRect_);
selfDrawingNodeDirtyRect_ = bufferDirtyRect.IntersectRect(selfDrawRect_);
RS_OPTIONAL_TRACE_NAME_FMT("RSRenderNode id: %" PRIu64 ", buffer size [%d,%d], "
"buffer damageRegion [%d,%d,%d,%d], dirtyRect %s", GetId(),
buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
rect.x, rect.y, rect.w, rect.h, selfDrawingNodeDirtyRect_.ToString().c_str());
}
#endif
}
@ -1204,11 +1210,17 @@ bool RSRenderNode::CheckAndUpdateGeoTrans(std::shared_ptr<RSObjAbsGeometry>& geo
void RSRenderNode::UpdateAbsDirtyRegion(RSDirtyRegionManager& dirtyManager, const RectI& clipRect)
{
dirtyManager.MergeDirtyRect(oldDirty_);
if (isSelfDrawingNode_ && absDrawRect_ != oldAbsDrawRect_) {
// merge self drawing node last frame size and join current frame size to absDrawRect_ when changed
dirtyManager.MergeDirtyRect(oldAbsDrawRect_.IntersectRect(clipRect));
selfDrawingNodeAbsDirtyRect_.JoinRect(absDrawRect_);
oldAbsDrawRect_ = absDrawRect_;
}
// easily merge oldDirty if switch to invisible
if (!shouldPaint_ && isLastVisible_) {
return;
}
auto dirtyRect = absDrawRect_;
auto dirtyRect = isSelfDrawingNode_ ? selfDrawingNodeAbsDirtyRect_ : absDrawRect_;
dirtyRect = dirtyRect.IntersectRect(clipRect);
oldDirty_ = dirtyRect;
oldDirtyInSurface_ = oldDirty_.IntersectRect(dirtyManager.GetSurfaceRect());
@ -1251,8 +1263,12 @@ bool RSRenderNode::UpdateDrawRectAndDirtyRegion(
// planning: double check if it would be covered by updateself without geo update
// currently CheckAndUpdateGeoTrans without dirty check
if (auto geoPtr = properties.boundsGeo_) {
if (CheckAndUpdateGeoTrans(geoPtr) || accumGeoDirty) {
// selfdrawing node's geo may not dirty when its dirty region changes
if (CheckAndUpdateGeoTrans(geoPtr) || accumGeoDirty || isSelfDrawingNode_) {
absDrawRect_ = geoPtr->MapAbsRect(selfDrawRect_);
if (isSelfDrawingNode_) {
selfDrawingNodeAbsDirtyRect_ = geoPtr->MapAbsRect(selfDrawingNodeDirtyRect_);
}
UpdateClipAbsDrawRectChangeState(clipRect);
}
}
@ -1356,15 +1372,15 @@ RSProperties& RSRenderNode::GetMutableRenderProperties()
return renderContent_->GetMutableRenderProperties();
}
void RSRenderNode::UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRegion)
bool RSRenderNode::UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRegion)
{
#ifndef ROSEN_CROSS_PLATFORM
if (GetType() != RSRenderNodeType::SURFACE_NODE) {
return;
return false;
}
auto surfaceNode = ReinterpretCastTo<RSSurfaceRenderNode>();
if (surfaceNode == nullptr) {
return;
return false;
}
auto buffer = surfaceNode->GetBuffer();
if (buffer != nullptr) {
@ -1382,8 +1398,10 @@ void RSRenderNode::UpdateBufferDirtyRegion(RectI& dirtyRect, const RectI& drawRe
"buffer damageRegion [%d,%d,%d,%d], dirtyRect %s", GetId(),
buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(),
rect.x, rect.y, rect.w, rect.h, dirtyRect.ToString().c_str());
return true;
}
#endif
return false;
}
void RSRenderNode::UpdateDirtyRegion(
@ -1412,7 +1430,14 @@ void RSRenderNode::UpdateDirtyRegion(
auto dirtyRect = properties.GetDirtyRect(drawRegion);
auto rectFromRenderProperties = dirtyRect;
// When surface node with buffer has damageRegion, use this instead of the node size
UpdateBufferDirtyRegion(dirtyRect, drawRegion);
if (UpdateBufferDirtyRegion(dirtyRect, drawRegion)) {
// Add node's last and current frame absRect when the node size change
if (rectFromRenderProperties != oldRectFromRenderProperties_) {
dirtyManager.MergeDirtyRect(oldRectFromRenderProperties_);
dirtyRect.JoinRect(rectFromRenderProperties);
oldRectFromRenderProperties_ = rectFromRenderProperties;
}
}
// Add node's shadow region to dirtyRect
if (properties.IsShadowValid()) {
@ -1426,6 +1451,8 @@ void RSRenderNode::UpdateDirtyRegion(
RSPropertiesPainter::GetShadowDirtyRect(shadowRect, properties);
}
if (!shadowRect.IsEmpty()) {
// Avoid deviation caused by converting float to int
shadowRect = shadowRect.MakeOutset({1, 1, 1, 1});
dirtyRect = dirtyRect.JoinRect(shadowRect);
}
}