Added mechanism for tracking when interactive images are being rendered to

enable their backends to only rendered them when they are actively being rendered
in the OpenGL window.
This commit is contained in:
Robert Osfield 2008-11-23 15:51:43 +00:00
parent 8264b31fa1
commit 5b15436935
7 changed files with 95 additions and 11 deletions

View File

@ -33,7 +33,10 @@ osg::Node* createInteractiveQuad(const osg::Vec3& origin, osg::Vec3& widthAxis,
texture, texture,
osg::StateAttribute::ON); osg::StateAttribute::ON);
pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(image)); osg::ref_ptr<osgViewer::InteractiveImageHandler> callback = new osgViewer::InteractiveImageHandler(image);
pictureQuad->setEventCallback(callback.get());
pictureQuad->setCullCallback(callback.get());
osg::Geode* geode = new osg::Geode; osg::Geode* geode = new osg::Geode;
geode->addDrawable(pictureQuad); geode->addDrawable(pictureQuad);

View File

@ -311,11 +311,13 @@ class OSG_EXPORT Image : public Object
/** method for sending pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.*/ /** method for sending pointer events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.*/
virtual void sendPointerEvent(int x, int y, int buttonMask) {}; virtual void sendPointerEvent(int x, int y, int buttonMask) {}
/** method for sending key events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.*/ /** method for sending key events to images that are acting as front ends to interactive surfaces such as a vnc or browser window.*/
virtual void sendKeyEvent(int key, bool keyDown) {}; virtual void sendKeyEvent(int key, bool keyDown) {}
/** method for passing frame information to the custom Image classes, to be called only when objects associated with imagery are not culled.*/
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp) {}
protected : protected :

View File

@ -365,19 +365,27 @@ class OSGVIEWER_EXPORT ScreenCaptureHandler : public osgGA::GUIEventHandler
/** InteractiveImage is an event handler that computes the mouse coordinates in an images coordinate frame /** InteractiveImage is an event handler that computes the mouse coordinates in an images coordinate frame
* and then passes keyboard and mouse events to it. This event handler is useful for vnc or browser * and then passes keyboard and mouse events to it. This event handler is useful for vnc or browser
* surfaces in the 3D scene.*/ * surfaces in the 3D scene.*/
class OSGVIEWER_EXPORT InteractiveImageHandler : public osgGA::GUIEventHandler class OSGVIEWER_EXPORT InteractiveImageHandler : public osgGA::GUIEventHandler, public osg::Drawable::CullCallback
{ {
public: public:
InteractiveImageHandler(osg::Image* image): InteractiveImageHandler(osg::Image* image):
_image(image) {} _image(image) {}
META_Object(osgViewer, InteractiveImageHandler);
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv); virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv);
virtual bool cull(osg::NodeVisitor* nv, osg::Drawable* drawable, osg::RenderInfo* renderInfo) const;
protected: protected:
virtual ~InteractiveImageHandler() {} virtual ~InteractiveImageHandler() {}
InteractiveImageHandler() {}
InteractiveImageHandler(const InteractiveImageHandler& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {}
bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const; bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const;
osg::observer_ptr<osg::Image> _image; osg::observer_ptr<osg::Image> _image;

View File

@ -105,7 +105,10 @@ class ReaderWriterUBrowser : public osgDB::ReaderWriter
texture, texture,
osg::StateAttribute::ON); osg::StateAttribute::ON);
pictureQuad->setEventCallback(new osgViewer::InteractiveImageHandler(image)); osg::ref_ptr<osgViewer::InteractiveImageHandler> callback = new osgViewer::InteractiveImageHandler(image);
pictureQuad->setEventCallback(callback.get());
pictureQuad->setCullCallback(callback.get());
osg::Geode* geode = new osg::Geode; osg::Geode* geode = new osg::Geode;
geode->addDrawable(pictureQuad); geode->addDrawable(pictureQuad);

View File

@ -214,21 +214,36 @@ struct UpdateOperation : public osg::Operation
std::back_inserter(images)); std::back_inserter(images));
} }
int numUpdated = 0;
for(RefImageList::iterator itr = images.begin(); for(RefImageList::iterator itr = images.begin();
itr != images.end(); itr != images.end();
++itr) ++itr)
{ {
update(itr->get()); if (update(itr->get())) ++numUpdated;
} }
// osg::notify(osg::NOTICE)<<"complted Update"<<std::endl; if (numUpdated==0)
{
//osg::notify(osg::NOTICE)<<"completed Update but no images updated"<<std::endl;
OpenThreads::Thread::YieldCurrentThread();
}
else
{
//osg::notify(osg::NOTICE)<<"completed Updated "<<numUpdated<<std::endl;
}
} }
void update(UBrowserImage* image) bool update(UBrowserImage* image)
{ {
if (!image) return; if (!image) return false;
double deltaTime = image->getTimeOfLastRender() - image->getTimeOfLastUpdate();
if (deltaTime<0.0)
{
return false;
}
int id = image->getBrowserWindowId(); int id = image->getBrowserWindowId();
@ -272,8 +287,12 @@ struct UpdateOperation : public osg::Operation
(unsigned char*)LLMozLib::getInstance()->getBrowserWindowPixels( id ), (unsigned char*)LLMozLib::getInstance()->getBrowserWindowPixels( id ),
osg::Image::NO_DELETE); osg::Image::NO_DELETE);
image->updated();
// _needsUpdate = false; // _needsUpdate = false;
} }
return true;
} }
}; };
@ -465,6 +484,8 @@ void UBrowserManager::sendPointerEvent(UBrowserImage* image, int x, int y, int b
_previousButtonMask = buttonMask; _previousButtonMask = buttonMask;
_thread->add(new PointerEventOperation(image, x, y, deltaButton)); _thread->add(new PointerEventOperation(image, x, y, deltaButton));
active(image);
} }
@ -496,6 +517,7 @@ void UBrowserManager::sendKeyEvent(UBrowserImage* image, int key, bool keyDown)
if (_keyMap.find(key)==_keyMap.end()) _thread->add(new KeyEventOperation(image, key, true)); if (_keyMap.find(key)==_keyMap.end()) _thread->add(new KeyEventOperation(image, key, true));
else _thread->add(new KeyEventOperation(image, itr->second, false)); else _thread->add(new KeyEventOperation(image, itr->second, false));
active(image);
} }
@ -519,6 +541,12 @@ struct NavigateToOperation : public osg::Operation
void UBrowserManager::navigateTo(UBrowserImage* image, const std::string& url) void UBrowserManager::navigateTo(UBrowserImage* image, const std::string& url)
{ {
_thread->add(new NavigateToOperation(image, url)); _thread->add(new NavigateToOperation(image, url));
active(image);
}
void UBrowserManager::active(UBrowserImage* image)
{
} }
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
@ -527,7 +555,9 @@ void UBrowserManager::navigateTo(UBrowserImage* image, const std::string& url)
UBrowserImage::UBrowserImage(UBrowserManager* manager, const std::string& homeURL, int width, int height): UBrowserImage::UBrowserImage(UBrowserManager* manager, const std::string& homeURL, int width, int height):
_browserWindowId(0), _browserWindowId(0),
_needsUpdate(true) _needsUpdate(true),
_timeOfLastUpdate(0.0),
_timeOfLastRender(0.0)
{ {
_manager = manager; _manager = manager;
@ -562,6 +592,18 @@ void UBrowserImage::sendKeyEvent(int key, bool keyDown)
_manager->sendKeyEvent(this, key, keyDown); _manager->sendKeyEvent(this, key, keyDown);
} }
void UBrowserImage::setFrameLastRendered(const osg::FrameStamp*)
{
_timeOfLastRender = time();
_manager->active(this);
}
void UBrowserImage::updated()
{
_timeOfLastUpdate = time();
}
void UBrowserImage::navigateTo(const std::string& url) void UBrowserImage::navigateTo(const std::string& url)
{ {
_manager->navigateTo(this, url); _manager->navigateTo(this, url);

View File

@ -17,6 +17,7 @@
#include <osgWidget/Browser> #include <osgWidget/Browser>
#include <osg/OperationThread> #include <osg/OperationThread>
#include <osg/Timer>
#include <list> #include <list>
#include <algorithm> #include <algorithm>
@ -70,6 +71,8 @@ class UBrowserManager : public osgWidget::BrowserManager
OpenThreads::Mutex _ubrowserImageListMutex; OpenThreads::Mutex _ubrowserImageListMutex;
UBrowserImageList _ubrowserImageList; UBrowserImageList _ubrowserImageList;
void active(UBrowserImage* image);
protected: protected:
UBrowserManager(const UBrowserManager& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {} UBrowserManager(const UBrowserManager& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {}
@ -109,9 +112,12 @@ class UBrowserImage : public osgWidget::BrowserImage, public LLEmbeddedBrowserWi
virtual void sendKeyEvent(int key, bool keyDown); virtual void sendKeyEvent(int key, bool keyDown);
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp);
virtual void navigateTo(const std::string& url); virtual void navigateTo(const std::string& url);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// virtual // virtual
void onPageChanged( const EventType& eventIn ) void onPageChanged( const EventType& eventIn )
@ -168,6 +174,13 @@ class UBrowserImage : public osgWidget::BrowserImage, public LLEmbeddedBrowserWi
osg::ref_ptr<UBrowserManager> _manager; osg::ref_ptr<UBrowserManager> _manager;
void updated();
double getTimeOfLastUpdate() const { return _timeOfLastUpdate; }
double getTimeOfLastRender() const { return _timeOfLastRender; }
double time() const { return osg::Timer::instance()->time_s(); }
protected: protected:
virtual ~UBrowserImage(); virtual ~UBrowserImage();
@ -175,6 +188,9 @@ class UBrowserImage : public osgWidget::BrowserImage, public LLEmbeddedBrowserWi
int _browserWindowId; int _browserWindowId;
bool _needsUpdate; bool _needsUpdate;
std::string _homeURL; std::string _homeURL;
double _timeOfLastUpdate;
double _timeOfLastRender;
}; };
#endif #endif

View File

@ -731,4 +731,14 @@ bool InteractiveImageHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUI
return false; return false;
} }
bool InteractiveImageHandler::cull(osg::NodeVisitor* nv, osg::Drawable*, osg::RenderInfo*) const
{
if (_image.valid())
{
_image->setFrameLastRendered(nv->getFrameStamp());
}
return false;
}
} }