Fixed a regression in UIWebView that caused to basically don't have render culling:

- Added UISceneNode::getVisibleWorldBounds() with an optional bounds-node binding.
  - UIWebView binds its document scene to the scroll container’s clipped viewport.
  - UINode::nodeDraw() now culls against visible scene bounds instead of the full document extent.
  - Existing top-level scenes retain their previous behavior.
  - Added a regression test confirming offscreen document widgets are skipped and visible widgets render.
This commit is contained in:
Martín Lucas Golini
2026-08-01 01:16:13 -03:00
parent 24302ec9f1
commit 323d511eed
5 changed files with 47 additions and 1 deletions
+1 -1
View File
@@ -1113,7 +1113,7 @@ void UINode::nodeDraw() {
smartClipStart( ClipType::BorderBox, needsClipPlanes );
bool intersected = mWorldBounds.intersect( mSceneNode->getWorldBounds() );
bool intersected = mWorldBounds.intersect( mUISceneNode->getVisibleWorldBounds() );
if ( intersected ) {
smartClipStart( ClipType::ContentBox, needsClipPlanes );
+8
View File
@@ -1075,6 +1075,14 @@ const Sizef& UISceneNode::getViewportPixelsSize() const {
return mHasViewportPixelsSize ? mViewportPixelsSize : getPixelsSize();
}
void UISceneNode::setVisibleBoundsNode( Node* node ) {
mVisibleBoundsNode = node;
}
const Rectf& UISceneNode::getVisibleWorldBounds() {
return mVisibleBoundsNode ? mVisibleBoundsNode->getWorldBounds() : getWorldBounds();
}
void UISceneNode::setLayoutViewportPixelsSize( const Sizef& size ) {
if ( mHasLayoutViewportPixelsSize && mLayoutViewportPixelsSize == size )
return;
+1
View File
@@ -168,6 +168,7 @@ UIWebView::UIWebView() : UIScrollView( "webview" ) {
mDocumentScene = UISceneNode::New();
mDocumentScene->setFollowParentSize( false );
mDocumentScene->setVisibleBoundsNode( mContainer );
mDocumentScene->setParent( mDocumentLayout );
mDocContainer = UIWebViewDocumentContainer::New();
+23
View File
@@ -43,6 +43,15 @@ using namespace EE::Window;
using namespace EE::Scene;
using namespace EE::UI;
class CountingDrawWidget : public UIWidget {
public:
static CountingDrawWidget* New() { return eeNew( CountingDrawWidget, () ); }
void draw() override { drawCount++; }
int drawCount{ 0 };
};
static bool readHttpRequestHeaders( TcpSocket& client, std::string* headers = nullptr ) {
std::string request;
char buffer[1024];
@@ -144,6 +153,20 @@ UTEST( UIWebView, OwnedDocumentSceneScrollTarget ) {
EXPECT_NEAR( documentScene->getViewportPixelsSize().getHeight(), 300.f, 1.f );
EXPECT_GT( documentScene->getPixelsSize().getHeight(), 1000.f );
EXPECT_TRUE( webView->getVerticalScrollBar()->isVisible() );
EXPECT_TRUE( documentScene->getVisibleWorldBounds() ==
webView->getContainer()->getWorldBounds() );
EXPECT_LT( documentScene->getVisibleWorldBounds().getHeight(),
documentScene->getWorldBounds().getHeight() );
auto* drawProbe = CountingDrawWidget::New();
drawProbe->setPixelsSize( 20.f, 20.f );
drawProbe->setPixelsPosition( 10.f, 700.f );
drawProbe->setParent( documentScene->getRoot() );
drawProbe->nodeDraw();
EXPECT_EQ( drawProbe->drawCount, 0 );
drawProbe->setPixelsPosition( 10.f, 10.f );
drawProbe->nodeDraw();
EXPECT_EQ( drawProbe->drawCount, 1 );
ASSERT_TRUE( documentScene->getParent() != nullptr && documentScene->getParent()->isUINode() );
UINode* scrollTarget = documentScene->getParent()->asType<UINode>();