osgEarth的Rex引擎原理分析(十六)请求合并队列_mergeQueue

目标:(十四)中的33

请求合并队列_mergeQueue是在帧循环的更新遍历时构建的。这个是有分页数据库DatabasePager的更新遍历实现的,而不是依靠场景树节点的更新遍历。

osgEarthDrivers/engine_rex/Loader.cpp
bool
PagerLoader::addChild(osg::Node* node)
{
    osg::ref_ptr<RequestResultNode> result = dynamic_cast<RequestResultNode*>(node);

    Request* req = result->getRequest();

    _mergeQueue.insert( req );
                    
}

那么,分页数据库DatabasePager又是如何知道要往请求合并队列_mergeQueue添加哪些请求呢。在分页数据库DatabasePager的addLoadedDataToSceneGraph中有(这个函数是在更新遍历DatabasePager中调用的):

osgDB/DatabasePager.cpp
void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp)
{
    _dataToMergeList->swap(localFileLoadedList);
    for(RequestQueue::RequestList::iterator itr=localFileLoadedList.begin();
        itr!=localFileLoadedList.end();
        ++itr)
    {
        DatabaseRequest* databaseRequest = itr->get();
        group->addChild(databaseRequest->_loadedModel.get());
    }
}

注意到,这里有_dataToMergeList,DatabasePager最终就是将这里面的内容添加到请求合并队列_mergeQueue中的。

问题又来了,这个_dataToMergeList又是怎么来的呢?

原来DatabasePager中有一个运行线程,他会从DatabasePager中的_fileRequestQueue队列中读取请求信息,它将请求信息处理后放入到分页加载器的_dataToMergeList中。

osgDB/DatabasePager.cpp

void DatabasePager::DatabaseThread::run()
{
    read_queue = _pager->_fileRequestQueue;

    osg::ref_ptr<DatabaseRequest> databaseRequest;
    read_queue->takeFirst(databaseRequest);

    _pager->_dataToMergeList->addNoLock(databaseRequest.get());
}

那么这个_fileRequestQueue队列中的数据又是怎么来的呢?简单的说,是osgEarth::Drivers::RexTerrainEngine::TileNode节点在渲染阶段的裁剪时产生的。osg::ref_ptr<ReadQueue> _fileRequestQueue;

osgDB/DatabasePager
struct OSGDB_EXPORT ReadQueue : public RequestQueue
        {}

osgDB/DatabasePager.cpp
void DatabasePager::RequestQueue::addNoLock(DatabasePager::DatabaseRequest* databaseRequest)
{
    _requestList.push_back(databaseRequest);
    updateBlock();
}

那么问题又来了,osgEarth::Drivers::RexTerrainEngine::TileNode节点是什么时候创建的?(可以参考问题30的分析)

总结一下是这样的一个流程:

1、osgEarth::Drivers::RexTerrainEngine::TileNode在渲染遍历时产生请求,并将此请求放入了DatabasePager的_fileRequestQueue队列中

2、DatabasePager的运行线程DatabaseThread又将请求放入DatabasePager的_dataToMergeList的队列中

3、在更新遍历DatabasePager时,将其_dataToMergeList列表中的请求,放入瓦片分页加载器的_mergeQueue队列中

4、在更新遍历时瓦片分页加载器处理_mergeQueue中的请求

当然这个流程中的很多细节问题还是需要深究的,另外专门开设一篇博文详解吧。

待继续分析列表:

9、earth文件中都有哪些options((九)中问题)

10、如何根据earth文件options创建不同的地理信息引擎节点((九)中问题)

11、rex地理信息引擎的四梁八柱((九)中问题)

12、osgEarth::TerrainEngineNode中setMap方法作用((十二)中问题)

13、RexTerrainEngineNode中_mapFrame的作用((十二)中问题)

14、地形变形(Terrain morphing)((十二)中问题)

15、地球瓦片过期门限的含义((十二)中问题)

16、高分辨率优先的含义((十二)中问题)

17、OSGEARTH_DEBUG_NORMALS环境变量的作用((十二)中问题)

18、活跃瓦片寄存器的作用((十二)中问题)

19、资源释放器子节点的作用((十二)中问题)

20、共享几何图形池子节点的作用((十二)中问题)

21、分页瓦片加载器子节点的作用((十二)中问题)

22、分页瓦片卸载器子节点的作用((十二)中问题)

23、栅格化器子节点的作用((十二)中问题)

24、地形子节点的作用((十二)中问题)

25、绑定渲染器的作用((十二)中问题)

26、地图回调函数的作用((十二)中问题)

27、如何将地图图层添加到rex引擎中((十二)中问题)

28、选择信息的作用((十二)中问题)

29、瓦片包围盒修改回调函数的作用((十二)中问题)

30、刷新rex引擎((十二)中问题)

31、刷新边界作用((十二)中问题)

32、osgEarth::Metrics类的意义((十四)中问题)

33、请求合并队列_mergeQueue((十四)中问题)

34、分页瓦片加载器在更新遍历时对请求处理过程((十四)中问题)

35、分页瓦片加载器在更新遍历时对已处理请求裁剪过程((十四)中问题)

36、已处理的请求队列_requests((十四)中问题)

37、DatabasePager中的_fileRequestQueue和_httpRequestQueue((十六)中问题)

38、瓦片请求的生成到处理过程详解((十六)中问题)

猜你喜欢

转载自blog.csdn.net/hankern/article/details/84195774