mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-18 06:55:48 +03:00
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:
@@ -133,6 +133,19 @@ class EE_API UISceneNode : public SceneNode {
|
||||
/** @return The explicit viewport size, or the scene extent when no override is set. */
|
||||
const Sizef& getViewportPixelsSize() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the node whose world bounds delimit the visible portion of this scene.
|
||||
*
|
||||
* Embedded scenes can have an extent larger than their host viewport. Binding the visible
|
||||
* bounds to the host's clipping node lets render culling use that viewport while preserving the
|
||||
* full scene extent for layout and scrolling. The node must outlive this scene or clear the
|
||||
* binding before it is destroyed.
|
||||
*/
|
||||
void setVisibleBoundsNode( Node* node );
|
||||
|
||||
/** @return The visible world bounds used for render culling. */
|
||||
const Rectf& getVisibleWorldBounds();
|
||||
|
||||
/**
|
||||
* @brief Sets the layout viewport size used by the scene root as the initial containing block.
|
||||
*
|
||||
@@ -975,6 +988,7 @@ class EE_API UISceneNode : public SceneNode {
|
||||
Uint32 mCurrentMarker{ 0 };
|
||||
Sizef mViewportPixelsSize;
|
||||
bool mHasViewportPixelsSize{ false };
|
||||
Node* mVisibleBoundsNode{ nullptr };
|
||||
Sizef mLayoutViewportPixelsSize;
|
||||
bool mHasLayoutViewportPixelsSize{ false };
|
||||
bool mFollowParentSize{ true };
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -168,6 +168,7 @@ UIWebView::UIWebView() : UIScrollView( "webview" ) {
|
||||
|
||||
mDocumentScene = UISceneNode::New();
|
||||
mDocumentScene->setFollowParentSize( false );
|
||||
mDocumentScene->setVisibleBoundsNode( mContainer );
|
||||
mDocumentScene->setParent( mDocumentLayout );
|
||||
|
||||
mDocContainer = UIWebViewDocumentContainer::New();
|
||||
|
||||
@@ -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>();
|
||||
|
||||
Reference in New Issue
Block a user