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、瓦片請求的生成到處理過程詳解((十六)中問題)