欧美成a人片免费看久久,色婷婷综合久久久中文字幕 ,国产欧美久久一区二区http://www.shnenglu.com/flagship/創新+實踐zh-cnWed, 07 May 2025 01:37:28 GMTWed, 07 May 2025 01:37:28 GMT60幾種多線程3D引擎架構的比較http://www.shnenglu.com/flagship/archive/2009/03/25/77886.htmlflagshipflagshipWed, 25 Mar 2009 15:22:00 GMThttp://www.shnenglu.com/flagship/archive/2009/03/25/77886.htmlhttp://www.shnenglu.com/flagship/comments/77886.htmlhttp://www.shnenglu.com/flagship/archive/2009/03/25/77886.html#Feedback10http://www.shnenglu.com/flagship/comments/commentRss/77886.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/77886.html1、在CPU上進行的邏輯計算(比如骨骼動畫粒子發射等)不影響渲染速度
2、較差的GPU渲染速度的低下不影響邏輯速度

      第一個目標已經很明確了,我來解釋下需要達到第二個目標的原因:許多動作游戲的邏輯判定是基于幀的,所以在渲染較慢的情況下,邏輯不能跳幀,而仍然需要嚴格執行才能保證游戲邏輯的正確性,這就導致了游戲速度的放慢,而實際上個人認為渲染保持15幀以上就已經可以正常進行游戲了。
      在較差的GPU上跑《鬼泣4》《刺客信條》《波斯王子4》簡直就像是慢鏡頭一樣,完全沒法玩。而實際上CPU跑滿幀是沒有問題的,如果能把邏輯幀和渲染幀徹底分離,即使渲染幀達不到要求,但CPU仍能正確的執行游戲邏輯,就可以解決動作游戲對GPU要求過高的問題。

      我們先來看多線程Ogre的兩種架構,第一種是middle-level multithread


      如上圖所示,每個需渲染的實體被復制成了兩份,主線程和渲染線程交替更新和渲染同一個實體的兩個備份,并在一幀結束時同步,這種解決方案達到了第一個目標而并沒有達到第二個目標,同時兩份實體的維護也相對復雜,并且沒法為更多核數的CPU進行擴展優化。
      第二種Ogre多線程的方法是 low-level multithread

      如圖,將D3D對象復制兩份,同樣是在幀結束時同步并交換,和上面的優缺點類似。兩種多線程Ogre的解決方案都是在引擎層完成的,對上層應用透明,對于用戶而言無需考慮多線程細節,這點是非常不錯的。

      接下來我們來看SIGGRAPH2008上,id soft提出的多線程3D引擎的方案

      這里是已PS3的引擎結構為例的,與PC有較大的差別,其中SPU是Cell芯片的8個協處理器,擁有強大的并行能力,id的解決方案在SPU上進行了諸如骨骼動畫、形變動畫、頂點和索引緩存的壓縮、Progressive Mesh的計算等諸多內容,同時與PPU上的物理計算RSX上的渲染工作交錯進行,最大化的利用了PS3的硬件結構,最終的游戲產品《Rage》很快就會面世了!

      最后是我的解決方案

      特點是邏輯完全分離,無需同步,雖然成功的達到了文章開始提出的兩個目標,但對于引擎的使用者必須考慮多線程的諸多問題,各種計算需放在哪個線程,如何在兩個線程間交互,都需要深入思考,所以要應用到實際的游戲制作,恐怕還有很長的一段路要走。
      結合目前的架構和上面看到的幾種多線程架構,同時也為了迎接DX11的到來,我準備將我的方案進一步改進成如下所示

      場景剪裁與提交渲染交替進行,并在渲染幀末進行一次同步,而多個渲染表面的場景剪裁可再并行執行。
      圖片多,文字少,需更詳細資料請自行google,本文就此結束!


flagship 2009-03-25 23:22 發表評論
]]>
多Pass渲染體系與多線程渲染的矛盾http://www.shnenglu.com/flagship/archive/2009/03/15/76630.htmlflagshipflagshipSun, 15 Mar 2009 04:45:00 GMThttp://www.shnenglu.com/flagship/archive/2009/03/15/76630.htmlhttp://www.shnenglu.com/flagship/comments/76630.htmlhttp://www.shnenglu.com/flagship/archive/2009/03/15/76630.html#Feedback3http://www.shnenglu.com/flagship/comments/commentRss/76630.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/76630.html    最近為了實現多光源和多陰影的渲染,把渲染系統改成了多Pass的,對每一個可見光源進行一次光照、ShadowMap和最終陰影的渲染,雖然這樣等于是把整個場景重復渲染了很多次,但為了實現靈活的實時光照系統,這似乎是唯一的辦法了。
    但實踐后發現,陰影和光照會隨著骨骼動畫的播放而閃爍,甚至鏡頭的移動也會造成閃爍,究其原因,還是邏輯線程和渲染線程的同步問題,由于對場景內的同一個物體渲染了多次,而邏輯線程又在不停的更新攝像機和骨骼動畫數據,導致了兩Pass渲染取到的數據很可能不一致,造成了光照和陰影的閃爍。
    所以共享數據結構必須做一些修改,在多Pass渲染開始前進行一次備份,渲染中只取備份數據,這樣就保證了多次渲染的數據一致性了

    也就是加這么兩個簡單的set和get方法,在渲染相關數據讀取時調用get,邏輯相關時調用read

template <class T>
struct SharedData
   
{
        T        m_pData[DATACENTER_CACHE];
        T        m_kCloneData;
        
int      m_iIndex;

        SharedData()
      
{
            ZeroMemory( m_pData, DATACENTER_CACHE 
* sizeof(T) );
            m_iIndex 
= 0;
        }


        
void    Write( T& rData )
      
{
            
int iNewIndex = m_iIndex == DATACENTER_CACHE - 1 ? 0 : m_iIndex + 1;
            m_pData[iNewIndex] 
= rData;
            m_iIndex 
= iNewIndex;
        }


        T
&    Read()
      
{
           
return m_pVector[m_iIndex];
        }


        
void    Set()
      
{
           m_kCloneData 
= Read();
        }


        T
&      Get()
      {

           
return m_kCloneData;
        }

    }
;



flagship 2009-03-15 12:45 發表評論
]]>
DX11與多線程渲染http://www.shnenglu.com/flagship/archive/2009/02/16/73951.htmlflagshipflagshipMon, 16 Feb 2009 09:11:00 GMThttp://www.shnenglu.com/flagship/archive/2009/02/16/73951.htmlhttp://www.shnenglu.com/flagship/comments/73951.htmlhttp://www.shnenglu.com/flagship/archive/2009/02/16/73951.html#Feedback4http://www.shnenglu.com/flagship/comments/commentRss/73951.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/73951.html    本來只是以為自己只是火星了而已,裝好一看,完。。。徹底冥王星了,DX11的Preview版出了!真是又激動又懊悔,粗略看了看,新特性真是太令人激動了,主要有以下幾點:

一、SM5.0 從類C變成類C++了,有類有繼承有虛函數,太夸張了。。。
二、支持Shader動態Link,DX9里面就有個FragmentLinker,不太好用,DX10直接取消了,這次變本加厲的又回來了!
三、渲染的多線程支持,我重點來談談這個

    DX11提供了一個新的接口:ID3D11DeviceContext,取代了以前Device接口所有與渲染相關的功能,有兩個類型:immediate和deferred,前者和現在的效果一樣,收到渲染指令就立即執行,而后者則會將命令緩存起來,由用戶決定何時執行
    在例子MultithreadedRendering11中,渲染了三面帶反射的鏡子和一個人物模型,Sample創建了四個Context,三個deferred用于鏡子反射表面的渲染,一個immediate用于最終場景,Sample創建了三個線程,渲染幀開始時,首先并行的執行三個鏡子反射的渲染,完成后,在主線程順序執行三個Context,然后用immediate的Context渲染最終場景。
    由這個例子,我們來展望一下美好的未來:所有的渲染表面都可以并行執行,比如水面、鏡子、甚至ShadowMap,并行的進行場景剪裁,使得多核CPU的使用更有效率。
    DX11預計在今年年底推出,于Windows7捆綁,到那時,四核CPU應該已經普及了吧。。。


flagship 2009-02-16 17:11 發表評論
]]>
3D引擎多線程:邏輯操作http://www.shnenglu.com/flagship/archive/2009/01/24/72556.htmlflagshipflagshipSat, 24 Jan 2009 15:38:00 GMThttp://www.shnenglu.com/flagship/archive/2009/01/24/72556.htmlhttp://www.shnenglu.com/flagship/comments/72556.htmlhttp://www.shnenglu.com/flagship/archive/2009/01/24/72556.html#Feedback1http://www.shnenglu.com/flagship/comments/commentRss/72556.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/72556.html        解決辦法其實在上一篇中已經提到了,仍然是利用天然的同步機制——Windows消息,添加實體時,邏輯線程只是new了一個Entity對象,設置這個對象的初始共享數據,比如位置信息,同時向渲染線程發送一條WM_ADDENTITY的自定義消息,將Entity指針作為wParam傳遞。渲染線程接受到消息后調用Entity的UpdateScene方法,更新Entity在場景樹中的位置,并加載資源。
        刪除也是一樣,邏輯線程向渲染線程發送WM_DELETEENTITY消息,并不再使用該Entity指針,渲染對象則處理改消息,將此Entity從場景中刪除并卸載資源。
        這里有一個非常危險的情況,前面一篇提到,資源加載也是通過消息傳遞實現的,同樣是傳遞的資源指針,如果邏輯線程添加了一個Entity,還沒加載就刪掉了它,則資源加載線程會拿到一個過期指針,一切就結束了。。。
        解決這一問題,最穩妥的方法是消息的wParam并不傳遞指針,而是傳遞該Entity或資源的唯一ID,這樣的話即使ID過期,也可輕松忽略掉這條消息,壞處是每次消息處理都的從全局的map里檢查是否存在此ID對應的Entity或資源,這可是筆不小的開銷。
        第二種方案,我們仍然傳遞指針,只是在接受到WM_DELETEENTITY消息時,檢查該Entity是否已經加載完成,如果沒有完成,則重新將此消息加入消息隊列,下個渲染幀再次判斷。
       FlagshipEngine的多線程設計大致就是如此了。

flagship 2009-01-24 23:38 發表評論
]]>
3D引擎多線程:框架http://www.shnenglu.com/flagship/archive/2009/01/10/71688.htmlflagshipflagshipSat, 10 Jan 2009 15:37:00 GMThttp://www.shnenglu.com/flagship/archive/2009/01/10/71688.htmlhttp://www.shnenglu.com/flagship/comments/71688.htmlhttp://www.shnenglu.com/flagship/archive/2009/01/10/71688.html#Feedback1http://www.shnenglu.com/flagship/comments/commentRss/71688.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/71688.html        首先,資源讀取線程可以簡單設計為一個循環等待的線程結構,每隔一段時間檢查加載隊列中是否有內容,如果有則進行加載工作,如果沒有則繼續等待一段時間。這種方式雖然簡單清晰,但卻存在問題,如果等待時間設得過長,則加載會產生延遲,如果設得過短,則該線程被喚醒的次數過于頻繁,會耗費很多不必要的CPU時間。
        然后,主線程是邏輯線程還是渲染線程?因為邏輯線程需要處理鍵盤鼠標等輸入設備的消息,所以我起初將邏輯線程設為主線程,而渲染線程另外創建,但實際發現,幀數很不正常,估計與WM_PAINT消息有關,有待進一步驗證。于是掉轉過來,幀數正常了,但帶來了一個新的問題,邏輯線程如何處理鍵盤鼠標消息?
      
        對于第一個問題,有兩種解決方案:
        第一,我們可以創建一個Event,資源讀取線程使用WaitForSingleObject等待著個Event,當渲染線程向加載隊列添加新的需加載的資源后,將這個Event設為Signal,將資源讀取線程喚醒,為了安全,我們仍需要在渲染線程向加載隊列添加元素,以及資源加載線程從加載隊列讀取元素時對操作過程加鎖。
        第二,使用在渲染線程調用PostThreadMessage,將資源加載的請求以消息的形式發送到資源價值線程,并在wParam中傳遞該資源對象的指針,資源加載線程調用WaitMessage進行等待,收到消息后即被喚醒,這種解決方案完全不需要加鎖。
        對于第二個問題,我們同樣可以用PostThreadMessage來解決,在主線程的WndProc中,將邏輯線程需要處理的消息發送出去,邏輯線程收到后進行相關處理。

        需要注意的是,我們必須搞清楚線程是在何時創建消息隊列的,微軟如是說:

The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use one of the following methods to handle this situation.

  • Call PostThreadMessage. If it fails, call the Sleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
  • Create an event object, then create the thread. Use the WaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage as shown here to force the system to create the message queue.
    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)
    Set the event, to indicate that the thread is ready to receive posted messages.

        看來,我們只需要在線程初始化時調一句PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)就可以了,然后在主線程中如此這般:

switch ( uMsg )
        
{
        
case WM_PAINT:
            
{
                hdc 
= BeginPaint(hWnd, &ps);
                EndPaint(hWnd, 
&ps);
            }

            
break;
        
case WM_DESTROY:
            
{
                m_pLogic
->StopThread();
                WaitForSingleObject( m_pLogic
->GetThreadHandle(), INFINITE );
                PostQuitMessage(
0);
            }

            
break;
        
default:
            
{
                
if ( IsLogicMsg( uMsg ) )
                
{
                    PostThreadMessage( m_pLogic
->GetThreadID(), uMsg, wParam, lParam );
                }

                
else
                
{
                    
return DefWindowProc( hWnd, uMsg, wParam, lParam );
                }

            }

            
break;
        }

        在邏輯線程中這般如此:
MSG msg;
        
while ( m_bRunning )
        
{
            
if ( PeekMessage( &msg, NULL, 00, PM_NOREMOVE ) )
            
{
                
if ( ! GetMessageW( &msg, NULL, 00 ) )
                
{
                    
return (int) msg.wParam;
                }


                MessageProc( msg.message, msg.wParam, msg.lParam );
            }


            LogicTick();
        }
        完成!

flagship 2009-01-10 23:37 發表評論
]]>
3D引擎多線程:渲染與邏輯分離http://www.shnenglu.com/flagship/archive/2009/01/04/71165.htmlflagshipflagshipSun, 04 Jan 2009 13:15:00 GMThttp://www.shnenglu.com/flagship/archive/2009/01/04/71165.htmlhttp://www.shnenglu.com/flagship/comments/71165.htmlhttp://www.shnenglu.com/flagship/archive/2009/01/04/71165.html#Feedback7http://www.shnenglu.com/flagship/comments/commentRss/71165.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/71165.html        如果考慮使用多線程優化,最容易想到的就是采用平行分解模式,將骨骼動畫計算和粒子計算寫成兩個for循環,然后用OpenMP將其多線程化,但事實上這樣并不會提高多少效率,這兩者計算仍然要阻滯渲染幀,線程的創建也有一定的消耗。于是我想到了一種極端的解決方案,采用任務分解模式,將渲染和邏輯完全分離到兩個線程去,互不影響,當然這樣線程同步會是大問題,畢竟線程的數量和BUG的數量是成正比的。
        我們首先來分析下這兩個線程分別需要做什么工作,需要那些數據。渲染線程需要獲取實體的位置、材質等信息,并交給GPU渲染,邏輯線程需要更新實體的位置、材質、骨骼動畫等數據,很顯然一個寫入一個讀取,這為我們實現一個沒有線程同步的多線程3D渲染系統提供了可能。
        為了讓讀取和寫入不需要Lock,我們需要為每一份數據設計一個帶有冗余緩存的結構,讀取線程讀取的是上次寫入完成的副本,而寫入線程則向新的副本寫入數據,并在完成后置上最新標記,置標記的操作為原子操作即可。以Vector為例,這個結構大致是這樣的:
struct VectorData 
{
        Vector4f    m_pVector[DATACENTER_CACHE];
       
int         m_iIndex;

        VectorData()
    
{
            memset( m_pVector, 
0, DATACENTER_CACHE * sizeof(Vector4f) );
            m_iIndex 
= 0;
        }


       
void    Write( Vector4f& rVector )
    
{
           
int iNewIndex = m_iIndex == DATACENTER_CACHE - 1 ? 0 : m_iIndex + 1;
            m_pVector[iNewIndex] 
= rVector;
            m_iIndex 
= iNewIndex;
        }


        Vector4f
&    Read()
  
{
            
return m_pVector[m_iIndex];
        }

}
;
        當然我們可以用模板來寫這個結構,讓其適用于int,float,matrix等多種數據類型,余下的工作就簡單了,將所有有共享數據的類的成員變量都定義為以上這種數據類型,例如我們可以定義:
        SharedData<Matrix4f>  m_matWorld;
        在渲染線程中調用pDevice->SetWorldMatrix( m_matWorld.Read() );
        在邏輯線程中調用m_matWorld.Write( matNewWorld );

        需要注意的是,這種方案并非絕對健壯,當渲染線程極慢且邏輯線程極快的情況下,有可能寫入了超過了DATACENTER_CACHE次,而讀取卻尚未完成,那么數據就亂套了,當然真要出現了這種情況,游戲早已經是沒法玩了,我測試的結果是渲染幀小于1幀,邏輯幀大于10000幀,尚未出現問題。
        FlagshipEngine采用了這一設想,實際Demo測試結果是,計算25個角色的骨骼動畫,從靜止到開始奔跑,單線程的情況下,幀數下降了20%~30%,而使用多線程的情況下,幀數完全沒有變化!


flagship 2009-01-04 21:15 發表評論
]]>
3D引擎多線程:資源異步加載http://www.shnenglu.com/flagship/archive/2009/01/03/71086.htmlflagshipflagshipSat, 03 Jan 2009 13:37:00 GMThttp://www.shnenglu.com/flagship/archive/2009/01/03/71086.htmlhttp://www.shnenglu.com/flagship/comments/71086.htmlhttp://www.shnenglu.com/flagship/archive/2009/01/03/71086.html#Feedback0http://www.shnenglu.com/flagship/comments/commentRss/71086.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/71086.html
首先我們需要定義一個Resource基類,它大致上是這樣的:
class _DLL_Export Resource : public Base
    
{
    
public:
        Resource();
        
virtual ~Resource();

        
// 是否過期
        bool                IsOutOfDate();
       

    
public:
        
// 是否就緒
        virtual bool    IsReady();

        
// 讀取資源
        virtual bool    Load();

        
// 釋放資源
        virtual bool    Release();

        
// 緩存資源
        virtual bool    Cache();

        
// 釋放緩存
        virtual void    UnCache();

    
protected:
        
// 加載標記
        bool            m_bLoad;

        
// 完成標記 
        bool            m_bReady;
        

    
private:

    }
;
        在實際游戲中,加載資源的范圍大于視野,當攝像機移動到單元格邊緣(必須有一定的緩沖區),就應將新的單元格中的對象加入到資源加載隊列中,喚醒資源加載線程調用Load接口進行加載,完成后將該資源的加載標記設為true。而通過可視剪裁所得到的最終可視實體,則需要調用Cache接口構建圖像API所需對象,當Load和Cache都完成后IsReady才會返回true,這時該資源才能開始被渲染。
        卸載方面,在加載新的單元同時,卸載身后舊的單元,對單元內所有資源調用Release,Load/Release帶有引用計數,仍被引用的資源不會被卸載。當某一資源長時間沒有被看見,則超時,調用UnCache釋放VertexBuffer等資源。
        為了實現超時卸載功能,我們需要一個ResourceManager類,每幀檢查幾個已Cache的資源,看起是否超時,另外也需對已加載的資源進行分類管理,注冊其資源別名(可以為其文件名),提供查找資源的接口。
        另外為了方便使用,我們需要一個模板句柄類ResHandle<T>,設置該資源的別名,其內部調用ResourceManange的查找方法,看此資源是否已存在,如不存在則new一個新的,GetImpliment則返回該資源對象,之后可以將該資源添加到實體中,而無需關心其是否已被加載,代碼如下:
template <class T>
    
class _DLL_Export ResHandle
    
{
    
public:
        ResHandle() 
{ m_pResource = NULL; }
        
virtual ~ResHandle() {}

        
// 設置資源路徑
        void            SetPath( wstring szPath )
        
{
            Resource 
* pResource = ResourceManager::GetSingleton()->GetResource( Key( szPath ) );
            
if ( pResource != NULL )
            
{
                m_pResource 
= (T *) pResource;
            }

            
else
            
{
                m_pResource 
= new T;
                m_pResource
->SetPath( szPath );
                ResourceManager::GetSingleton()
->AddResource( m_pResource );
            }

        }


        
// 模板實體類指針
        T *             GetImpliment() return (T *) m_pResource; }

        T 
*             operator-> () return (T *) m_pResource; }

    
protected:
        
// 模板實體類指針
        Resource *      m_pResource;

    
private:
    }
;



flagship 2009-01-03 21:37 發表評論
]]>
開篇:關于FlagshipEnginehttp://www.shnenglu.com/flagship/archive/2009/01/03/71083.htmlflagshipflagshipSat, 03 Jan 2009 13:10:00 GMThttp://www.shnenglu.com/flagship/archive/2009/01/03/71083.htmlhttp://www.shnenglu.com/flagship/comments/71083.htmlhttp://www.shnenglu.com/flagship/archive/2009/01/03/71083.html#Feedback1http://www.shnenglu.com/flagship/comments/commentRss/71083.htmlhttp://www.shnenglu.com/flagship/services/trackbacks/71083.html      首先要感謝旗艦工作室的倒掉,讓我可以名正言順的使用FlagshipEngine這個名字,話說這個實驗引擎,當初只是我的大學畢業設計,工作之后實在太忙,寫寫停停,進度緩慢,到今天也只能算V0.001,其特性主要有以下三點:

一、多線程
      多核CPU早已普及,但3D引擎卻遲遲不能享受到其好處,還僅僅停留在資源異步加載,音頻獨立線程等不疼不癢的應用,就在一年前吧,公司的牛人們為了優化骨骼動畫和粒子計算煞費苦心,這兩樣計算,特別是在無法控制同屏資源的網絡游戲中,對CPU資源的占用非常可觀,自然也拖累了游戲幀數,于是我便有了將邏輯計算與渲染分離的想法。
      FlagshipEngine實現了一套沒有線程同步的雙線程結構,可以做到骨骼動畫、粒子計算、光源移動等邏輯計算分離到一個單獨的線程運行,完全不影響渲染幀數。

二、shader渲染器
      DX10已經放棄了固定管線,那么我們也沒理由再留戀它,完全基于shader的渲染器實現起來更加清晰簡潔,并且易于擴展,目前FlagshipEngine已經實現了DX9和DX10兩個渲染器,可以方便的添加特效。

三、統一剪裁
      場景組織和剪裁永遠是3D引擎的核心功能,視錐、四叉樹、BSP、Portal如何選擇,如何統一是個難題,我的做法是將所有的剪裁都抽象成剪裁面,并用壓棧和出棧的方式,遞歸的對場景進行剪裁,另外我們還可以對大塊實體綁定簡單模型的遮擋體,使用邊緣檢測算法生成遮擋剪裁面,實現遮擋剪裁。
      這套機制還沒有經過嚴格的測試,有待進一步的驗證。

      就這么多了,希望它有朝一日能修成正果,阿門。。。


flagship 2009-01-03 21:10 發表評論
]]>
性做久久久久久久久| 久久精品国产半推半就| 久久精品国产99国产精品导航 | 久久国产精品无| 久久综合亚洲欧美成人| 亚洲一区中文字幕久久| 一本久久综合亚洲鲁鲁五月天| 国产精品99久久久久久宅男小说| 久久久久九九精品影院| 久久免费的精品国产V∧| 久久精品这里只有精99品| 日韩精品久久无码人妻中文字幕| 久久婷婷五月综合国产尤物app| 国内精品久久久久国产盗摄| 久久久久久久精品妇女99| 久久久国产精品| 久久国产精品无码网站| 91精品婷婷国产综合久久 | 国产精品久久久久久久久免费| 亚洲性久久久影院| 模特私拍国产精品久久| 久久人人爽人人爽人人片AV麻烦 | 一本久道久久综合狠狠躁AV| 成人亚洲欧美久久久久| 亚洲午夜精品久久久久久app| 久久国产精品二国产精品| 日本高清无卡码一区二区久久| 精品多毛少妇人妻AV免费久久| 国产三级精品久久| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 久久久久久久97| 亚洲欧洲久久av| 情人伊人久久综合亚洲| 欧美麻豆久久久久久中文| 亚洲国产另类久久久精品黑人| 国产精品久久久久天天影视| 欧洲国产伦久久久久久久| 久久青青草原亚洲av无码app| 亚洲国产成人久久精品影视 | 亚洲国产成人久久精品99| 久久亚洲AV成人无码国产|