目标:(十四)中的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、瓦片请求的生成到处理过程详解((十六)中问题)