青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

麒麟子

~~

導(dǎo)航

<2010年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

統(tǒng)計

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

Friends

WebSites

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

OGRE3D 渲染系統(tǒng)線程化

先前研究渲染系統(tǒng)線程化的時候翻到了這篇文章,于是一邊看一邊寫出了漢語。 文中寫多地方翻譯得很不通順,見諒。

 

譯者序:偶然在網(wǎng)上看到這篇文章,自己很想仔細(xì)研究一下。但搜尋半天不見中文版。于是自己斗膽翻譯了一下。文中不免有漏洞百出,甚至可以說有些地方不及Google翻譯得好。但這樣總的來說是出了一個中文版,而我自己在翻譯過程中也會停下來仔細(xì)思考。

OGRE這個線程化的文章很老了。因為OGRE目前已經(jīng)支持多線程渲染。 這篇文章貌似是某些人研究出來的三個線程化方案,并給出了測試結(jié)果。以向OGRE社區(qū)證明線程化方案的可行性。 對于許多想研究渲染線程化的人來說,是一篇值得參考的文章。文中提出了許多在不同情況下線程化時遇到的問題,以及需要注意的問題。值得一讀/

介紹

OGRE3D(a.k.a. Ogre)是目前最常用的開放源代碼 3D 引擎之一。它是一款功能完善的通用 3D 引擎,可應(yīng)用于從游戲到科學(xué)模擬等多種商用產(chǎn)品。該引擎由來自開放源代碼社區(qū)的數(shù)百名技術(shù)人員歷經(jīng)五年時間而開發(fā)成功。如欲了解 Ogre 的詳細(xì)信息,請訪問網(wǎng)站 www.ogre3d.org 。

然而,盡管 Ogre 功能強(qiáng)大,但是它卻在技術(shù)上存在一個重要缺憾,那就是它無法在系統(tǒng)中充分利用多個處理器的優(yōu)勢。目前,英特爾已經(jīng)有多款雙核產(chǎn)品上市,而超線程(HT)技術(shù)更是在多年前就已應(yīng)用在英特爾&reg; 奔騰&reg; 4 處理器中。將 Ogre 線程化所實現(xiàn)的性能增益將絲毫不遜色于添加第二枚處理器所實現(xiàn)的性能增益。

本文將向您介紹將 Ogre 渲染系統(tǒng)線程化的三種不同處理方法,并且我們將根據(jù)下文所描述的線程化目的,選擇一種方法進(jìn)行完整實施。

線程化目標(biāo)

當(dāng)我們在對OGRE線程化時,需要實現(xiàn)以下幾個目標(biāo):

·通過改動最少的OGRE源碼以使OGRE社區(qū)接受。

·在雙核處理器上,相對于非線程化渲染的OGRE系統(tǒng)來說,提升25%的FPS,以平衡應(yīng)用程序的CPU和GPU使用率

·在用戶不知道的情況下對SDK包中的DEMO進(jìn)行必要的變動,而不讓用戶在畫面上有任何察覺。

假設(shè)

本文提及了OGRE中的許多類,以及使用了OGRE中的許多程序片段。所以,這里假設(shè)讀者都是對OGRE的源碼非常了解或者已經(jīng)對源碼進(jìn)行過快速的查閱,否則將很難理解這些OGRE的特性。同樣,讀者也應(yīng)該對線程的概念有所了解。這里就不再介紹更多關(guān)于線程的內(nèi)容。

限制

這里所討論的所有實現(xiàn),都沒有在超過兩個處理器的機(jī)器上實驗過。因此,這些技術(shù)對于雙核處理器或雙核心系統(tǒng)最適合不過。以后的文章中將會討論如何在OGRE中創(chuàng)建一個線程隊列,使OGRE以及使用OGRE的應(yīng)用程序都能夠在雙核處理器以及多核上得到性能的提升。

線程化OGRE渲染系統(tǒng)使用到的技術(shù)

OGRE中有很多地方都可以被線程化,但線程化最能在多核上提升性能的是渲染系統(tǒng)。渲染系統(tǒng)在OGRE占據(jù)了巨大的一塊,并且從某種意義上講,它能單獨地被外部程序訪問。下面介紹三種將OGRE渲染系統(tǒng)線程化的例子。

1、 在OGRE中對于渲染的調(diào)用可以被放在他自己的線程中。

2、 一個線程化層可以被放在OgreMain和渲染系統(tǒng)插件之間。

3、 渲染系統(tǒng)插件可以單開一個線程來調(diào)用圖形API。

上面這三種方案都有各自的優(yōu)缺點,本文將會一一討論。

線程化并不會對每個應(yīng)用程序有利

注意,線程化只對那種花費在圖形調(diào)用API和邏輯處理上的時間很接近的應(yīng)用程序有好處。若其中一個較另一個差別很大,則看不到明顯的效果。

技術(shù)方案1:線程化OgreMain(高級線程化手段)

在OgreMain中進(jìn)行線程化是一種最高級的線程化手段,也表示能獲得最高級的潛在性能。這是因為Ogre在做一次渲染的時候,需要做很多事情,并且不僅僅是提交某些命令或數(shù)據(jù)到顯卡。比如,決定哪個攝相機(jī)是活動攝相機(jī),遍歷場景中所有可見物體,標(biāo)志所有可見物體去渲染,等等。 下面的插圖展示了一個Ogre渲染過程(為了簡化起見,一些東西被忽略)。高級線程化將導(dǎo)致這里所有的過程被放置在他自己的線程里。

clip_image002

線程化問題

采用這種方案有一個主要的問題就是,兩個線程中將會發(fā)生代碼重疊。打個比方,主線程和渲染線程都需要訪問場景中某個場景對象的相同數(shù)據(jù)。主線程要更新它的位置和方向,然而此時渲染線程要讀這些信息或者在渲染線程渲染前主線程修改了這些內(nèi)容。從而導(dǎo)致渲染幀的內(nèi)容與實際不符,會相差一幀。特別地,當(dāng)渲染在渲染一個對象時主線程卻要把它刪除,就會出問題。如下圖所示:

clip_image004

除了剛剛提到的線程自身的問題外,同樣也存在處理器共享失敗的問題。當(dāng)一個變量被一個線程更新的時候,這個變量是處于這個線程所在的CPU緩存行中的,而另外一個線程也會訪問這個緩存行中的內(nèi)容的相同數(shù)據(jù)。由于它們共享緩存行,一個處理器需要清空整個緩存行,不管其它處理器是否做了修改。這就是這個高級線程方方案的問題所在。因為主線程和渲染線程使用同樣的類的實例。 由于類體變量被相繼地放置在內(nèi)存中,因此他們要共享同樣的緩存行。關(guān)于更多緩存行共享失敗的問題。可以查看相關(guān)文章。

避免問題

為了避免上面提到的線程問題,這里提供了兩個可以安全訪問和更新對象的解決方案。

1、 使用一個更新隊列。

2、 復(fù)制對象

更新隊列的方案通過維持一個對象的更新隊列來防止訪問重疊。見下圖。 更新將只發(fā)生一次,即當(dāng)主線程準(zhǔn)備讓渲染線程開始渲染的時候。當(dāng)然,你需要等待渲染線程完成后才能進(jìn)行第二次啟用。這個方案有一個缺點,就是單處理系統(tǒng)上的CPU反而會承受這個更新隊列的額外負(fù)擔(dān),而享受不到這個更新隊列的好處。另一個缺點就是,當(dāng)對硬件資源(如索引,頂點緩沖等)改變時。排隊改變這些資源將會很困難,因為這些數(shù)據(jù)都非常大。

clip_image006

復(fù)制對象的方案從本質(zhì)上講,就是為一個經(jīng)常變動的對象復(fù)制副本。在這種方案下,使用OGRE的應(yīng)用程序?qū)⒈灰髲?fù)制一個經(jīng)常需要更新的對象,因為只有它知道哪些對象是需要經(jīng)常更新的。應(yīng)用程序也不得不按照一定的方式來寫:對象的處理是在對象被顯示后的下一幀。(這點沒有太明白,貌似意思是說,對象的處理和渲染為兩個幀,一個幀拿來渲染,一個幀拿來處理,看到下面那圖應(yīng)該是這個意思)。當(dāng)然,如果你的應(yīng)用程序并不每幀更新對象,這也是一個問題,在這種情況下,你的對象有可能是在幾幀后才被訪問,這樣就會導(dǎo)致沖突。也可以對其做一些優(yōu)化,如只有對象中主線程和渲染線程要共享的數(shù)據(jù)才被復(fù)制,以此來減少負(fù)擔(dān)。在這樣的情況下對象將不再是一個復(fù)制品,但是將會有一個雙緩沖用于存放你復(fù)制的這些東西。

在下圖中,注意那個object X 將保持一致性(假設(shè)更新速度大于30FPS)。但是object Y將不會,因為在前一幀進(jìn)行了縮放,但是這個數(shù)據(jù)并沒有被體現(xiàn)在復(fù)制對象中。

clip_image008

圖里有許多關(guān)于同步的東西被我刪掉了,但是上面著實能夠反應(yīng)這個技術(shù)的實現(xiàn)形式。

上面說到的兩個技術(shù)中,并沒有任何一個技術(shù)被OGRE社區(qū)接受,它們都需要大量修改OGRE代碼,因此并未繼續(xù)。一個需要復(fù)制對象數(shù)據(jù)來控制數(shù)據(jù)修改的例子便是Frustum::updataView函數(shù)和_update函數(shù),對于實現(xiàn)這個函數(shù)的所有類,都需要在渲染中被調(diào)用,以及OGRE的其它地方(渲染以外的地方)。

在哪里進(jìn)行線程化

在OgreMain中進(jìn)行線程化的一個理想的地方便是在Root::renderOneFrame中。這個函數(shù)調(diào)用了主渲染_Root::_updateAllRenderTargets,這個函數(shù)可以輕易地被封裝一次。

下面是一些實現(xiàn)上面想法的示例代碼。



_beginthreadex(
0,0,Root::renderThreadFuc,0,0,0);



/*static*/ unsigned int Root::renderThreadFunc( )



    
while(1)

    
{

        waitForStartRendering( );

        _setStartRendering(flase);

        _updateAllRenderTargets( );

        _setRenderingComplete(
true);

    }


}


bool Root::renderOneFrame( )

{

    
if(!_fireFrameStarted( ) )

        
return false;

    
if(mThreadedRendering)

    


        _waitForRenderingComplete( );

        _setRenderingComplete(
false);

        _setStartRendering(
true);

    }


    
else

    
{

        _updateAllRenderTargets( );

    }


}


_wait 和_set函數(shù)演示了操作系統(tǒng)依賴的同步函數(shù)調(diào)用,例如,WINDOWS版本的_waitForRenderingComplete將會包含一個WaitForSingleObject調(diào)用。注意當(dāng)多線程開啟的時候,應(yīng)該在真正渲染完成之前調(diào)用_fireFrameEnded函數(shù)。

技術(shù)方案2:創(chuàng)建一個線程渲染系統(tǒng)層(中級線程化手段)

創(chuàng)建一個線程化的渲染系統(tǒng)層對OGRE渲染系統(tǒng)來說是一個很不顯眼的方案。但是由于OGRE渲染系統(tǒng)的復(fù)雜性,它也是最困難的方案。渲染層從本質(zhì)上講是對渲染系統(tǒng)插件(如D3D,OPENGL)的一個封裝。想要在OGRE中創(chuàng)建和集成一個這樣的附加渲染系統(tǒng),只需要對OGRE進(jìn)行較少的改動。但是創(chuàng)建創(chuàng)建一個線程化的渲染系統(tǒng)層,又是另一回事了。

clip_image010

為了創(chuàng)建一個線程化的渲染系統(tǒng)層,你至少需要在OgreMain中實現(xiàn)Ogre::RenderSystem 類和Ogre:RenderWindow類。這兩個類僅僅是界于Ogre和實際的渲染器插件之間的一個層。這個層的工作并不是簡單的將對插件的函數(shù)調(diào)用進(jìn)行封裝。需要決定要做哪些什么,以便調(diào)用渲染器插件,因為這個方案的目標(biāo)是將渲染的工作分離到另一個線程中。在實面這些類的函數(shù)時,有幾事情需要思考。

·習(xí)慣性地(如,所有函數(shù)調(diào)用僅僅是在開始渲染之前調(diào)用。)可以僅是對渲染器插件的直接調(diào)用,(相當(dāng)于函數(shù)轉(zhuǎn)發(fā))。也可以在包裝的同時進(jìn)行一些必要的初始化。

·在調(diào)用渲染器插件進(jìn)行創(chuàng)建操作時,將需要等待前一幀渲染完成。并且需要一個包裝類來包裝那個渲染器返回(提供一個已經(jīng)存在的實例)的與創(chuàng)建相當(dāng)?shù)念?。一個需要包裝類的好例子便是渲染器插件返回的RenderWindow類。這個類的實例通過RenderWindow:createRenderWindow創(chuàng)建并返回。

·某些函數(shù)需要訪問基類。RenderSystem和RenderWindow類需要調(diào)用一些基類方法來完成一些內(nèi)部事情。在OGRE中不這樣做,會導(dǎo)致不正確的行為。

·渲染用的函數(shù)需要被排隊,以便享受到多線程的好處。渲染線程將會遍歷那個隊列,并按順序調(diào)用那些函數(shù)。 RenderWindow中的swapBuffers函數(shù)是一個例外。它的包裝函數(shù)既要加入渲染隊列管理,但它又是向渲染線程發(fā)出信號,執(zhí)行渲染隊列中的函數(shù)的地方。

上面提到的幾點描述了實現(xiàn)這個方案需要做的事情,也還有其它一些小問題需要考慮,并且一些問題需要在實現(xiàn)的時候處理。

線程化的問題

這個實現(xiàn)和“方案1:高級線程化方案”一樣,存在同樣的問題。除開這種情況,最好的解決方案就是復(fù)制需要共享的數(shù)據(jù)。因為這個中間層不擁有Ogre中的類。也有其它一些從“低級線程化方案”中借鑒而來的解決辦法來完成這個實現(xiàn),從而對顯卡資源提供一個線程安全訪問手段。

在哪里線程化

正如先前提到的,這將是線程化Ogre渲染系統(tǒng)的一個最不顯眼的方案。所需要對Ogre做的輕微改變僅是對Ogre現(xiàn)有的渲染系統(tǒng)增加一個線程化的渲染系統(tǒng)層。像這樣

void Root::AddRenderSystem(RenderSystem *newRender)

{

    mRenderers.push_back(newRender);

#ifdef __THEARDRENDERSYSTEM__

    
if(mThreadRenderSystem)

    
{

        RenderSystem
* newTRender = 

            
new ThreadedRenderSystem(newRender);

        
if(newTRender != NULL)

            mRenderers.push_back( newTRender);

    }


#endif

}




技術(shù)方案3:線程化渲染插件(低級線程化手段)

線程化一個特定的渲染插件帶來了最低級的適應(yīng)性,因為它和特定的技術(shù)(如D3D,OPENGL)綁定起來。但是它也使你能夠最大限度地操縱硬件資源。

實現(xiàn)這個方案最干凈利落的辦法就是創(chuàng)建一個介于API和渲染插件之間的層,用來處理線程化。(如下圖)

clip_image012

在這種方法下,它僅僅是用你的層來替換API接口。并且每個一調(diào)用從渲染插件的調(diào)用都是線程安全的,因為你的這個層處理了所有的調(diào)用。為D3D做這個,僅僅是用你自己的包裝類和方法替換了IDirect3D的接口。對于OPENGL,你將移除所有的OPENGL頭文件,并用你自己包裝好后的頭文件替換掉它們。有可能你需要用一個命名空間來包裝OPENGL函數(shù),以免出現(xiàn)名詞沖突。

這個方案依然和“中級線程化手段”一樣需要考慮些線程化相關(guān)的東西。

·初始化不需要多線程

·創(chuàng)建函數(shù)以及一些get函數(shù)需要在渲染完一幀前等待。

·渲染命令,和伴隨參數(shù)將需要加入隊列中。

關(guān)于索引和頂點緩沖的加鎖

對于所有的方案,都存在一個使用硬件資源時的潛在線程問題。對索引頂點緩沖區(qū)的加鎖就是一個很大的挑戰(zhàn),因為某些應(yīng)用程序在執(zhí)行的時候總是會反復(fù)對這些緩沖區(qū)進(jìn)行加鎖和解鎖。比如對于動態(tài)緩沖區(qū),總是會每幀都改變它的內(nèi)容來實現(xiàn)畫面的變化。一些應(yīng)用程序也會重用緩沖區(qū)以使多個對象每幀都能夠共享同樣的頂點和索引緩沖區(qū)。為了解決這個問題,我們需要緩沖這些緩沖區(qū)。然而,可以通過很多方法來實現(xiàn),下面有兩種緩沖辦法:

1、 部分緩沖區(qū)加鎖,這是一個類似于雙緩沖的緩沖技術(shù)。我們將在顯卡中創(chuàng)建兩個緩沖區(qū),而不是一個。在這種情況下,當(dāng)應(yīng)用程序在寫一個緩沖區(qū)的時候,渲染線程將使用另一個緩沖區(qū)中的數(shù)據(jù)進(jìn)行渲染。這個方案可以提升渲染速度但是有一個缺點,就是會消耗更多的顯存。并且不能處理應(yīng)用程序在每一幀對同一緩沖區(qū)連續(xù)寫兩次的情況。

clip_image014

2、 完全緩沖區(qū)加鎖,這個技術(shù)保持一個對于緩沖區(qū)的所有鎖的副本。保留一個本地緩沖區(qū)并在上面進(jìn)行所有的修改。當(dāng)解鎖它的時候,那些數(shù)據(jù)就會被放入一個參數(shù)隊列,這樣就可以對每次加鎖/解鎖維護(hù)一個唯一的副本。雖然這樣可以對緩沖區(qū)數(shù)據(jù)進(jìn)行精確的維護(hù),但當(dāng)某些應(yīng)用程序在鎖較大的數(shù)據(jù)的時候效果會大打折扣。

clip_image016

為什么鎖表面的時候不用緩沖

表面(如前臺緩沖,后臺緩沖,紋理等)通常消耗大量的存儲空間。 所以,在對表面加鎖時緩沖是無用的,也是不必要的。為什么沒有用呢,因為在上面的加鎖緩沖技術(shù)中,一個顯卡會瞬間消耗掉大量的存儲空間,因為這個時候我們需要創(chuàng)建兩個表面。 例如:一個1024X1024 32bpp的紋理通常會消耗掉4MB的顯存,但是如果采用了上面的緩沖鎖技術(shù),那么將會占用8MB的顯存。這個技術(shù)將會導(dǎo)致紋理可用的顯存資源直接減半。而對于完全緩沖區(qū)鎖技術(shù)。則會消耗了大量的系統(tǒng)內(nèi)存并且花費較多時間來拷貝數(shù)據(jù)。因為這個技術(shù)在系統(tǒng)內(nèi)存中維護(hù)了一個數(shù)據(jù)的副本。所以它將會一次性地為這個表面分配大量的空間。當(dāng)解鎖的時候,又會將數(shù)據(jù)拷貝到參數(shù)隊列里,并且參數(shù)隊列在必要的時候,也會分配較大的空間。在渲染時,渲染線程同樣需要將數(shù)據(jù)從參數(shù)隊列中取出,并拷貝到真正的表面上。所有的這些拷貝操作,都會導(dǎo)致加鎖和解鎖的速度大大降低。

表面加鎖時緩沖不必要是因為應(yīng)用程序不需要直接對表面(紋理除外)進(jìn)行讀寫,為了取得更好的性能,可以使用顯卡直接對表面進(jìn)行操作。紋理,從另一方面講,僅會被加鎖一次,然后從文件中加載信息到它的表面。所以,對于紋理的加鎖,可以讓主線程等待渲染線程返回,然后再進(jìn)行加鎖,而不用對其進(jìn)行緩沖。注意,等待渲染線程返回并加鎖有可能導(dǎo)致錯誤。因為有可能顯卡正在填充這個表面資源。記住,頻繁的對表面進(jìn)行加鎖將會導(dǎo)致因為主線程的強(qiáng)制等待而使效率降低。

在哪里進(jìn)行線程化

這個方案的實現(xiàn)只能是在包裝圖形API的那個包裝類中。每一個函數(shù)都會有不同的實現(xiàn),因為它們有可能是直接調(diào)用圖形API,而有可能是要在調(diào)用圖形API前等待前一幀繪制完成。或者是將數(shù)據(jù)放入渲染線程的隊列,讓渲染線程去調(diào)用API。也可以對其進(jìn)行一些優(yōu)化,采用在包裝類中做一些緩存來緩存那些需要等待的調(diào)用(譯注:個人理解是因為每一幀需要等待的調(diào)用可能不止一個,將他們緩存起來。這樣當(dāng)渲染線程返回時,一并調(diào)用這些函數(shù),就能少了許多等待)。你還需要的就是修改渲染系統(tǒng)插件的代碼,用你的包裝類函數(shù)替換掉所有的圖形API調(diào)用。

下面的代碼演示了如何進(jìn)行IUnknown接口的包裝。

 


D3D9WrapperUnknown:: D3D9WrapperUnknown

D3D9WrapperDevice
* pD3DDevice)

:m_pD3DDevice(pD3DDevice)

,m_RefCount(
1)

{

}


D3D9WrapperUnknown:: 
~D3D9WrapperUnknown

{

    
if(m_RefCount>0)

    
{

        
//輸出信息,因為錯了。

    }


}


ULONG D3D9WrapperUnknown::AddRef( )

{

    
return ++m_RefCount;

}


ULONG D3D9WrapperUnknown::Release( )

{

    
if(!(--m_RefCount))

    
{

        
if(m_pUnknown != NULL)

        
{

            m_pD3DDevice
->SubmitRelease(m_pUnKown);

        }


        delete 
this;

    }


    
return m_RefCount;

}



這個技術(shù)達(dá)到了本文介紹中的所有目標(biāo),并且也是最終的選擇方案。D3D9渲染系統(tǒng)被選擇來實現(xiàn)這個方案,伴隨本文的代碼可以從Intel Developer website上下載。

OGRE分析以及結(jié)果

這個部分我們將討論采用“低級線程化手段”時,運行OGRE的例子程序的情況。下面的數(shù)據(jù)是在2.4GHz Core 2 雙核處理器,NVIDIA 7800顯卡上測試的結(jié)果。這些數(shù)據(jù)顯示了兩個不同的緩沖加鎖方案,以及在沒有開啟多線程時DirectX包裝類的負(fù)載。綠色背景指明了使用這個方案時提升到了1.1倍,甚至更多。 黃色部分指明了運用該方案時,降低到了1.0倍以下,但是并無太大損耗。而紅色部分指明了動用此方案時,出現(xiàn)了沖突情況。

clip_image018

注意,這里有太多的1。0左右的元素,當(dāng)然也有一些稍微低于1。0的。但是不會太多。可以看到,這里也有許多綠色的元素,表明運行良好。但要注意,這些測試?yán)佣际荗GRE的DEMO,DEMO并不使用CPU處理太多的東西。只有兩個元素是紅的。都是處于“完全緩沖加鎖”方案中。因為這些DEMO經(jīng)常更新很大的頂點緩沖。導(dǎo)致很多時間花費在等待復(fù)制完成,從而出現(xiàn)問題。

需要特別說明的是“Shadow Demo”。有兩種陰影方案,模版和紋理。只有模版陰影在“部分緩沖加鎖”方案時會出現(xiàn)問題,而紋理陰影則工作良好。

同時也要注意的時,一些例子在“完全緩沖加鎖”方案中運行的效果比“部分緩沖加鎖”方案要好。在這種情況下,應(yīng)用程序取得一個可以讀寫的緩沖區(qū)。在這種情況下,主要是負(fù)載在于應(yīng)用程序會將顯存中的數(shù)據(jù)復(fù)制到系統(tǒng)內(nèi)存中。而“完全緩沖加鎖”方案通過將加鎖和解鎖放到渲染線程中,而將這個負(fù)擔(dān)消除了。

結(jié)論:

將一個3D渲染引擎線程化是一項具有挑戰(zhàn)性的工作,但事實證明,它是可行的。正如先前所展示的一樣,將OGRE渲染引擎線程化是很成功的,并且在某些DEMO上運行出了良好的效果。有三種線程化方案,但最終只選擇了“低級優(yōu)化方案“來實現(xiàn)。因為其滿足了本文最初提出的目標(biāo)。在OGRE社區(qū)的共同努力下,OGRE可以在CPU和GPU資源都密集型的應(yīng)用程序中,運行出更多幀數(shù)和更平滑的顯示效果。

posted on 2010-12-20 23:14 麒麟子 閱讀(2376) 評論(0)  編輯 收藏 引用 所屬分類: Game and Engine

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产亚洲欧美一区二区三区| 欧美激情亚洲另类| 精品成人a区在线观看| 国产欧美日韩精品a在线观看| 欧美午夜免费电影| 国产精品视频免费观看www| 国产精品日韩二区| 国模私拍一区二区三区| 亚洲成色www8888| 一本色道久久综合亚洲精品小说 | 欧美中文在线视频| 久久久久五月天| 欧美精品激情在线| 国产九九精品视频| 亚洲人成欧美中文字幕| 亚洲欧美一区二区视频| 男男成人高潮片免费网站| 日韩网站在线观看| 久久精品国产精品亚洲精品| 欧美日本一区| 狠狠88综合久久久久综合网| 一区二区三区四区国产精品| 久久裸体艺术| 免费成人av资源网| 亚洲精品久久久久久久久久久久久 | 亚洲视频高清| 久久精品视频在线观看| 日韩亚洲欧美一区二区三区| 香港久久久电影| 国产精品国产自产拍高清av| 亚洲精品看片| 亚洲国产另类久久精品| 亚洲欧美日韩国产中文在线| 亚洲欧洲视频| 欧美大色视频| 亚洲欧美国产毛片在线| 激情成人av| 亚洲主播在线播放| 亚洲高清视频在线观看| 欧美伊久线香蕉线新在线| 欧美三级小说| 亚洲精品久久视频| 欧美+日本+国产+在线a∨观看| 亚洲欧美日韩中文播放| 欧美三级日本三级少妇99| 亚洲国产精品免费| 久久综合色8888| 欧美一级在线播放| 国产精品久久久久久久久| 亚洲精品在线免费| 你懂的国产精品| 久久精品九九| 韩国av一区二区三区四区| 午夜精品福利一区二区蜜股av| 亚洲美女一区| 欧美日韩不卡一区| 99视频精品在线| 亚洲国产91精品在线观看| 麻豆精品视频在线观看视频| 亚洲高清在线观看一区| 欧美不卡一卡二卡免费版| 久久久久久久网站| 亚洲第一福利视频| 欧美高清hd18日本| 欧美成人午夜| 宅男在线国产精品| 99精品国产热久久91蜜凸| 欧美日韩在线免费| 亚洲欧美日韩视频二区| 亚洲欧美日韩成人高清在线一区| 国产精品亚洲视频| 久久精品99国产精品酒店日本| 亚洲欧美在线x视频| 国产一区二区三区久久悠悠色av | 久久这里只有| 性色av一区二区三区| 国产真实乱子伦精品视频| 久久婷婷国产综合精品青草| 久久久久久亚洲精品杨幂换脸| 亚洲国产欧美一区二区三区同亚洲 | 久久久久久久久久久久久9999| 久久久久99| 久久在线91| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲国产精品一区| 欧美h视频在线| 99视频在线精品国自产拍免费观看| 日韩五码在线| 黑人巨大精品欧美一区二区| 最新精品在线| 国产一区二区三区黄| 亚洲国产裸拍裸体视频在线观看乱了| 欧美在线关看| 亚洲特级毛片| 免费观看国产成人| 欧美精品乱人伦久久久久久 | 国产精品大片免费观看| 久久久成人网| 欧美金8天国| 久久精品国产亚洲aⅴ| 欧美大片免费观看| 欧美在线观看一二区| 欧美xx69| 久久天天狠狠| 国产精品久久久久999| 欧美成人福利视频| 国产精品一区久久久久| 欧美成人精品不卡视频在线观看| 国产精品va在线播放我和闺蜜| 欧美成人性生活| 日韩视频永久免费| 在线日韩欧美视频| 午夜精品999| 欧美在线观看视频| 99re6这里只有精品| 欧美一区二区在线免费观看| 99这里有精品| 免费视频亚洲| 麻豆乱码国产一区二区三区| 国产精品一区二区三区久久| 日韩亚洲国产精品| 亚洲欧洲综合另类| 久久免费99精品久久久久久| 久久激情久久| 国产乱码精品一区二区三区av| 欧美激情综合色| 久久人人97超碰人人澡爱香蕉| 一区二区在线不卡| 午夜久久影院| 午夜免费在线观看精品视频| 欧美色播在线播放| 亚洲狼人综合| 在线午夜精品| 国产精品sm| 亚洲欧美激情在线视频| 午夜视频一区| 国产午夜精品久久久久久免费视| 亚洲一区二区视频在线观看| 欧美一区二区成人| 国产欧美va欧美va香蕉在| 亚洲欧美日韩国产成人精品影院| 亚洲欧美影院| 国产亚洲精品aa午夜观看| 性做久久久久久久免费看| 久久aⅴ国产欧美74aaa| 国产在线播精品第三| 久久久久亚洲综合| 亚洲二区在线视频| 亚洲毛片在线观看| 欧美日韩在线综合| 亚洲欧美成人网| 久久在线免费| 亚洲人成毛片在线播放| 欧美日韩国产精品一卡| 亚洲午夜羞羞片| 麻豆久久婷婷| 中日韩男男gay无套| 国产免费观看久久黄| 久久久久综合一区二区三区| 亚洲福利视频二区| 亚洲欧美激情一区二区| 国产一区二区日韩精品欧美精品| 久久免费午夜影院| 日韩视频在线观看一区二区| 欧美亚洲在线观看| 亚洲成色777777在线观看影院| 欧美区二区三区| 欧美在线3区| 亚洲三级视频| 久久久久久亚洲精品中文字幕 | 国产真实久久| 亚洲网站视频| 免费在线日韩av| 欧美视频在线观看视频极品| 国产精品久久午夜| 亚洲一品av免费观看| 国产欧美精品一区二区色综合 | 亚洲精品国精品久久99热一| 欧美视频免费在线| 久久青草久久| 亚洲一区二区免费视频| 欧美韩国在线| 久久成人18免费网站| 99国产精品久久久久久久成人热 | 欧美日韩综合视频| 久久国产乱子精品免费女| 亚洲激情在线| 久久裸体艺术| 亚洲男人的天堂在线| 亚洲黄色有码视频| 国产一区二区电影在线观看| 欧美日韩中文| 欧美福利视频| 久久精品国产亚洲精品| 亚洲天天影视| 一本久久综合亚洲鲁鲁| 亚洲国产1区| 亚洲第一黄网| 久久字幕精品一区| 久久爱www|