1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Surface 與 SurfaceFlinger 之間的關(guān)系

        共 25226字,需瀏覽 51分鐘

         ·

        2021-06-18 08:18

        和你一起終身學(xué)習(xí),這里是程序員Android

        經(jīng)典好文推薦,通過閱讀本文,您將收獲以下知識點:

        一、SurfaceFlinger 啟動過程
        二、Surface 創(chuàng)建過程
        三、Surface 顯示過程

        一、SurfaceFlinger 啟動過程

        SurfaceFlinger 啟動過程:

        SurfaceFlinger 進(jìn)程是由 init 進(jìn)程創(chuàng)建的,運行在獨立的 SurfaceFlinger 進(jìn)程中。init 進(jìn)程讀取 init.rc 文件啟動 SurfaceFlinger。

        service surfaceflinger /system/bin/surfaceflinger
        class core
        user system
        group graphics drmrpc
        onrestart restart zygote
        writepid /dev/cpuset/system-background/tasks

        SurfaceFlinger 的創(chuàng)建會執(zhí)行 main() 方法:
        main_surfaceflinger.cpp

        int main(int, char**) {
        ProcessState::self()->setThreadPoolMaxThreadCount(4);

        sp<ProcessState> ps(ProcessState::self());
        ps->startThreadPool();

        //實例化 surfaceflinger
        sp<SurfaceFlinger> flinger = new SurfaceFlinger();

        setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
        set_sched_policy(0, SP_FOREGROUND);

        //初始化
        flinger->init();

        //發(fā)布 surface flinger,注冊到 ServiceManager
        sp<IServiceManager> sm(defaultServiceManager());
        sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

        // 運行在當(dāng)前線程
        flinger->run();

        return 0;
        }


        SurfaceFlinger 的實例化會執(zhí)行到:onFirstRef()

        void SurfaceFlinger::onFirstRef() {
        mEventQueue.init(this);
        }

        onFirstRef() 中會創(chuàng)建 Handler 并初始化。
        MessageQueue.cpp:

        void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
        mFlinger = flinger;
        mLooper = new Looper(true);
        mHandler = new Handler(*this);
        }

        然后會執(zhí)行到 SurfaceFlinger::init():

        void SurfaceFlinger::init() {
        Mutex::Autolock _l(mStateLock);

        //初始化 EGL,作為默認(rèn)的顯示
        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        eglInitialize(mEGLDisplay, NULL, NULL);

        // 初始化硬件 composer 對象
        mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));

        //獲取 RenderEngine 引擎
        mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());

        //檢索創(chuàng)建的 EGL 上下文
        mEGLContext = mRenderEngine->getEGLContext();

        //初始化非虛擬顯示屏
        for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        //建立已連接的顯示設(shè)備
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
        bool isSecure = true;
        createBuiltinDisplayLocked(type);
        wp<IBinder> token = mBuiltinDisplays[i];

        sp<IGraphicBufferProducer> producer;
        sp<IGraphicBufferConsumer> consumer;
        //創(chuàng)建 BufferQueue 的生產(chǎn)者和消費者
        BufferQueue::createBufferQueue(&producer, &consumer,
        new GraphicBufferAlloc());

        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer);
        int32_t hwcId = allocateHwcDisplayId(type);
        //創(chuàng)建顯示設(shè)備
        sp<DisplayDevice> hw = new DisplayDevice(this,
        type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
        fbs, producer,
        mRenderEngine->getEGLConfig());
        if (i > DisplayDevice::DISPLAY_PRIMARY) {
        hw->setPowerMode(HWC_POWER_MODE_NORMAL);
        }
        mDisplays.add(token, hw);
        }
        }

        getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);

        //當(dāng)應(yīng)用和 sf 的 vsync 偏移量一致時,則只創(chuàng)建一個 EventThread 線程
        if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
        vsyncPhaseOffsetNs, true, "app");
        mEventThread = new EventThread(vsyncSrc);
        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
        sfVsyncPhaseOffsetNs, true, "sf");
        mSFEventThread = new EventThread(sfVsyncSrc);
        mEventQueue.setEventThread(mSFEventThread);
        } else {
        //創(chuàng)建 DispSyncSource 對象
        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
        vsyncPhaseOffsetNs, true, "sf-app");
        //創(chuàng)建線程 EventThread
        mEventThread = new EventThread(vsyncSrc);
        //設(shè)置 EventThread
        mEventQueue.setEventThread(mEventThread);
        }

        //創(chuàng)建 EventControl
        mEventControlThread = new EventControlThread(this);
        mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

        //當(dāng)不存在 HWComposer 時,則設(shè)置軟件 vsync
        if (mHwc->initCheck() != NO_ERROR) {
        mPrimaryDispSync.setPeriod(16666667);
        }

        //初始化繪圖狀態(tài)
        mDrawingState = mCurrentState;

        //初始化顯示設(shè)備
        initializeDisplays();

        //啟動開機動畫
        startBootAnim();
        }


        該方法主要功能是:

        初始化 EGL
        創(chuàng)建 HWComposer
        初始化非虛擬顯示屏
        啟動 EventThread 線程
        啟動開機動畫
        創(chuàng)建 HWComposer:

        HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger, EventHandler& handler):mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false) {
        ...
        bool needVSyncThread = true;
        int fberr = loadFbHalModule(); //加載 framebuffer 的 HAL 層模塊
        loadHwcModule(); //加載 HWComposer 模塊

        //標(biāo)記已分配的 display ID
        for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
        mAllocatedDisplayIDs.markBit(i);
        }

        if (mHwc) {
        if (mHwc->registerProcs) {
        mCBContext->hwc = this;
        mCBContext->procs.invalidate = &hook_invalidate;
        //VSYNC 信號的回調(diào)方法
        mCBContext->procs.vsync = &hook_vsync;
        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
        mCBContext->procs.hotplug = &hook_hotplug;
        else
        mCBContext->procs.hotplug = NULL;
        memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
        //注冊回調(diào)函數(shù)
        mHwc->registerProcs(mHwc, &mCBContext->procs);
        }

        //進(jìn)入此處,說明已成功打開硬件 composer 設(shè)備,則不再需要 vsync 線程
        needVSyncThread = false;
        eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
        ...
        }
        ...
        if (needVSyncThread) {
        //不支持硬件的 VSYNC,則會創(chuàng)建線程來模擬定時 VSYNC 信號
        mVSyncThread = new VSyncThread(*this);
        }
        }

        HWComposer 代表著硬件顯示設(shè)備,注冊了 VSYNC 信號的回調(diào)。VSYNC 信號本身是由顯示驅(qū)動產(chǎn)生的,在不支持硬件的 VSYNC,則會創(chuàng)建“VSyncThread”線程來模擬定時 VSYNC 信號。

        當(dāng)硬件產(chǎn)生VSYNC信號時,則會發(fā)送消息,handler 收到消息進(jìn)行處理。當(dāng) SurfaceFlinger 進(jìn)程收到 VSync 信號后經(jīng)層層調(diào)用,最終調(diào)用到該對象的 handleMessageRefresh() 方法。

        SurfaceFlinger.cpp:

        void SurfaceFlinger::handleMessageRefresh() {
        ATRACE_CALL();
        preComposition();//處理顯示設(shè)備與 layers 的改變,更新光標(biāo)
        rebuildLayerStacks();//重建所有可見 Layer 列表,根據(jù)Z軸排序
        setUpHWComposer();//更新 HWComposer 圖層
        doDebugFlashRegions();
        doComposition();//生成 OpenGL 紋理圖像
        postComposition();//將圖像傳遞到物理屏幕
        }

        二、Surface 創(chuàng)建過程

        Surface 創(chuàng)建過程:

        Surface 創(chuàng)建的過程就是 Activity 顯示的過程,在 ActivityThread.handleResumeActivity() 中調(diào)用了 Activity.makeVisible(),我們接著看下 Activity 是怎么顯示出來的。

        Activity.makeVisible:

        void makeVisible() {
        if (!mWindowAdded) {
        ViewManager wm = getWindowManager();//此處 getWindowManager 獲取的是 WindowManagerImpl 對象
        wm.addView(mDecor, getWindow().getAttributes());
        mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
        }

        WindowManagerImpl.java:

        public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mDisplay, mParentWindow);
        }

        WindowManagerGlobal.java:

        public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
        ...
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        //創(chuàng)建 ViewRootImpl
        ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
        view.setLayoutParams(wparams);
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
        //設(shè)置 View
        root.setView(view, wparams, panelParentView);
        ...
        }

        創(chuàng)建 ViewRootImpl:

        public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
        ...
        final Surface mSurface = new Surface(); //創(chuàng)建 Surface,此時 Surface 創(chuàng)建完什么都沒有,詳見下面分析
        ...
        public ViewRootImpl(Context context, Display display) {
        mContext = context;
        //獲取 IWindowSession 的代理類
        mWindowSession = WindowManagerGlobal.getWindowSession();
        mDisplay = display;
        mThread = Thread.currentThread(); //主線程
        mWindow = new W(this);
        mChoreographer = Choreographer.getInstance();
        ...
        }
        }

        WindowManagerGlobal.java:

        public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
        if (sWindowSession == null) {
        try {
        //獲取 IMS 的代理類
        InputMethodManager imm = InputMethodManager.getInstance();
        //獲取 WMS 的代理類
        IWindowManager windowManager = getWindowManagerService();
        //經(jīng)過 Binder 調(diào)用,最終調(diào)用 WMS
        sWindowSession = windowManager.openSession(
        new IWindowSessionCallback.Stub() {...},
        imm.getClient(), imm.getInputContext());
        } catch (RemoteException e) {
        ...
        }
        }
        return sWindowSession
        }
        }

        WindowManagerService.openSession:

        public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {
        //創(chuàng)建 Session 對象
        Session session = new Session(this, callback, client, inputContext);
        return session;
        }

        再次經(jīng)過 Binder 將數(shù)據(jù)寫回 app 進(jìn)程,則獲取的便是 Session 的代理對象 IWindowSession。

        創(chuàng)建完 ViewRootImpl 對象后,接下來調(diào)用該對象的 setView() 方法。
        ViewRootImpl:

        public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        synchronized (this) {

        requestLayout(); //詳見下面分析
        ...
        //通過 Binder調(diào)用,進(jìn)入 system 進(jìn)程的 Session
        res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
        getHostVisibility(), mDisplay.getDisplayId(),
        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
        mAttachInfo.mOutsets, mInputChannel);
        ...
        }
        }

        final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {

        public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
        //調(diào)用 WMS.addWindow
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
        outContentInsets, outStableInsets, outOutsets, outInputChannel);
        }
        }

        WindowManagerService.java:

        public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
        ...
        WindowToken token = mTokenMap.get(attrs.token);
        //創(chuàng)建 WindowState
        WindowState win = new WindowState(this, session, client, token,
        attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
        ...
        //調(diào)整 WindowManager 的 LayoutParams 參數(shù)
        mPolicy.adjustWindowParamsLw(win.mAttrs);
        res = mPolicy.prepareAddWindowLw(win, attrs);
        addWindowToListInOrderLocked(win, true);
        // 設(shè)置 input
        mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
        //詳見下面分析
        win.attach();
        mWindowMap.put(client.asBinder(), win);

        if (win.canReceiveKeys()) {
        //當(dāng)該窗口能接收按鍵事件,則更新聚焦窗口
        focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
        false /*updateInputWindows*/);
        }
        assignLayersLocked(displayContent.getWindowList());
        ...
        }

        //WindowState.java
        void attach() {
        mSession.windowAddedLocked();
        }

        創(chuàng)建 SurfaceSession 對象,并將當(dāng)前 Session 添加到 WMS.mSessions 成員變量。
        Session.java:

        void windowAddedLocked() {
        if (mSurfaceSession == null) {
        mSurfaceSession = new SurfaceSession();
        mService.mSessions.add(this);
        if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
        mService.dispatchNewAnimatorScaleLocked(this);
        }
        }
        mNumWindow++;
        }

        SurfaceSession 的創(chuàng)建會調(diào)用 JNI,在 JNI 調(diào)用 nativeCreate()。
        android_view_SurfaceSession.cpp:

        static jlong nativeCreate(JNIEnv* env, jclass clazz) {
        SurfaceComposerClient* client = new SurfaceComposerClient();
        client->incStrong((void*)nativeCreate);
        return reinterpret_cast<jlong>(client);
        }

        創(chuàng)建 SurfaceComposerClient 對象, 作為跟 SurfaceFlinger 通信的代理對象。

        SurfaceComposerClient::SurfaceComposerClient() {
        //getComposerService() 將返回 SF 的 Binder 代理端的 BpSurfaceFlinger 對象
        sp<ISurfaceComposer> sm(getComposerService());

        //先調(diào)用 SF 的 createConnection(),再調(diào)用_init
        _init(sm, sm->createConnection());
        if(mClient != 0) {
        Mutex::Autolock _l(gLock);

        //gActiveConnections 是全局變量,把剛才創(chuàng)建的 client 保存到這個 map 中去
        gActiveConnections.add(mClient->asBinder(), this);
        }
        }

        SurfaceFlinger.cpp:

        sp<ISurfaceFlingerClient>SurfaceFlinger::createConnection() {
        Mutex::Autolock _l(mStateLock);
        uint32_t token = mTokens.acquire();

        //先創(chuàng)建一個Client
        sp<Client> client = new Client(token, this);

        //把這個Client對象保存到mClientsMap中,token是它的標(biāo)識。
        status_t err = mClientsMap.add(token, client);

        /*
        創(chuàng)建一個用于 Binder 通信的 BClient,BClient 派生于 ISurfaceFlingerClient,
        它的作用是接受客戶端的請求,然后把處理提交給 SF,注意,并不是提交給 Client。
        Client 會創(chuàng)建一塊共享內(nèi)存,該內(nèi)存由 getControlBlockMemory 函數(shù)返回。
        */

        sp<BClient> bclient = new BClient(this, token,client->getControlBlockMemory());
        return bclient;
        }


        Client::Client(ClientID clientID, constsp<SurfaceFlinger>& flinger):ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) {
        const int pgsize = getpagesize();
        //下面這個操作會使 cblksize 為頁的大小,目前是4096字節(jié)
        constint cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
        mCblkHeap = new MemoryHeapBase(cblksize, 0, "SurfaceFlinger Clientcontrol-block");

        ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
        if(ctrlblk) {
        new(ctrlblk) SharedClient;//原來 Surface 的 CB 對象就是在共享內(nèi)存中創(chuàng)建的這個 SharedClient 對象
        }
        }

        SharedClient:

        class SharedClient {

        public:
        SharedClient();
        ~SharedClient();
        status_t validate(size_t token) const;
        uint32_t getIdentity(size_t token) const;

        private:
        Mutexlock;
        Condition cv; //支持跨進(jìn)程的同步對象

        //NUM_LAYERS_MAX 為 31,SharedBufferStack 是什么?
        SharedBufferStack surfaces[ NUM_LAYERS_MAX ];

        };

        //SharedClient的構(gòu)造函數(shù),沒什么新意,不如Audio的CB對象復(fù)雜
        SharedClient::SharedClient():lock(Mutex::SHARED), cv(Condition::SHARED) {
        }

        一個 Client 最多支持 31 個顯示層。每一個顯示層的生產(chǎn)/消費步調(diào)都由會對應(yīng)的 SharedBufferStack 來控制。而它內(nèi)部就用了幾個成員變量來控制讀寫位置。

        SharedBufferStack.h:

        class  SharedBufferStack{
        ......
        //Buffer 是按塊使用的,每個 Buffer 都有自己的編號,其實就是數(shù)組中的索引號。
        volatile int32_t head; //FrontBuffer 的編號
        volatile int32_t available; //空閑 Buffer 的個數(shù)
        volatile int32_t queued; //臟 Buffer 的個數(shù),臟 Buffer 表示有新數(shù)據(jù)的 Buffer
        volatile int32_t inUse; //SF 當(dāng)前正在使用的 Buffer 的編號
        volatilestatus_t status; //狀態(tài)碼
        ......
        }

        SF 的一個 Client 分配一個跨進(jìn)程共享的 SharedClient 對象。這個對象有31個 SharedBufferStack 元素,每一個 SharedBufferStack 對應(yīng)于一個顯示層。

        一個顯示層將創(chuàng)建兩個 Buffer,后續(xù)的 PageFlipping 就是基于這兩個 Buffer 展開的。

        接著看 SurfaceComposerClient 中這個_init函數(shù):

        void SurfaceComposerClient::_init(
        const sp<ISurfaceComposer>& sm, constsp<ISurfaceFlingerClient>& conn) {
        mPrebuiltLayerState = 0;
        mTransactionOpen = 0;
        mStatus = NO_ERROR;
        mControl = 0;

        mClient = conn;// mClient 就是 BClient 的客戶端
        mControlMemory =mClient->getControlBlock();
        mSignalServer = sm;// mSignalServer 就是 BpSurfaceFlinger
        //mControl 就是那個創(chuàng)建于共享內(nèi)存之中的 SharedClient
        mControl = static_cast<SharedClient*>(mControlMemory->getBase());
        }

        創(chuàng)建完 ViewRootImpl 對象后,接下來調(diào)用該對象的 setView() 方法。在 setView() 中調(diào)用了 requestLayout() 方法我們來看下這個方法:

        public void requestLayout() {
        checkThread();
        mLayoutRequested = true;
        scheduleTraversals();
        }

        public void scheduleTraversals() {
        if(!mTraversalScheduled) {
        mTraversalScheduled = true;
        sendEmptyMessage(DO_TRAVERSAL); //發(fā)送 DO_TRAVERSAL 消息
        }
        }

        public void handleMessage(Message msg) {
        switch (msg.what) {
        ......
        case DO_TRAVERSAL:
        ......
        performTraversals();//調(diào)用 performTraversals()
        ......
        break;
        ......
        }
        }

        private void performTraversals() {
        finalView host = mView;//還記得這mView嗎?它就是 DecorView
        booleaninitialized = false;
        booleancontentInsetsChanged = false;
        booleanvisibleInsetsChanged;

        try {
        relayoutResult= // 1. 關(guān)鍵函數(shù)relayoutWindow
        relayoutWindow(params, viewVisibility,insetsPending);
        }
        ......
        draw(fullRedrawNeeded);// 2. 開始繪制
        ......
        }

        private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending)throws RemoteException {
        //原來是調(diào)用 IWindowSession 的 relayout(),暫且記住這個調(diào)用
        int relayoutResult = sWindowSession.relayout(mWindow, params, (int) (mView.mMeasuredWidth * appScale + 0.5f), (int) (mView.mMeasuredHeight * appScale + 0.5f), viewVisibility, insetsPending, mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //mSurface 做為參數(shù)傳進(jìn)去了。
        }
        ......
        }

        private void draw(boolean fullRedrawNeeded) {
        Surface surface = mSurface;//mSurface 是 ViewRoot 的成員變量
        ......
        Canvascanvas;

        try {
        int left = dirty.left;
        int top = dirty.top;
        int right = dirty.right;
        int bottom = dirty.bottom;

        //從 mSurface 中 lock 一塊 Canvas
        canvas = surface.lockCanvas(dirty);
        ......
        mView.draw(canvas);//調(diào)用 DecorView 的 draw 函數(shù),canvas 就是畫布
        ......
        //unlock 畫布,屏幕上馬上就能看到 View 的樣子了
        surface.unlockCanvasAndPost(canvas);
        }
        ......
        }

        在 ViewRoot 構(gòu)造時,會創(chuàng)建一個 Surface,它使用無參構(gòu)造函數(shù),代碼如下所示:

        final Surface mSurface = new Surface();
        1
        此時創(chuàng)建完的 Surface 是空的,什么都沒有。接著繼續(xù)分析 relayoutWindow(),在 relayoutWindow() 中會調(diào)用 IWindowSession 的 relayout(),這是一個跨進(jìn)程方法會調(diào)用到 WMS 中的 Session.relayout(),最后調(diào)用到 WindowManagerService.relayoutWindow()。

        public int relayoutWindow(Session session,IWindow client,
        WindowManager.LayoutParams attrs, int requestedWidth,
        int requestedHeight, int viewVisibility, boolean insetsPending,
        Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
        Configuration outConfig, SurfaceoutSurface){
        .....

        try {
        //win 就是 WinState,這里將創(chuàng)建一個本地的 Surface 對象
        Surfacesurface = win.createSurfaceLocked();
        if(surface != null) {
        //先創(chuàng)建一個本地 surface,然后在 outSurface 的對象上調(diào)用 copyFrom
        //將本地 Surface 的信息拷貝到 outSurface 中,為什么要這么麻煩呢?
        outSurface.copyFrom(surface);
        ......
        }

        WindowManagerService.java::WindowState:

        Surface createSurfaceLocked() {
        ......
        try {
        //mSurfaceSession 就是在 Session 上創(chuàng)建的 SurfaceSession 對象
        //這里,以它為參數(shù),構(gòu)造一個新的 Surface 對象
        mSurface = new Surface(mSession.mSurfaceSession, mSession.mPid, mAttrs.getTitle().toString(), 0, w, h, mAttrs.format, flags);
        }
        Surface.openTransaction();//打開一個事務(wù)處理
        ......
        Surface.closeTransaction();//關(guān)閉一個事務(wù)處理
        ......
        }

        構(gòu)造 Surface 對象:

         public Surface(SurfaceSession s,//傳入一個SurfaceSession對象
        int pid, String name, int display, int w, int h, int format, int flags) throws OutOfResourcesException {
        ......
        mCanvas = new CompatibleCanvas();
        //又一個 native 函數(shù)
        init(s,pid,name,display,w,h,format,flags);
        mName = name;
        }

        static void Surface_init(JNIEnv*env, jobject clazz, jobject session, jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags) {

        //從 SurfaceSession 對象中取出之前創(chuàng)建的那個 SurfaceComposerClient 對象
        SurfaceComposerClient* client = (SurfaceComposerClient*)env->GetIntField(session, sso.client);
        sp<SurfaceControl> surface;//注意它的類型是 SurfaceControl
        if (jname == NULL) {
        //調(diào)用 SurfaceComposerClient 的 createSurface 函數(shù),返回的 surface 是一個 SurfaceControl 類型
        surface = client->createSurface(pid, dpy, w, h, format, flags);
        } else{
        ......
        }

        //把這個 surfaceControl 對象設(shè)置到 Java 層的 Surface 對象中
        setSurfaceControl(env, clazz, surface);
        }

        在 createSurface 內(nèi)部會使用 Binder 通信將請求發(fā)給 SurfaceFlinger:

        sp<ISurface>SurfaceFlinger::createSurface(ClientID clientId, int pid, const String8& name, ISurfaceFlingerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) {
        sp<LayerBaseClient> layer;//LayerBaseClient 是 Layer 家族的基類
        //這里又冒出一個 LayerBaseClient 的內(nèi)部類,它也叫Surface
        sp<LayerBaseClient::Surface> surfaceHandle;
        Mutex::Autolock _l(mStateLock);

        //根據(jù) clientId 找到 createConnection 時加入的那個 Client 對象
        sp<Client> client = mClientsMap.valueFor(clientId);
        ......
        //注意這個 id,它的值表示 Client 創(chuàng)建的是第幾個顯示層
        //同時也表示將使用 SharedBufferStatck 數(shù)組的第 id 個元素
        int32_t id = client->generateId(pid);

        //一個 Client 不能創(chuàng)建多于 NUM_LAYERS_MAX 個的Layer
        if(uint32_t(id) >= NUM_LAYERS_MAX) {
        return surfaceHandle;
        }

        //根據(jù) flags 參數(shù)來創(chuàng)建不同類型的顯示層
        switch(flags & eFXSurfaceMask) {
        case eFXSurfaceNormal:
        if (UNLIKELY(flags & ePushBuffers)) {
        //創(chuàng)建 PushBuffer 類型的顯示層
        layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags);
        } else {
        //創(chuàng)建 Normal 類型的顯示層
        layer = createNormalSurfaceLocked(client, d, id, w, h, flags, format);
        }
        break;
        case eFXSurfaceBlur:
        //創(chuàng)建 Blur 類型的顯示層
        layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
        break;
        case eFXSurfaceDim:
        //創(chuàng)建 Dim 類型的顯示層
        layer = createDimSurfaceLocked(client, d, id, w, h, flags);
        break;
        }

        if(layer != 0) {
        layer->setName(name);
        setTransactionFlags(eTransactionNeeded);
        //從顯示層對象中取出一個 ISurface 對象賦值給 SurfaceHandle
        surfaceHandle = layer->getSurface();
        if(surfaceHandle != 0) {
        params->token = surfaceHandle->getToken();
        params->identity = surfaceHandle->getIdentity();
        params->width = w;
        params->height = h;
        params->format = format;
        }
        }
        return surfaceHandle;//ISurface 的 Bn 端就是這個對象
        }

        sp<LayerBaseClient>SurfaceFlinger::createNormalSurfaceLocked(const sp<Client>& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) {
        switch(format) { //一些圖像方面的參數(shù)設(shè)置,可以不去管它
        case PIXEL_FORMAT_TRANSPARENT:
        case PIXEL_FORMAT_TRANSLUCENT:
        format = PIXEL_FORMAT_RGBA_8888;
        break;
        case PIXEL_FORMAT_OPAQUE:
        format = PIXEL_FORMAT_RGB_565;
        break;
        }

        //創(chuàng)建一個 Layer 類型的對象
        sp<Layer> layer = new Layer(this, display,client, id);

        //設(shè)置 Buffer
        status_t err = layer->setBuffers(w, h, format, flags);
        if (LIKELY(err == NO_ERROR)) {
        //初始化這個新 layer 的一些狀態(tài)
        layer->initStates(w, h, flags);
        //下面這個函數(shù)把這個 layer 加入到 Z 軸集合中
        addLayer_l(layer);
        }
        ......
        return layer;
        }

        createNormalSurfaceLocked 函數(shù)有三個關(guān)鍵點,它們是:

        構(gòu)造一個Layer對象。
        調(diào)用Layer對象的setBuffers函數(shù)。
        調(diào)用SF的addLayer_l函數(shù)。
        當(dāng)跨進(jìn)程的 createSurface() 執(zhí)行完返回一個 ISurface 對象,接下來會創(chuàng)建 SurfaceControl 對象:

        SurfaceControl::SurfaceControl(
        const sp<SurfaceComposerClient>& client,
        const sp<ISurface>& surface,
        const ISurfaceFlingerClient::surface_data_t& data,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
        //mClient 為 SurfaceComposerClient,而 mSurface 指向跨進(jìn)程 createSurface() 調(diào)用返回的 ISurface 對象
        :mClient(client), mSurface(surface),
        mToken(data.token), mIdentity(data.identity),
        mWidth(data.width), mHeight(data.height), mFormat(data.format),
        mFlags(flags){
        ......
        }

        SurfaceControl 類可以看作是一個 wrapper 類,它封裝了一些函數(shù),通過這些函數(shù)可以方便地調(diào)用 mClient 或 ISurface 提供的函數(shù)。

        最后會執(zhí)行 copyFrom() 返回給 App 客戶端:

        static void Surface_copyFrom(JNIEnv* env,jobject clazz, jobject other) {
        //根據(jù)JNI函數(shù)的規(guī)則,clazz 是 copyFrom 的調(diào)用對象,而 other 是 copyFrom 的參數(shù)。
        //目標(biāo)對象此時還沒有設(shè)置 SurfaceControl,而源對象在前面已經(jīng)創(chuàng)建了 SurfaceControl
        constsp<SurfaceControl>& surface = getSurfaceControl(env, clazz);
        constsp<SurfaceControl>& rhs = getSurfaceControl(env, other);
        if (!SurfaceControl::isSameSurface(surface, rhs)) {
        //把源 SurfaceControl 對象設(shè)置到目標(biāo) Surface 中
        setSurfaceControl(env, clazz, rhs);
        }
        }

        copyFrom 期間一共有三個關(guān)鍵對象,它們分別是:

        SurfaceComposerClient
        SurfaceControl
        Surface,這個 Surface 對象屬于 Native 層,和 Java 層的 Surface 相對應(yīng)
        其中轉(zhuǎn)移到 ViewRoot 成員變量 mSurface 中的,就是最后這個 Surface 對象了。

        在 SurfaceFlinger 進(jìn)程中,Client 的一個 Layer 將使用 SharedBufferStack 數(shù)組中的一個成員,并通過 SharedBufferServer 結(jié)構(gòu)來控制這個成員,我們知道 SurfaceFlinger 是消費者,所以可由 SharedBufferServer 來控制數(shù)據(jù)的讀取。

        與之相對應(yīng),客戶端的進(jìn)程也會有一個對象來使用這個 SharedBufferStack,可它是通過另外一個叫 SharedBufferClient 的結(jié)構(gòu)來控制的。客戶端為 SurfaceFlinger 提供數(shù)據(jù),所以可由 SharedBufferClient 控制數(shù)據(jù)的寫入。

        三、Surface 顯示過程

        如圖所示,在 App 進(jìn)程中創(chuàng)建 PhoneWindow 后會創(chuàng)建 ViewRoot。ViewRoot 的創(chuàng)建會創(chuàng)建一個 Surface,這個 Surface 其實是空的,通過與 WindowManagerService 通信 copyFrom() 一個 NativeSurface。在與 SurfaceFlinger 通信時,會創(chuàng)建 SharedClient 一段共享內(nèi)存,里面存放的是 SharedBufferStack 對應(yīng) SurfaceFlinger 中的 SurfaceLayer 每個 Layer 其實是一個 FrameBuffer,每個 FrameBuffer 中有兩個 GraphicBuffer 記作 FrontBuffer 和 BackBuffer。

        在 SurfaceFlinger 中 SharedBufferServer 來管理 FrameBuffer。同時在 App 端 copyFrom() 出來 NativeSurface 時會創(chuàng)建一個 SharedBufferClient 與 SharedClient 這塊共享內(nèi)存關(guān)聯(lián)。當(dāng)客戶端 addView() 或者需要更新 View 時,會通過 SharedBufferClient 寫入數(shù)據(jù)到 ShareClient 中,SurfaceFlinger 中的 SharedBufferServer 接收到通知會將 FrameBuffer 中的數(shù)據(jù)傳輸?shù)狡聊簧稀?/p>

        HWComposer 是基于硬件來產(chǎn)生 VSync 信號的,來通知 SurfaceFlinger 重繪控制顯示的幀率。

        原文鏈接:https://blog.csdn.net/freekiteyu/article/details/79483406

        友情推薦:

        Android 開發(fā)干貨集錦

        至此,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章,小編覺得很優(yōu)秀,歡迎點擊閱讀原文,支持原創(chuàng)作者,如有侵權(quán),懇請聯(lián)系小編刪除,歡迎您的建議與指正。同時期待您的關(guān)注,感謝您的閱讀,謝謝!

        點個在看,方便您使用時快速查找!

        瀏覽 41
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产激情电影| 免费人成年激情视频在线观看| 国产综合精品久久久久成人AV| 日韩骚货| 亚洲高清福利视频| 操一线天逼| 亚洲午夜福利视频| 黄色成人在线| 北条麻妃91| 蜜桃av无码一区二区三区| 无码视频在线免费播放| 自慰喷水在线观看| 国产三级一区| 亚洲福利天堂| 国产中文字幕片| 自拍超碰| 中文字幕人妻日韩在线| 黄a在线观看| 日皮在线观看| 成人无码日韩精品| 国产乱伦内射视频| 国产一区二区在线播放| 成人动漫一区| 伊人三级网| 99re6热在线精品视频功能| 青春草在线观看| 特级无码| 亚洲成人性爱网| 三级在线观看视频| 天天色色色| 欧美亚洲成人电影| 国产精品你懂得| 午夜激情国产| 日韩欧美偷拍| 白峰美羽人妻AND-499| 人人操人人看人人摸| 国产精品123| 精品视频在线免费观看| 国产一级a爱做片免费☆观看| 国产91探花秘入口| 中文无码播放| 一级a一级a爰片免费| 亚洲精品久久久久毛片A级绿茶| 五月天综合久久| 久久久久久久久成人| 精品人妻系列| 在线免费三级| 免费无码A片在线观看全| 免费观看黄色视频| 9I看片成人免费视频| 亚洲一区二区视频| 操碰97| 欧美日韩中文字幕在线| 你懂的视频网站| 强伦轩一区二区三区四区| 在线免费看黄色视频| 91丨九色丨熟女新版| 成人一级a片| 婷婷午夜精品久久久久久性色| 一级二级三级毛片| 九九九网站| 欧美最猛黑A片黑人猛交蜜桃视频| 亚洲网站在线免费观看| 国产老女人操逼视频| 蜜桃视频网站在线观看| 成人免看一级a一片| 不卡一二三区| 久久国产热在8| 亚洲最新视频| 日本无码久久嗯啊流水| 亚洲第一狼人综合网| 国产精品久久AV电影| 99热这里| 久久v| 国产精品福利在线| 成人无码区免费A片久久鸭| 黄色视频在线观看网站| 日韩精品视频在线| 色色婷婷五月天| 操操操操操操| 欧美不卡视频| 成人无码在线观看免费视频| 91成人免费视频| 久久高清免费视频| 欧美精产国品一二三区别电影| 性爱无码| 欧美一区二区| 亚洲色无码人妻激情| 欧美日韩国产尤物主播精品| 国产顶级理伦| 91逼逼| а√天堂中文最新版8| 日韩在线观看AV| 国产美女操逼网站| 天天日天天操天天日| 玖玖91| 色吊妞| 大香蕉在线播| 色综合99久久久无码国产精品| 青青成人视频| 九九内射| 亚洲无码AV在线观看| 人人看人人摸人人草| 成人午夜在线视频| 成人精品一区二区三区中文字幕| 日韩亚洲欧美在线观看| 免费高潮视频| 午夜精品18| 国产精品你懂的| 丁香激情网| 中文字幕有码在线观看| 99久久国内精品成人免费| 99青草在线视频| 日产久久久| 日韩无码不卡电影| 国产SUV精品一区二区| 亚洲三级视频在线播出| AV片免费看| 成人免费视频在线| 久热精品在线观看视频| 99视频这里有精品| 无码日| 一区亚洲| 先锋无码| 91超碰在线观看| 偷拍视频网站北条麻妃| 毛片2| 婷婷在线观看免费| 日韩色情电影| 少妇AV| 欧美搡BBBB搡BBB| 亚洲欧洲成人| 九九性爱视频| 欧美性爱综合网| 日韩中文字幕在线视频| 久久91av| 日韩无码波多野结衣| 草久在线观看| AV高清无码在线| 日韩人妻av| 亚洲无码AV在线播放| 婷婷丁香激情| 五月天婷婷激情| 国产曰韩欧美综合另类在线| 色欲天天网| 无码一区二区三区免费看| 色在线视频| 日韩骚货| 成人1区| 北条麻妃被操| 欧美三P囗交做爰| 青草影视久久| 成人免费无码A片免费| 少妇性受XXXX黑人XYX性爽| 久久久波多野结衣| 精品无码一区二区三区的天堂| 91丨PORNY丨丰满人妻网站| a在线免费观看| 91精品无码| 性爱久久久| 久久久精品少妇| 九色91PORNY国产| 无码秘蜜桃吴梦梦| 国产免费自拍视频| 足交在线观看| 成人影视亚洲| 无码人妻91| 日韩精品无码AV| 狠狠躁日日躁夜夜躁A片小说免费 色综合久久久无码中文字幕999 | 丝袜内射| 91久久精品一区二区三区| 成人自拍视频在线| 黄色免费观看网站| 翔田千里一区二区三区| 免费观看无码| 97人妻碰碰中文无码久热丝袜| 午夜理论在线| 台湾无码片| 久草大| 污视频免费在线观看| 在线观看亚洲| 黄片精品| 青青久热| 春宵福利导航| 久久夜色精品| 久久精品综合| 国产成人精品a视频一区| 五月丁香婷婷色色| 伊人999| 国产一级18片视频| 蜜桃网一区二区| 亚洲不卡一区二区三区| 午夜操人妻| 亚洲日本一区二区三区| 国产人妖网站| 综合一区二区三区| A片一级片| 免费在线观看中文字幕| 国产无码做爱视频| 亚洲午夜精品久久久| 欧一美一婬一伦一区二区三区黑人| 日本精品人妻无码77777| 免费的一级A片| 手机在线操B视频| 日本一区二区三区免费观看| 亚洲天堂无码视频| 亚洲中文字幕人妻。| 9I成人免费版视频| 性无码一区二区三区在线观看| 男女日比视频| 熊猫视频91| 黄色国产在线| 日韩无码性爱视频| www香蕉成人片com| 婷婷激情丁香五月天| 亚洲一区2区| 国产一级A| 日韩一二三| 亚洲一线播放| 一区二区三区日本| 东京热在线免费观看| 伊人成人在线视频| 色婷婷欧美| 日韩一级片免费看| 国产精品99久久久久的广告情况 | 一级a一级a爰片免费免免中国A片 一级一级a免一级a做免费线看内裤 | 中文字幕精品在线| 亚洲精品成人无码熟妇在线| 在线免费观看黄色视频网站| 日本高清一区| 成人在线免费观看国产| 老司机午夜免费精品视频| 亚洲小视频在线播放| 九色PORNY自拍视频| 奶头和荫蒂添的好舒服囗交漫画| 毛片A| 69国产精品成人无码视频色| 操逼网站免费| 国产成人视频在线播放| 中文字幕精品一区| 日韩成人网址| 一区二区免费| 99久久久精品久久久久久| 久久精品苍井空免费一区二| 久久精品福利视频| 国产成人精品亚洲男人的天堂| 青青草公开视频| 99热7| 69久久久久久久久久| 97伊人大香蕉| 天堂在线www| 狠狠干狠狠干| 免费高清无码在线| 亚洲日本中文| 国产第一页在线观看| AV无码资源| 四虎日韩| 人妻互换一二三区免费| 蜜桃久久久亚洲精| 91蜜桃传媒在线观看| 骚逼av| 国产精品久久久久久亚洲毛片| 久久婷综合| 爆乳尤物一区二区三区| 玖玖爱AV| 久久久久久9| 亚洲高清无码中文字幕| 男同人到爽无套狂欢| 一区二区三区四区av| 淫淫五月天| 日韩视频播放在线综合| 男女拍拍拍拍| 成人午夜无码福利视频| 日韩乱轮小说与视频| 免费一级AAAAA片在线播放| 五月丁香婷婷色| 久久久久久久香蕉视频| 成人午夜无码| 亚洲精品中文字幕无码| 日本黄在线播放| 成人黄色免费看| 日韩一区二区三区视频| 无码一区二区三区免费看| 中文字幕无码日韩| 俺去俺来也在线www色官网| 成人在线无码视频| 另类老妇videos另类| 超碰激情| 国产熟女一区| 免费a在线观看| 国产精品色情A级毛片| www.午夜| 国产顶级理伦| 无码不卡av| 成人性生活免费视频| 久久久aaa| 日韩乱伦AV| 亚洲香蕉视频| 一级黄色生活片| 亚洲第一av| 国产成人精品国内自产拍免费看 | 午夜视频免费在线观看| 午夜天堂网| 天天操天天操免费视频| 久久天天拍| 久久久一区二区三区四区| 日韩一级在线视频| 无码成人AV| 日本乱伦电影中文字幕| 日韩精品一区在线| 超碰AV在线| 天天操人人操| 天天射天天爽| 国产污视频| 这里只有精品在线观看| 亚洲AVwww| 欧美亚洲日韩在线观看| 亚洲资源站| 欧美成人免费观看| 一级理论片| 怡红院成人AV| 91麻豆精品91久久久ios版| 无毛无码| 成人网站高清无码| 免费射精一二三区| 久久成人网豆花视频| 一级a片免费看| 最新中文| 日韩爱爱视频| 日日摸日日添日日躁AV| 精品69| 美国熟妇| 天天综合网久久综合网| 日韩精品一区二区三免费视频| 婷婷五月无码| 欧美日韩免费在线播放电影在线播放电影在线播放电影免费 | 无码熟妇人妻无码AV在线天堂| 大荫蒂HD大荫蒂视频| 怡红院成人AV| 成人做爰黄AA片免费看三区 | 成人av网站在线播放| 成人视频你懂的| 国产亚洲av| 九九九九九九精品| 国产乱子伦日B视频| 国产麻豆一区二区三区| 成人网视频| 53岁露大奶熟女偷情贴吧| 操逼一级片| 久久亚洲一区| 五月丁香综合激情| 少妇喷水在线观看| 黄色一级免费| 国产最新AV| 尤物视频网| 伊人免费视频在线观看| 国产三级网| 黄色福利网| 北条麻妃无码| 色综合社区| 青青草精品视频| 色香蕉在线视频| 亚洲欧美一区二区三区在线| 成人H视频| 无码一区二区三区在线| 吃奶做爱视频| 国产精品h| 91热爆TS人妖系列| 久久久久久久国产| 熟妇熟女一区二区三区| 日韩不卡| 亚洲成色A片77777在线小说| 亚洲a视频在线| 乱子伦国产精品一区二区| 亚洲国际中文字幕在线| 亚洲无码人妻| 香蕉国产精品| 午夜AV无码| 激情视频在线播放| 中文字幕第六页| 欧美日韩国产成人电影| 亚洲日韩中文字幕在线观看| 天干天干天夜夜| 国产免费黄色视频| 永久免费无码中文字幕| av福利在线观看| 日本三级中文字幕| 99视频自拍| 亚洲人妻在线视频| 日韩高清无码观看| 久草中文在线| 一道本无码在线观看| 无套内射在线免费观看| 成年人A片| 91人妻人人澡人人爽人人精品一| 中文字幕亚洲区| 黑人aV| 亚洲黄色成人网站| 黄色一级片免费观看| 成人做爰100片免费-百度| 国产精品黄片| 国产aaaaaaaaaa| 天天日天天干天天射| 女同久久另类99精品国产91| 北条麻妃无码精品AV怎么看| 在线成人av| 日本特黄视频| 久热国产视频| 青青草原成人在线视频| 久久手机电影| 日韩在线精品视频| 亚洲videos| 乱伦麻豆| 一本大道东京热AV| 做爱的网站| 2025天天干| 六十路老熟女码视频| 国产精品A片| 老熟妇搡BBBB搡BBBB| 先锋影音资源站av每日资源在线| 日韩操逼网站| 无码人妻AⅤ一区二区三区| 美女一级片| 国产TS在线| 欧洲成人无码| 亚洲精品中文字幕无码| 日韩四区| 激情小说亚洲图片:伦| 日老女人的逼| 国产一级婬乱片免费| 日韩一级片在线观看| 91在线无码精品秘国产-百度| 免费AV播放| 久久91视频| 天堂a√在线8| 午夜老司机福利| 小黄片免费| 一区视频免费观看| 777免费观看成人电影视频 | 日本成人毛片| 91N视频| 国产成人精品一区二三区熟女在线 | 丝袜一区| 国产精品一区二区在线播放| 亚洲无码久久| 99热青青草| 午夜美女福利视频| 91成人导航| 久久久久久无码精品亚洲日韩麻豆| 国产AV三级片| 成人免费三级| 牛牛影视一区二区| Japanese在线观看| 美国熟妇| 久久爱成人| 黄片91| 韩国精品一区二区三区| BBB搡BBB搡BBB搡BBB| 熟女高潮| 激情小视频国产在线播放| AV不卡在线| 日韩人妻丝袜中文字幕| 欧美在线一级片| 最新毛片网站〖网:.〗| 在线免费观看黄片| 足交在线观看| 人人上人人干| 蜜臀成人片| 操逼AV无码| 88AV在线| 无码777| 黄色AV网| 一级黄色片免费| 男女拍拍网站| 996精品在线| 午夜毛片| 三级片在线视频| 国产区AV| 俺去也在线视频| 精品无码免费视频| 黄色片A| 琪琪色在线视频| 91精品国产一区| 久久肏屄视频| 在线免费看毛片| 日韩三级久久| 鸡巴操骚逼视频| а中文在线天堂精品| 国产噜噜噜噜久久久久久久久| 精品交换一区二区三区无码| 亚洲无码视频在线| 大香蕉性爱| 日本免费无码| 日本亚洲国产| 操逼a片| 看肏屄视频| 午夜福利AV电影| 无码视频免费| 日韩一级性爱视频| 国产vA| 免费18禁网站| 99精品999| 干欧美美女| 香蕉成人网站在线观看| 丁香五月影院| 鲁鲁鲁鲁鲁鲁鲁777777| 视频一区在线观看| 婷婷五月天激情小说| AAAA毛片| 欧美又粗又长| 一级黄色操逼视频| 91视频中文字幕| 中文最新天堂8√| 人妻无码久久精品| 大香蕉中文视频| 国产精品成人3p一区二区三区| 日本三级AAA三级AAAA97| 亚洲天堂在线观看视频| 日韩A级毛片| 久久久久一| 日韩少妇无码| 按摩性高湖婬AAA片A片中国| 视频一区二区三区免费| 国产精品福利导航| 精品无套| 日本黄色一级视频| www.99视频| 欧美色图色就是色| 欧美一区| 亚洲无码人妻| 日韩精品视频一区二区三区| Av天堂图片在线| 欧美在线黄色| 亚洲精品久久久久avwww潮水| 操逼123首页| a在线观看免费| 国产中文字幕波多| 久久天堂影院| 18久久| 免费观看AV| 亚洲欧洲天堂| A片黄色| 亚洲aⅤ| 超碰在线天天干| 亚洲日逼| 精品一区二区三区毛片| 国产欧美日韩一区| 99久热在线精品视频| 免费看成人A片无码照片88hⅤ| 人人澡人人澡人人澡| 黄色一区二区三区| 俺也去射| 五月丁香视频在线观看| www.99在线| 视色视频在线观看18| 北条麻妃人妻中文字幕91影视 | 一级黄色av| 国产成人一区二区无码| 国产精品播放| 激情五月天导航| 波多野结衣av在线观看| 性性性性性XXXXX| 欧美大片视频| 亚洲狼友| 97成人视频| 日韩黄色一级视频| 日韩高清无码电影| 91亚洲精品视频| 日韩特级片| www.插插| 蜜桃传媒在线播放| 国产一区在线播放| 青青在线| 亚洲高清免费视频| 婷婷五月天无码| 影音先锋天堂网| 这里只有精品在线观看| 国产成人精品免高潮在线人与禽一| 自拍偷拍中文字幕| 翔田千里一区二区| 色男人天堂| 操逼高清无码| 日韩欧美午夜成人无码| 在线免费观看成人视频| 日韩AV网站在线观看| 色色一级| 久久丁香五月天| 欧美日韩狠狠操在线观看视频| a片在线免费观看| 亚洲69| 中文字幕久久无码| 啪啪免费视频| 日韩精品三区| 欧美在线不卡综合| 中文无码熟妇一区二区| 永久免费看片视频5355| 嫩BBB嗓BBBB榛BBBB| 中文字幕视频一区| 在线中文字幕网站| 欧美黄网站| 日韩在线中文字幕| 波多野吉衣视频| 国产在线一二三| 伊人丁香| 久久成人免费视频| 日韩十八禁| 欧美日本亚洲| 一区二区三区免费观看| 99re视频在线| 日日撸| 国产成人精品在线观看| 91大香蕉| 亚日韩视频| 欧美大鸡巴视频| 先锋AV资源站| 色片免费| 男人的天堂网页| 亚洲欧美国产高清vA在线播放| 天天草视频| 黃色一級片黃色一級片尖叫声-百度-百 | 久久精品苍井空免费一区| 国产人妻AV| 成人一区二区电影| 精品AV国产| 亚洲av色图| 做爱A片| 亚洲国产成人精品激情在线| 国产无码内射视频| 日韩18在线| 噜噜| 91N视频| aaa国产精品| 高潮国产| 乱子伦毛片国产| 黄色视频网站观看| 久久精品女同亚洲女同13| 先锋AV资源站| 蜜桃Av噜噜一区二区三区四区| 欧美亚洲日韩在线观看| 在线观看免费黄色| 免费无码一区| 人人操av| 黄色成人18| 性感91影院| 看国产毛片| 亚洲天堂视频网| 中文无码日本高潮喷水| 日韩在线视频网| 亚洲无码A区| 日韩Va| 狠狠躁日日躁夜夜躁A片男男视频 精品无码一区二区三区蜜桃李宗瑞 | 免看一级a一片| 国产18水真多18精品| 综合伊人大香蕉| 欧美日韩成人在线观看| 草莓av| 欧美操b| 黄片网站在线看| 中文字幕+乱码+中文乱码www| AV在线免费观看网站| 亚洲综合激情| 亚洲天堂免费观看| 山东熟妇搡BBBB搡BBBB| 成人国产片女人爽到高潮| 亚洲一道本在线| 色婷婷欧美| 一本色道久久综合无码人妻四虎| 亚洲视频91| 91天堂网| 波多野结衣网站| 成人A视频| 亚洲第一色婷婷| 麻豆md0049免费| 国产激情在线播放| 一本色道88久久加勒比精品| 免费高清无码视频在线观看| 国产乱伦中文字幕| 亚洲色五月| 狼友视频在线看| 青青草娱乐视频| 中文解说AⅤ水果派| 蜜臀99久久精品久久久久久软件 | 免费成人在线看片黄| av片在线免费观看| 亚洲免费在线视频| 亚洲深夜福利| 国产日韩欧美视频| 欧美一区| 亚洲AV无码蜜桃| 天天射网| A亚洲天堂| 午夜精品一区二区三区在线成人| 国产成人精品一区| 日本色色网站| 国产精品视频在线观看| 黄色人妻| 俺去啦俺来也| 内射毛片| 日韩欧美日韩| 超碰997| 精品美女视频| 黑人无码AV黑人天堂无码AV| 嫩BBB嫩BBB嫩BBB| 无码精品一区二区免费| 日韩一级片免费观看| A级成人网站| 丰满少妇一级片| 日本内射在线播放| 欧美a在线观看| 人人色人人操| 亚洲成人一二三区| 日韩三级在线观看| 日韩精品欧美一区二区三区| 中字幕视频在线永久在线观看免费 | 狠狠色噜噜狠狠狠7777| 91人人妻人人澡| 99成人乱码一区二区三区在线 | 亚洲三级片在线| 欧美国产日韩综合在线观看170 | 97视频精品| 国产又粗又猛又爽又黄91精品| 欧美性爱手机在线| 欧美成人在线视频网站| 大荫蒂hd大荫蒂视频| 一区二区视频在线观看| 蜜桃av秘无码一区二区三区| 亚洲第一伊人| 日本成人视频在线免费播放| 中文字幕有码在线播放| 成人性生交大片免费看小芳| 999精品| 免费成人视频在线观看| 天码人妻一区二区三区在线看| 免费观看一区二区三区| av资源站| 东方av在线观看| 国产麻豆| 亚洲成人性爱av| 国产麻豆精品ThePorn| 日韩免费网| 日批视频免费观看| 噜噜影院| 国产无码操逼| 北条麻妃99| 日本色色视频| 国产成人秘一区二区三区东京热 | 国产精品一二三| 开心色色五月天| 国产女人18毛片水真多18| 欧美成人综合一区| 三级黄片网站| 免费在线黄色视频| 日韩精品一级| 先锋影音资源av| 亚洲激情小说| 日本无码久久嗯啊流水| 国产成人精品一区二区三区四区| 人人澡人人摸| 97AV人妻无码视频二区| 成人小视频18| 91精品视频在线播放| 亚洲视频在线观看免费| 丁香五月激情中文字幕| 亚洲经典一| 夜夜骑天天| 久久私人影院| 人妻人人操人人爽| 国产一区二区无码| 青青草五月天色婷婷丁香| 天堂vs亚洲| 日本黄色片在线播放| 国产操逼大片| 日韩成人视频在线| 久久人人爱| 亚洲人妻视频| 国产精品无码永久免费A片| 天天色天天色| 91黑人丨人妻丨国产丨| 69久久久| 一区二区三区四区无码视频 | 国产AV网| A免费在线观看| 97人人色| 色婷婷色99国产综合精品| 嫩BBB槡BBBB槡BBB| 最新AV在线播放| 国产一级A片免费播放| 在线视频一区二区| 国产日产亚洲精品| 69黄色视频| 另类老妇奶性生BBwBB| 国产AV无码一区| 色视频免费在线观看| 国产AV中文| 成人电影一区| 黑人操逼| 男女啪啪啪| www.99在线| 加勒比无码在线播放| 亚洲精品资源| 奇米影视色偷偷| 噼里啪啦免费观看视频大全| 亚韩av| 一级欧美一级日韩片| 91人人澡人人爽人人看| 亚洲精品97久久| 欧美成人日韩| 无码黄页| 色色9999| 乱伦无码高清麻豆视频一区二区| 日本一区二区视频在线观看| 黄片高清视频| 久草视频观看| 日韩性视频| 先锋久久资源| 伊人黄色片| 国产精品93333333| 国产熟女视频| 午夜福利电影无码| 超碰免费人人| 国产乱子伦-区二区三区四区| 欧美精品秘一区二区三区蜜臀| 国产亚洲欧美一区二区| 成人A片免费在线观看| 91亚洲精品在线观看| 自拍AV在线| 美妇肥臀一区二区三区-久久99精品国 | 粉嫩av懂色av蜜臀av分享| 久久久久成人电影| 天天色天天干天天| 亚洲制服中文字幕| 日本一区免费| 欧美色图第一页| 亚洲偷拍中文| www.199麻豆在线观看网站| a4yy午夜福利| a在线视频| 北条麻妃无码av| 东北操逼视频| 日韩高清中文字幕| 日逼视频| 高潮无码在线观看| 亚洲熟妇视频| 欧美日韩小视频| 日韩成人无码片| 日韩性爱片| 东京热在线免费观看| 国产福利视频| 精品一区二区三区四区学生| 日韩大屌| 一区二区高清| 亚洲成人无码片| 亚洲男人的天堂AV| 91探花国产综合在线精品| 亚洲男人综合| 日韩精品无码一区二区三区| 超碰久操| 亚洲中文字幕第一页| 午夜爽爽视频| 丁香五月情| 中国老女人操逼| 欧美性爱XXXX| 在线观看视频国产| 国产成人在线免费视频| 久久免费操| 欧美激情一级| 一道本无码在线| 色婷婷AV| 午夜丁香婷婷| WWWA片| 伊人网站| 在线播放高清无码| 99国产精品99久久久久久粉嫩 | 欧美老妇另类| 国产伦子伦一级A片免费看老牛 | 九九九网站| 黄片一区二区三区| 淫荡五月天视频导航| 国产1级片| 波多野成人无码精品视频| 懂色中文字幕| 亚洲无码中文视频| 九哥草逼网| 欧美性爱永久| www.AV在线| a网站在线观看| 五月天亚洲激情| 天堂久久久久| 国产亚洲视频在线观看| 亚洲三级无码视频| 国产视频激情| 婷婷五月天AV| 国产精品对白| 亚洲欧洲av| 黄片视频免费看| 日韩中文字幕视频在线| 精品人妻午夜一区二区三区四区| 亚洲成人在线播放| www.xxx| 先锋影音AV在线|