1. 程式人生 > >osgEarth的Rex引擎原理分析(十六)請求合併佇列_mergeQueue

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