日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

renderthread是什么_Android5.0中 hwui 中 RenderThread 工作流程

發布時間:2023/12/3 Android 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 renderthread是什么_Android5.0中 hwui 中 RenderThread 工作流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本篇文章是自己的一個學習筆記,記錄了 Android 5.0 中 hwui 中的 RenderThread 的簡單工作流程。由于是學習筆記,所以其中一些細節不會太詳細,我只是將大概的流程走一遍,將其工作流標注出來,下次遇到問題的時候就可以知道去哪里查。

下圖是我用 Systrace 抓取的一個應用啟動的時候 RenderThread 的第一次 Draw 的 Trace 圖,從這里面的順序來看 RenderThread 的流程。熟悉應用啟動流程的話應該知道,只有當第一次 DrawFrame 完成之后,整個應用的界面才會顯示在手機上,在這之前,用戶看到的是應用的 StartingWindow 的界面。

RenderThread Draw first frame

從Java層說起

應用程序的每一幀是從接收到 VSYNC 信號開始進行計算和繪制的,這要從 Choreographer 這個類說起了,不過由于篇幅原因,我們直接看一幀的繪制調用關系鏈即可:

繪制關系鏈

Choreographer 的 drawFrame 會調用到 ViewRootImpl 的 performTraversals 方法,而 performTraversals 方法最終會調用到performDraw() 方法, performDraw 又會調用到 draw(boolean fullRedrawNeeded) 方法,這個 draw 方法是 ViewRootImpl 的私有方法,和我們熟知的那個draw并不是同一個方法

if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {

mIsAnimating = false;

boolean invalidateRoot = false;

if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {

mHardwareYOffset = yOffset;

mHardwareXOffset = xOffset;

mAttachInfo.mHardwareRenderer.invalidateRoot();

}

mResizeAlpha = resizeAlpha;

dirty.setEmpty();

mBlockResizeBuffer = false;

mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);

}

如果是走硬件繪制路線的話,則會走這一條先,之后就會調用 mHardwareRenderer 的 draw 方法,這里的 mHardwareRenderer 指的是 ThreadedRenderer ,其 Draw 函數如下:

@Override

void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {

attachInfo.mIgnoreDirtyState = true;

long frameTimeNanos = mChoreographer.getFrameTimeNanos();

attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;

long recordDuration = 0;

if (mProfilingEnabled) {

recordDuration = System.nanoTime();

}

updateRootDisplayList(view, callbacks);

if (mProfilingEnabled) {

recordDuration = System.nanoTime() - recordDuration;

}

attachInfo.mIgnoreDirtyState = false;

// register animating rendernodes which started animating prior to renderer

// creation, which is typical for animators started prior to first draw

if (attachInfo.mPendingAnimatingRenderNodes != null) {

final int count = attachInfo.mPendingAnimatingRenderNodes.size();

for (int i = 0; i < count; i++) {

registerAnimatingRenderNode(

attachInfo.mPendingAnimatingRenderNodes.get(i));

}

attachInfo.mPendingAnimatingRenderNodes.clear();

// We don't need this anymore as subsequent calls to

// ViewRootImpl#attachRenderNodeAnimator will go directly to us.

attachInfo.mPendingAnimatingRenderNodes = null;

}

int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,

recordDuration, view.getResources().getDisplayMetrics().density);

if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {

attachInfo.mViewRootImpl.invalidate();

}

}

這個函數里面的 updateRootDisplayList(view, callbacks) ;即 getDisplayList 操作。接下來就是比較重要的一個操作:

int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,

recordDuration, view.getResources().getDisplayMetrics().density);

可以看出這是一個阻塞操作,等Native層完成后,拿到返回值后才會進行下一步的操作。

Native層

其Native代碼在android_view_ThreadedRenderer.cpp中,對應的實現代碼如下:

static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,

jlong proxyPtr, jlong frameTimeNanos, jlong recordDuration, jfloat density) {

RenderProxy* proxy = reinterpret_cast(proxyPtr);

return proxy->syncAndDrawFrame(frameTimeNanos, recordDuration, density);

}

RenderProxy的路徑位于frameworks/base/libs/hwui/renderthread/RenderProxy.cpp

int RenderProxy::syncAndDrawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos,

float density) {

mDrawFrameTask.setDensity(density);

return mDrawFrameTask.drawFrame(frameTimeNanos, recordDurationNanos);

}

其中 mDrawFrameTask 是一個 DrawFrameTask 對象,其路徑位于frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp,其中drawFrame代碼:

int DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) {

mSyncResult = kSync_OK;

mFrameTimeNanos = frameTimeNanos;

mRecordDurationNanos = recordDurationNanos;

postAndWait();

// Reset the single-frame data

mFrameTimeNanos = 0;

mRecordDurationNanos = 0;

return mSyncResult;

}

其中 postAndWait() 的實現如下:

void DrawFrameTask::postAndWait() {

AutoMutex _lock(mLock);

mRenderThread->queue(this);

mSignal.wait(mLock);

}

就是將一個 DrawFrameTask 放入到了 mRenderThread 中,其中 queue 方法實現如下:

void RenderThread::queue(RenderTask* task) {

AutoMutex _lock(mLock);

mQueue.queue(task);

if (mNextWakeup && task->mRunAt < mNextWakeup) {

mNextWakeup = 0;

mLooper->wake();

}

}

其中 mQueue 是一個 TaskQueue 對象,其

void TaskQueue::queue(RenderTask* task) {

// Since the RenderTask itself forms the linked list it is not allowed

// to have the same task queued twice

LOG_ALWAYS_FATAL_IF(task->mNext || mTail == task, "Task is already in the queue!");

if (mTail) {

// Fast path if we can just append

if (mTail->mRunAt <= task->mRunAt) {

mTail->mNext = task;

mTail = task;

} else {

// Need to find the proper insertion point

RenderTask* previous = 0;

RenderTask* next = mHead;

while (next && next->mRunAt <= task->mRunAt) {

previous = next;

next = next->mNext;

}

if (!previous) {

task->mNext = mHead;

mHead = task;

} else {

previous->mNext = task;

if (next) {

task->mNext = next;

} else {

mTail = task;

}

}

}

} else {

mTail = mHead = task;

}

}

接著看 RenderThread 之前的 queue 方法,

void Looper::wake() {

ssize_t nWrite;

do {

nWrite = write(mWakeWritePipeFd, "W", 1);

} while (nWrite == -1 && errno == EINTR);

if (nWrite != 1) {

if (errno != EAGAIN) {

ALOGW("Could not write wake signal, errno=%d", errno);

}

}

}

wake 函數則更為簡單,僅僅向管道的寫端寫入一個字符“W”,這樣管道的讀端就會因為有數據可讀而從等待狀態中醒來。

HWUI-RenderThread

接下來會到哪里去,我們首先要熟悉一下RenderThread,RenderThread是繼承自Thread的,這個Thread是utils/Thread.h,RenderThread的初始化函數

RenderThread::RenderThread() : Thread(true), Singleton()

, mNextWakeup(LLONG_MAX)

, mDisplayEventReceiver(0)

, mVsyncRequested(false)

, mFrameCallbackTaskPending(false)

, mFrameCallbackTask(0)

, mRenderState(NULL)

, mEglManager(NULL) {

mFrameCallbackTask = new DispatchFrameCallbacks(this);

mLooper = new Looper(false);

run("RenderThread");

}

其 run 方法在 Thread 中有說明:

// Start the thread in threadLoop() which needs to be implemented.

virtual status_t run( const char* name = 0,

int32_t priority = PRIORITY_DEFAULT,

size_t stack = 0);

即啟動 threadLoop 函數,我們來看 RenderThread 的 threadLoop 函數,這個函數比較重要:

bool RenderThread::threadLoop() {

#if defined(HAVE_PTHREADS)

setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);

#endif

initThreadLocals();

int timeoutMillis = -1;

for (;;) {

int result = mLooper->pollOnce(timeoutMillis);

LOG_ALWAYS_FATAL_IF(result == Looper::POLL_ERROR,

"RenderThread Looper POLL_ERROR!");

nsecs_t nextWakeup;

// Process our queue, if we have anything

while (RenderTask* task = nextTask(&nextWakeup)) {

task->run();

// task may have deleted itself, do not reference it again

}

if (nextWakeup == LLONG_MAX) {

timeoutMillis = -1;

} else {

nsecs_t timeoutNanos = nextWakeup - systemTime(SYSTEM_TIME_MONOTONIC);

timeoutMillis = nanoseconds_to_milliseconds(timeoutNanos);

if (timeoutMillis < 0) {

timeoutMillis = 0;

}

}

if (mPendingRegistrationFrameCallbacks.size() && !mFrameCallbackTaskPending) {

drainDisplayEventQueue(true);

mFrameCallbacks.insert(

mPendingRegistrationFrameCallbacks.begin(), mPendingRegistrationFrameCallbacks.end());

mPendingRegistrationFrameCallbacks.clear();

requestVsync();

}

}

return false;

}

可以看到,一個 for 循環是一個無限循環,而其中 pollOnce 是一個阻塞函數,直到我們上面調用了 mLooper->wake() 之后,會繼續往下走,走到 while 循環中:

while (RenderTask* task = nextTask(&nextWakeup)) {

task->run();

// task may have deleted itself, do not reference it again

}

會將 RenderTask 取出來執行其 run 方法,經過前面的流程我們知道這個 RenderTask 是一個 DrawFrameTask ,其run方法如下:

void DrawFrameTask::run() {

ATRACE_NAME("DrawFrame");

mContext->profiler().setDensity(mDensity);

mContext->profiler().startFrame(mRecordDurationNanos);

bool canUnblockUiThread;

bool canDrawThisFrame;

{

TreeInfo info(TreeInfo::MODE_FULL, mRenderThread->renderState());

canUnblockUiThread = syncFrameState(info);

canDrawThisFrame = info.out.canDrawThisFrame;

}

// Grab a copy of everything we need

CanvasContext* context = mContext;

// From this point on anything in "this" is *UNSAFE TO ACCESS*

if (canUnblockUiThread) {

unblockUiThread();

}

if (CC_LIKELY(canDrawThisFrame)) {

context->draw();

}

if (!canUnblockUiThread) {

unblockUiThread();

}

}

RenderThread.DrawFrame

上面說到了 DrawFrameTask 的 run 方法,這里 run 方法中的執行的方法即我們在最前面那張圖中所示的部分(即文章最前面那張圖),下面的流程就是那張圖中的函數調用,我們結合代碼和圖,一部分一部分來走整個 DrawFrame 的流程:

1. syncFrameState

第一個比較重要的函數是 syncFrameState ,從函數名就可以知道, syncFrameState 的作用就是同步 frame 信息,將 Java 層維護的 frame 信息同步到 RenderThread中。

Main Thread 和Render Thread 都各自維護了一份應用程序窗口視圖信息。各自維護了一份應用程序窗口視圖信息的目的,就是為了可以互不干擾,進而實現最大程度的并行。其中,Render Thread維護的應用程序窗口視圖信息是來自于 Main Thread 的。因此,當Main Thread 維護的應用程序窗口信息發生了變化時,就需要同步到 Render Thread 去。

所以查看代碼就可以知道有兩個 RenderNode,一個在 hwui 中,一個在 View 中。簡單來說,同步信息就是將 Java 層的 RenderNode 中的信息同步到 hwui 中的 RenderNode 中。 注意syncFrameState的返回值賦給了 canUnblockUiThread ,從名字可以看出這個 canUnblockUiThread 的作用是判斷是否喚醒 Main Thread ,也就是說如果返回為 true 的話,會提前喚醒主線程來執行其他的事情,而不用等到 draw 完成后再去喚醒 Main Thread。 這也是 Android 5.0 和 Android 4.x 最大的區別了。

syncFrameState

bool DrawFrameTask::syncFrameState(TreeInfo& info) {

mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos);

mContext->makeCurrent();

Caches::getInstance().textureCache.resetMarkInUse();

for (size_t i = 0; i < mLayers.size(); i++) {

mContext->processLayerUpdate(mLayers[i].get());

}

mLayers.clear();

mContext->prepareTree(info);

if (info.out.hasAnimations) {

if (info.out.requiresUiRedraw) {

mSyncResult |= kSync_UIRedrawRequired;

}

}

// If prepareTextures is false, we ran out of texture cache space

return info.prepareTextures;

}

首先是makeCurrent,這里的mContext是一個CanvasContext對象,其makeCurrent實現如下:

void CanvasContext::makeCurrent() {

// In the meantime this matches the behavior of GLRenderer, so it is not a regression

mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface);

}

mEglManager是一個EglManager對象,其實現為:

bool EglManager::makeCurrent(EGLSurface surface) {

if (isCurrent(surface)) return false;

if (surface == EGL_NO_SURFACE) {

// If we are setting EGL_NO_SURFACE we don't care about any of the potential

// return errors, which would only happen if mEglDisplay had already been

// destroyed in which case the current context is already NO_CONTEXT

TIME_LOG("eglMakeCurrent", eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

} else {

EGLBoolean success;

TIME_LOG("eglMakeCurrent", success = eglMakeCurrent(mEglDisplay, surface, surface, mEglContext));

if (!success) {

LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s",

(void*)surface, egl_error_str());

}

}

mCurrentSurface = surface;

return true;

}

這里會判斷mCurrentSurface == surface,如果成立,則不用再初始化操作,如果是另外一個surface。,則會執行eglMakeCurrent,來重新創建上下文。

makeCurrent之后,會調用mContext->prepareTree(info),其實現如下:

void CanvasContext::prepareTree(TreeInfo& info) {

mRenderThread.removeFrameCallback(this);

info.damageAccumulator = &mDamageAccumulator;

info.renderer = mCanvas;

if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) {

info.canvasContext = this;

}

mAnimationContext->startFrame(info.mode);

mRootRenderNode->prepareTree(info);

mAnimationContext->runRemainingAnimations(info);

if (info.canvasContext) {

freePrefetechedLayers();

}

int runningBehind = 0;

// TODO: This query is moderately expensive, investigate adding some sort

// of fast-path based off when we last called eglSwapBuffers() as well as

// last vsync time. Or something.

TIME_LOG("nativeWindowQuery", mNativeWindow->query(mNativeWindow.get(),

NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind));

info.out.canDrawThisFrame = !runningBehind;

if (info.out.hasAnimations || !info.out.canDrawThisFrame) {

if (!info.out.requiresUiRedraw) {

// If animationsNeedsRedraw is set don't bother posting for an RT anim

// as we will just end up fighting the UI thread.

mRenderThread.postFrameCallback(this);

}

}

}

其中 mRootRenderNode->prepareTree(info) 又是最重要的。回到Java層,我們知道 ThreadedRenderer 在初始化時,初始化了一個指針

long rootNodePtr = nCreateRootRenderNode();

這個RootRenderNode也就是一個根Node,

mRootNode = RenderNode.adopt(rootNodePtr);

然后會創建一個 mNativeProxy 指針,在 Native 層初始化一個 RenderProxy 對象,將 rootNodePtr 傳給 RenderProxy 對象,這樣在 RenderProxy 我們就可以得到這個對象的指針了。其中 CanvasContext 也是在 RenderProxy 對象初始化的時候被初始化的,初始化的時候將 rootNodePtr 傳給了 CanvasContext 對象。

我們之前提到 ThreadedRenderer 的 draw 方法中首先會調用updateRootDisplayList,即我們熟悉的 getDisplayList 。這個方法中,其實也分為兩個步驟,第一個步驟是 updateViewTreeDisplayList,第二個步驟是將根 Node 加入到 DrawOp 中:

canvas.insertReorderBarrier();

canvas.drawRenderNode(view.getDisplayList());

canvas.insertInorderBarrier();

其最終實現在

status_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) {

LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");

// dirty is an out parameter and should not be recorded,

// it matters only when replaying the display list

DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform());

addRenderNodeOp(op);

return DrawGlInfo::kStatusDone;

}

再回到我們之前的 CanvasContext.prepareTree 中提到的 mRootRenderNode->prepareTree(info),這時候這里的 mRootRenderNode 就是 CanvasContext 初始化是傳進來的。

其實現在 RenderNode.cpp 中:

void RenderNode::prepareTree(TreeInfo& info) {

prepareTreeImpl(info);

}

void RenderNode::prepareTreeImpl(TreeInfo& info) {

TT_START_MARK(getName());

info.damageAccumulator->pushTransform(this);

if (info.mode == TreeInfo::MODE_FULL) {

pushStagingPropertiesChanges(info); //同步當前正在處理的Render Node的Property

}

uint32_t animatorDirtyMask = 0;

if (CC_LIKELY(info.runAnimations)) {

animatorDirtyMask = mAnimatorManager.animate(info);//執行動畫相關的操作

}

prepareLayer(info, animatorDirtyMask);

if (info.mode == TreeInfo::MODE_FULL) {

pushStagingDisplayListChanges(info); //同步當前正在處理的Render Node的Display List

}

prepareSubTree(info, mDisplayListData); //同步當前正在處理的Render Node的Display List引用的Bitmap,以及當前正在處理的Render Node的子Render Node的Display List等信息

pushLayerUpdate(info); //檢查當前正在處理的Render Node是否設置了Layer。如果設置了的話,就對這些Layer進行處理

info.damageAccumulator->popTransform();

TT_END_MARK();

}

這里所涉及到的進一步的具體操作大家可以自行去看代碼。

2. draw

Draw

執行完syncFrameState之后,接下來就是執行draw

if (CC_LIKELY(canDrawThisFrame)) {

context->draw();

}

CanvasContext的draw函數是一個核心函數,其位置在 frameworks/base/libs/hwui/OpenGLRenderer.cpp ,其實現如下:

void CanvasContext::draw() {

profiler().markPlaybackStart();

SkRect dirty;

mDamageAccumulator.finish(&dirty);

......

status_t status;

if (!dirty.isEmpty()) {

status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,

dirty.fRight, dirty.fBottom, mOpaque);

} else {

status = mCanvas->prepare(mOpaque);

}

Rect outBounds;

status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);

profiler().draw(mCanvas);

mCanvas->finish();

profiler().markPlaybackEnd();

if (status & DrawGlInfo::kStatusDrew) {

swapBuffers();

}

profiler().finishFrame();

/// M: enable to get overdraw count

if (CC_UNLIKELY(g_HWUI_debug_overdraw)) {

if (!mDebugOverdrawLayer) {

mDebugOverdrawLayer = LayerRenderer::createRenderLayer(mRenderThread.renderState(),

mCanvas->getWidth(), mCanvas->getHeight());

} else if (mDebugOverdrawLayer->layer.getWidth() != mCanvas->getWidth() ||

mDebugOverdrawLayer->layer.getHeight() != mCanvas->getHeight()) {

if (!LayerRenderer::resizeLayer(mDebugOverdrawLayer, mCanvas->getWidth(), mCanvas->getHeight())) {

LayerRenderer::destroyLayer(mDebugOverdrawLayer);

mDebugOverdrawLayer = NULL;

}

}

......

}

2.1 eglBeginFrame

首先來看eglBeginFrame的實現

void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {

makeCurrent(surface);

if (width) {

eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);

}

if (height) {

eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);

}

eglBeginFrame(mEglDisplay, surface);

}

makeCurrent是用來管理上下文,eglBeginFrame主要是校驗參數的合法性。

2.2 prepareDirty

status_t status;

if (!dirty.isEmpty()) {

status = mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,

dirty.fRight, dirty.fBottom, mOpaque);

} else {

status = mCanvas->prepare(mOpaque);

}

這里的mCanvas是一個OpenGLRenderer對象,其prepareDirty實現

//TODO:增加函數功能描述

status_t OpenGLRenderer::prepareDirty(float left, float top,

float right, float bottom, bool opaque) {

setupFrameState(left, top, right, bottom, opaque);

// Layer renderers will start the frame immediately

// The framebuffer renderer will first defer the display list

// for each layer and wait until the first drawing command

// to start the frame

if (currentSnapshot()->fbo == 0) {

syncState();

updateLayers();

} else {

return startFrame();

}

return DrawGlInfo::kStatusDone;

}

2.3 drawRenderNode

Rect outBounds;

status |= mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);

接下來就是調用OpenGLRenderer的drawRenderNode方法進行繪制

status_t OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) {

status_t status;

// All the usual checks and setup operations (quickReject, setupDraw, etc.)

// will be performed by the display list itself

if (renderNode && renderNode->isRenderable()) {

// compute 3d ordering

renderNode->computeOrdering();

if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { //判斷是否不重排序

status = startFrame();

ReplayStateStruct replayStruct(*this, dirty, replayFlags);

renderNode->replay(replayStruct, 0);

return status | replayStruct.mDrawGlStatus;

}

// 需要重新排序

bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs!

DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw);

DeferStateStruct deferStruct(deferredList, *this, replayFlags);

renderNode->defer(deferStruct, 0); //遞歸進行重排操作

flushLayers(); // 首先執行設置了 Layer 的子 Render Node 的繪制命令,以便得到一個對應的FBO

status = startFrame(); //執行一些諸如清理顏色繪沖區等基本操作

status = deferredList.flush(*this, dirty) | status;

return status;

}

// Even if there is no drawing command(Ex: invisible),

// it still needs startFrame to clear buffer and start tiling.

return startFrame();

}

這里的 renderNode 是一個 Root Render Node,

可以看到,到了這里雖然只是開始,但是其實已經結束了,這個函數里面最重要的幾步:

renderNode->defer(deferStruct, 0); //進行重排序

flushLayers(); 首先執行設置了 Layer 的子 Render Node 的繪制命令,以便得到一個對應的FBO

status = deferredList.flush(*this, dirty) | status; //對deferredList中的繪制命令進行真正的繪制操作

這幾個是渲染部分真正的核心部分,其中的代碼細節需要自己去研究。老羅在這部分講的很細,有空可以去看看他的文章Android應用程序UI硬件加速渲染的Display List渲染過程分析.

2.4 swapBuffers

if (status & DrawGlInfo::kStatusDrew) {

swapBuffers();

}

其核心就是調用EGL的 eglSwapBuffers(mEglDisplay, surface), duration)函數。

2.5 FinishFrame

profiler().finishFrame();

主要是記錄時間信息。

總結

鑒于我比較懶,而且總結能力不如老羅,就直接把他的總結貼過來了。

RenderThread的總的流程如下:

將Main Thread維護的Display List同步到Render Thread維護的Display List去。這個同步過程由Render Thread執行,但是Main Thread會被阻塞住。

如果能夠完全地將Main Thread維護的Display List同步到Render Thread維護的Display List去,那么Main Thread就會被喚醒,此后Main Thread和Render Thread就互不干擾,各自操作各自內部維護的Display List;否則的話,Main Thread就會繼續阻塞,直到Render Thread完成應用程序窗口當前幀的渲染為止。

Render Thread在渲染應用程序窗口的Root Render Node的Display List之前,首先將那些設置了Layer的子Render Node的Display List渲染在各自的一個FBO上,接下來再一起將這些FBO以及那些沒有設置Layer的子Render Node的Display List一起渲染在Frame Buffer之上,也就是渲染在從Surface Flinger請求回來的一個圖形緩沖區上。這個圖形緩沖區最終會被提交給Surface Flinger合并以及顯示在屏幕上。

第2步能夠完全將Main Thread維護的Display List同步到Render Thread維護的Display List去很關鍵,它使得Main Thread和Render Thread可以并行執行,這意味著Render Thread在渲染應用程序窗口當前幀的Display List的同時,Main Thread可以去準備應用程序窗口下一幀的Display List,這樣就使得應用程序窗口的UI更流暢。

注意最后一段,在 Android 4.x 時代,沒有RenderThread的時代,只有 Main Thread ,也就是說 必須要等到 Draw 完成后,才會去準備下一幀的數據,如下圖:

Paste_Image.png

Android5.0 之后,如老羅所說,有兩種情況,

Main Thread 和 Render Thread

Render Thread 提前喚醒了 Main Thread

可以看到第二張圖中,Render Thread 并沒有繪制完成,但是由于其提前喚醒了 Main Thread ,所以 Main Thread 在下一個Vsync信號到來的時候,響應了Vsync事件,開始準備下一幀。

此時雖然由于第一幀繪制時間過長,導致掉了一幀,但是第二幀沒有收到任何影響。

總結

以上是生活随笔為你收集整理的renderthread是什么_Android5.0中 hwui 中 RenderThread 工作流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

黄色成人av在线 | 亚洲激情久久 | 狠狠操欧美 | 久草免费在线观看 | 日韩亚洲在线 | 久久玖| 黄色影院在线免费观看 | 免费久久网站 | 人人爱天天操 | 亚洲欧美日韩中文在线 | 久久久久中文 | 狠狠干夜夜 | 99久久夜色精品国产亚洲96 | 四虎永久免费网站 | 欧美福利网址 | 夜夜操天天干, | 亚洲涩涩网 | 午夜狠狠干| 九九免费在线观看 | 日韩在线观看第一页 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 国产精品欧美久久久久天天影视 | 久久精品免费电影 | 久久免费在线视频 | 在线电影播放 | 四虎国产精品免费 | 国产精品久久久视频 | 精品久久久久久亚洲综合网 | 伊人五月在线 | 免费av影视| 91成人免费在线 | 欧美日韩3p| 91视频链接 | 欧洲精品视频一区二区 | 久久久久久综合网天天 | 久久精品国产亚洲 | 国内久久看 | 麻豆系列在线观看 | 狠狠干婷婷 | 天天做天天爱夜夜爽 | 日本中文字幕在线播放 | 国产精品久久久久久吹潮天美传媒 | 久久99这里只有精品 | 国产黄色免费看 | 中文字幕色网站 | 国产中文字幕久久 | 欧美国产日韩一区 | 久久久久欠精品国产毛片国产毛生 | 成年人在线看视频 | 97精品久久人人爽人人爽 | 日本三级久久 | www.99在线观看 | 成人精品久久久 | 久久美女视频 | 亚洲一级二级三级 | 就要干b | 精品免费久久久久 | 成年人在线免费看片 | 国产手机视频 | 天天天天天天干 | 国产v视频 | 色多多污污在线观看 | 中文在线8资源库 | 99r国产精品| 国产精品区一区 | 九九九在线观看 | 日日麻批40分钟视频免费观看 | 性日韩欧美在线视频 | av网站免费看 | 久草电影免费在线观看 | 国产精品久久久久999 | 欧美一区二区在线刺激视频 | 日本成人中文字幕在线观看 | 天天综合天天做天天综合 | 中文字幕视频观看 | 天天天色综合a | 色婷婷狠 | 五月天堂网 | 99久久久久久久 | www.成人久久| 亚洲视频免费在线看 | 国产一区二区在线播放视频 | 天天干天天摸天天操 | 久久免费国产精品1 | 91一区啪爱嗯打偷拍欧美 | 午夜精品久久久久久 | 欧美成人aa | 久久久久亚洲精品中文字幕 | 日韩欧美一区视频 | 国产一级二级视频 | 国产一在线精品一区在线观看 | 人人插人人舔 | 日本精品久久久久中文字幕 | 又爽又黄又无遮挡网站动态图 | 国产免费嫩草影院 | 色妞久久福利网 | 成人动漫一区二区 | 人人草在线观看 | 成人一级片在线观看 | 日日干视频 | 亚洲无吗视频在线 | 探花视频免费在线观看 | av丝袜制服 | 久久网站av | 国产玖玖在线 | 五月婷婷狠狠 | 一区二区三区日韩精品 | 日韩xxx视频| 中文字幕第一页在线播放 | 久久久视频在线 | 国产精品99精品久久免费 | 天天干,天天操,天天射 | 天天色天天色天天色 | 国产剧情一区在线 | 丝袜网站在线观看 | 日本久热 | 国产成人av电影 | 激情网站免费观看 | 91大神在线观看视频 | 97超碰人人模人人人爽人人爱 | 国产精品久久久久久久久久不蜜月 | 亚洲丝袜一区二区 | 二区中文字幕 | 国产一级二级视频 | 九九视频一区 | 色婷婷一区 | 18+视频网站链接 | 国产精品9999| 日韩欧美综合 | 国产一区成人 | 玖玖在线精品 | 这里只有精品视频在线 | 日本韩国精品一区二区在线观看 | 日韩精品久久久久久中文字幕8 | 久久久久久蜜av免费网站 | 国产精品乱码一区二三区 | 国产视频91在线 | 97视频总站 | 99re热精品视频 | 在线导航福利 | 国产成人一区二区啪在线观看 | 久热超碰 | 婷婷色在线观看 | 黄色国产在线观看 | 久久私人影院 | a午夜电影| 91热在线 | 日韩久久久久久 | 日韩成人精品在线观看 | 国产精品中文字幕在线观看 | 激情网婷婷 | av免费在线网| 国产在线中文 | 日日夜夜天天久久 | 成人av在线电影 | 欧美久久99 | 国内精品久久久久 | 97人人超碰在线 | 麻豆国产精品一区二区三区 | 欧美亚洲精品一区 | 日韩免费看片 | 婷婷久月| 久久精品久久99 | 国产精品久久久一区二区三区网站 | 久久 国产一区 | 国产精品亚洲a | 国色天香第二季 | 国产精品久久久久久久久久东京 | 久久99久久99精品免视看婷婷 | 97色婷婷成人综合在线观看 | 成人免费在线视频观看 | 亚洲最新视频在线 | 人人爽人人 | 婷婷草| 国产美女精品 | 亚洲欧美视频在线 | 国产美女精品久久久 | 三上悠亚一区二区在线观看 | 久久草网| 久久久精品综合 | 在线 国产 日韩 | 久久久久看片 | 日本黄色免费大片 | 日韩大片在线免费观看 | 欧美日韩国产一区 | 色网站在线免费观看 | 免费成人av在线看 | 亚洲最新在线 | 国精产品999国精产品岳 | 国产一性一爱一乱一交 | 在线中文字幕观看 | 四虎视频| 久久久久久久久久久久亚洲 | 国产高清视频在线播放一区 | 日韩av二区| 国产91在| 国产精品久久久久久麻豆一区 | 最新国产中文字幕 | 国产中年夫妇高潮精品视频 | 日韩欧美精品在线观看视频 | 国产91在线观 | 国产精品国内免费一区二区三区 | 国产九九九九九 | a天堂一码二码专区 | 日韩 国产 | avav99| 天天久久综合 | 久久97超碰 | 在线观看aa | 色综合天天色综合 | 久久xxxx| 欧美日韩一区二区三区不卡 | 午夜在线日韩 | 在线观看资源 | 久久精品久久99 | 网站在线观看你们懂的 | 色婷婷av一区 | 国产成人一区二区三区影院在线 | 激情五月婷婷激情 | 麻豆视频在线播放 | 国产在线观看高清视频 | 在线不卡a| 99久久婷婷国产综合精品 | 99久久日韩精品视频免费在线观看 | 一区免费视频 | av免费电影在线观看 | 毛片精品免费在线观看 | 99色资源 | 五月天婷婷视频 | 亚洲精品裸体 | 99欧美视频 | 国产精品久久久久久久久蜜臀 | 免费看色视频 | 国产理论影院 | 激情五月激情综合网 | 波多野结衣一区二区三区中文字幕 | 7777xxxx| 国产精品久久久久久影院 | 亚洲国产精品久久久 | 少妇搡bbb| 精品国产伦一区二区三区观看说明 | 久久经典视频 | 一区二区激情视频 | 九九热精 | 99精品国产免费久久久久久下载 | 久久亚洲综合国产精品99麻豆的功能介绍 | 在线观看视频一区二区三区 | 美女久久久久久久 | 久久成年人网站 | 一区二区在线影院 | 人人玩人人弄 | 国产黄在线免费观看 | 在线免费观看视频一区二区三区 | 亚洲黄色小说网址 | 91九色pron| 亚洲一区二区三区精品在线观看 | 久热免费在线 | 国产三级视频 | 99久久精品久久亚洲精品 | 天天艹日日干 | 在线亚洲午夜片av大片 | 国产在线精品一区二区三区 | 日韩在线二区 | 亚洲精品在线二区 | 欧美另类sm图片 | 亚洲激情在线播放 | 中文av资源站 | 国产打女人屁股调教97 | av在线亚洲天堂 | 日韩免费看视频 | 91在线看| 97免费中文视频在线观看 | 婷五月天激情 | 国产日韩高清在线 | 99精品免费网 | a在线v| 麻豆视频在线免费观看 | 日韩在线观看视频一区二区三区 | 日韩在线字幕 | 国产一区二区三区视频在线 | 91免费试看 | 亚洲欧美婷婷六月色综合 | 毛片888| 国产污视频在线观看 | av天天干| 久久久久久毛片精品免费不卡 | 免费h在线观看 | 区一区二区三在线观看 | 五月综合色婷婷 | 精品专区一区二区 | 中文字幕免费在线 | 国产精品一区二区三区四 | 天天操天天操天天操 | 日本xxxx.com | 亚洲丝袜一区二区 | 中文字幕亚洲欧美日韩2019 | 波多野结衣动态图 | 色婷婷综合成人av | 欧美中文字幕久久 | 能在线看的av | 婷婷久月 | 日本一区二区免费在线观看 | 色99视频 | 久久综合五月 | 91av片 | 亚洲国产视频直播 | 视频在线观看日韩 | 在线观看日韩专区 | 91精品国产麻豆国产自产影视 | 欧美一二区在线 | 免费观看成年人视频 | 黄污在线观看 | 一区二区三区高清在线观看 | 97国产精品亚洲精品 | 天天爽夜夜爽精品视频婷婷 | 精品96久久久久久中文字幕无 | 国产又粗又猛又爽又黄的视频先 | 久久久久久久久久国产精品 | 欧美精品网站 | 日韩久久一区 | 狠狠ri| 色婷五月| 日本久久久精品视频 | 好看的国产精品视频 | 伊人亚洲精品 | 久久精品国产亚洲精品 | 一区二区三区电影 | 亚洲成人欧美 | 国产伦理一区二区 | 国产精品久久艹 | 久草在线视频免赞 | 在线视频欧美亚洲 | 91麻豆精品一区二区三区 | 人人爽人人爽人人 | 99精品在线免费在线观看 | 欧美一区二区三区免费观看 | 五月天视频网站 | 国产a级精品 | 少妇性色午夜淫片aaaze | 国产尤物在线 | 国产3p视频 | 欧美va在线观看 | 99久久精品久久亚洲精品 | 日韩sese| 91视频在线观看大全 | 天堂资源在线观看视频 | 91精品国产91久久久久久三级 | 99精品在线看 | av在线免费网 | 精品一区二区在线观看 | 国产亚洲精品av | 婷香五月 | 男女免费视频观看 | 欧美成人精品xxx | 99婷婷狠狠成为人免费视频 | 久久精品中文字幕免费mv | 日韩精品一区二区三区视频播放 | 最近最新中文字幕 | 97免费公开视频 | 国产精品一区二区三区在线看 | 一区二区不卡视频在线观看 | 国产区久久| 成人一级在线观看 | 激情五月播播久久久精品 | 91黄色在线看 | 久久人人添人人爽添人人88v | 国产色视频一区二区三区qq号 | 91中文视频| 国产精选在线 | 日韩av进入 | 日本久久中文 | 国产精品国产亚洲精品看不卡 | 永久免费精品视频 | 欧美一级小视频 | 最近中文字幕第一页 | 九九亚洲视频 | 福利视频一区二区 | 日韩av资源站 | 玖玖在线观看视频 | 欧美爽爽爽 | 五月婷在线 | 国产91免费观看 | 国产精品国产自产拍高清av | 久久精品电影网 | 四虎成人在线 | 国产精品久免费的黄网站 | 亚洲,国产成人av | 日韩精品一区二区三区水蜜桃 | 久久免费黄色网址 | 51久久成人国产精品麻豆 | 视频在线亚洲 | 欧美一区二区伦理片 | 一区av在线播放 | 国产精品毛片久久久久久久久久99999999 | 久久国内精品 | 天天操夜夜干 | 天天干天天干天天干天天干天天干天天干 | 狠狠狠狠狠狠天天爱 | 精品二区视频 | 永久免费视频国产 | 久久99精品国产91久久来源 | 国产中文字幕视频在线观看 | 国产精品成人国产乱 | 欧美激情亚洲综合 | 网站免费黄 | 久久久夜色 | 91在线精品观看 | 成人在线播放免费观看 | 美女精品 | 美女黄濒 | 最新国产精品久久精品 | 天天插天天操天天干 | 国产精品白浆视频 | 久久99久久99精品免观看粉嫩 | 麻豆视频免费入口 | 国产精品久久久久久久久毛片 | 国精产品999国精产品视频 | 黄色网在线播放 | 久久久亚洲麻豆日韩精品一区三区 | 午夜精品久久久久久99热明星 | 日韩成人精品在线观看 | 久久久精品视频成人 | 中文字幕网站视频在线 | 成人在线黄色电影 | 国产手机视频在线播放 | av看片在线观看 | 日韩性久久 | www.久久色 | 日韩欧美69 | 午夜久久影视 | 国产99久久久精品 | 欧美激情精品久久久 | 精品国产_亚洲人成在线 | 成人欧美日韩国产 | 国产中文字幕一区 | 亚洲mv大片欧洲mv大片免费 | 日韩欧美一区二区三区免费观看 | 中文字幕免费高清 | 婷婷精品国产一区二区三区日韩 | 午夜.dj高清免费观看视频 | 97视频免费看 | 精品在线视频观看 | 五月开心婷婷 | 午夜精品一区二区国产 | 午夜天天操| 97狠狠干| 91av原创| 在线播放av网址 | 欧美精品xxx | 欧美日韩xxxxx | 九九热久久免费视频 | 日本三级中文字幕在线观看 | 婷婷爱五月天 | 国产成人精品午夜在线播放 | 欧美日韩69 | 91久久丝袜国产露脸动漫 | 国产视频黄 | 亚洲精品mv在线观看 | 国产韩国日本高清视频 | 国产精品欧美久久久久无广告 | 99久久99热这里只有精品 | 成人欧美一区二区三区黑人麻豆 | 久久论理| 日韩精品一区在线观看 | 91av成人 | 最近中文字幕在线播放 | 综合成人在线 | 国产日韩欧美在线 | 中文字幕色综合网 | 91免费黄视频 | 在线观看成人国产 | 久久免费视频2 | 欧美一区二区在线免费看 | 国产精品av免费 | 一本一本久久a久久精品综合小说 | 免费看片在线观看 | 色噜噜在线观看视频 | 一区二区三区手机在线观看 | 久久久久免费精品 | 免费亚洲黄色 | 亚洲午夜激情网 | 国产精品成人在线观看 | 91成人精品一区在线播放 | 在线视频成人 | 天天操天天摸天天射 | 久久社区视频 | www.亚洲激情.com | 午夜精品久久久99热福利 | 九九视频这里只有精品 | 欧美激情第十页 | 国产精品久久久久免费观看 | 午夜在线免费视频 | 天天干夜夜 | 亚洲一区美女视频在线观看免费 | 97综合网| 国产91aaa | 婷婷六月天综合 | 亚洲成aⅴ人在线观看 | 久久久 激情| 亚洲激情精品 | 国产三级久久久 | 成人av电影免费 | 国产精品久久久久婷婷二区次 | 国内综合精品午夜久久资源 | 亚洲欧美日本一区二区三区 | 9999激情 | 亚洲午夜久久久综合37日本 | 国产精品自产拍在线观看桃花 | 视频国产在线 | 国产精品久久三 | www久草| 成人在线视频一区 | 欧美成人xxxx | 国产在线一区二区三区播放 | 在线日本看片免费人成视久网 | 免费中午字幕无吗 | 91精品国产综合久久久久久久 | 免费看的黄色的网站 | 日本黄色大片免费 | 亚洲传媒在线 | 精品中文字幕在线观看 | 国产精品久久久久免费 | 97视频免费 | 精品久久久久国产 | 久草在线最新 | 亚洲午夜精品久久久久久久久 | 天堂v中文| a黄色一级 | 日韩视频欧美视频 | 97爱爱爱 | 五月天久久综合 | 日韩电影在线一区二区 | av免费网站观看 | 久久精品视频18 | 日本3级在线观看 | 久久99亚洲精品久久久久 | 久色网| 亚洲在线视频免费 | 免费看91的网站 | 国产精品毛片一区视频播不卡 | 日韩在线观 | 欧美男男tv网站 | 91精品国产乱码久久 | 日韩在线色视频 | 麻豆精品国产传媒 | 在线视频 成人 | 婷婷www | 国产理论在线 | 欧美一级视频免费看 | 黄网站www| 99久久精品一区二区成人 | 国产高清中文字幕 | 欧美久久久久久久久久久久久 | 91激情视频在线 | av成人免费网站 | 99在线热播精品免费 | 中文字幕高清在线 | 四虎成人精品永久免费av九九 | 久久国产精品系列 | 99视 | 波多野结衣视频一区 | 亚洲成av人片在线观看 | 日韩欧美在线国产 | 久久综合免费视频影院 | 欧美亚洲国产一卡 | www免费网站在线观看 | 久久精品99精品国产香蕉 | 久久久久久久久久久电影 | 久久爱www. | 免费看一级特黄a大片 | 99r在线观看 | 精品国产一区在线观看 | 亚洲国产日韩精品 | 天堂久久电影网 | 91亚洲夫妻 | 欧美人操人 | 日韩在线电影一区二区 | 亚洲精品动漫成人3d无尽在线 | 婷婷色婷婷 | 人人澡人人爽欧一区 | 91免费高清 | 欧美精品资源 | 成人黄色大片在线观看 | 99c视频高清免费观看 | 视频在线99 | 一区二区精品国产 | 欧美日韩一区二区三区免费视频 | av天天色| 欧美日韩免费在线观看视频 | 久久久综合色 | 国产精品久99 | 男女视频久久久 | 国产美女无遮挡永久免费 | 国产色视频网站2 | 日韩av免费在线看 | 成人影音在线 | 香蕉视频亚洲 | 成人精品视频久久久久 | 麻豆视频国产精品 | 蜜桃麻豆www久久囤产精品 | 五月婷在线播放 | 国产中文字幕在线看 | www.人人草| 丁香婷婷激情国产高清秒播 | 一区二区男女 | 中文字幕久久亚洲 | 中国一级特黄毛片大片久久 | av电影免费看 | 久久久久久久99精品免费观看 | 精品高清美女精品国产区 | 丝袜制服天堂 | 欧美一区在线观看视频 | 五月天综合色 | 久久精品国亚洲 | 欧美日韩国产综合一区二区 | 久草在线视频精品 | 亚洲砖区区免费 | 看片黄网站 | 美国av片在线观看 | 中文字幕在线观看第一区 | 免费看片亚洲 | 国产黄色在线网站 | 成人a v视频 | 国产毛片久久 | 色先锋av资源中文字幕 | 国产成人一二三 | 日韩中文三级 | 亚洲国产视频在线 | 国产69久久 | 国产成人av在线影院 | 操操操综合 | 国产中文字幕一区二区三区 | 成人h动漫精品一区二 | 欧美日韩在线免费观看 | 婷婷五情天综123 | 国产成人精品一区在线 | 人人玩人人添人人澡超碰 | 91免费网站在线观看 | 超碰公开在线 | 亚洲精品国产第一综合99久久 | 成人禁用看黄a在线 | 天天看天天干天天操 | 国产精品成 | 欧美地下肉体性派对 | 五月开心婷婷网 | 天天色视频| 国产高清不卡 | 日本爱爱免费 | 激情欧美丁香 | 精品美女视频 | 丁香五月网久久综合 | 美女久久久 | 久久草在线精品 | 精品久久一区 | 亚洲免费国产视频 | 国产999精品久久久影片官网 | 天堂在线一区二区 | 国产日韩精品视频 | a级国产毛片| 久草精品在线播放 | 99热这里有 | 99色资源| 欧美亚洲xxx| 一级一片免费视频 | 国内免费久久久久久久久久久 | 久久你懂的 | 日韩综合一区二区三区 | 99国产一区二区三精品乱码 | 久久综合九色综合欧美就去吻 | 天堂av观看 | 国产精品一区二区免费看 | 久草在线中文888 | 日韩黄色大片在线观看 | 成人国产一区 | 免费看片成人 | 日本女人在线观看 | 亚洲精品伦理在线 | 国产成人综合在线观看 | 国产大片免费久久 | 五月天亚洲精品 | 国产精品麻豆欧美日韩ww | 黄免费网站 | 在线中文字幕一区二区 | 久久成 | av在线不卡观看 | 97超碰色偷偷 | 国产视频一区在线 | 色资源网免费观看视频 | 亚洲精品国精品久久99热 | 五月婷婷狠狠 | 欧美日韩一区久久 | 人人艹视频 | 成年人电影毛片 | 中文字幕视频一区 | 狠狠干,狠狠操 | 国产破处精品 | 亚洲精品高清在线 | 亚洲免费观看视频 | 欧美一级电影免费观看 | 日韩videos | 国产精品国产亚洲精品看不卡 | 亚洲欧洲精品在线 | 天天操人人干 | 99久久视频| 久久久久女教师免费一区 | 久久久久视 | 在线看v片成人 | 久久夜av| 亚洲人成人在线 | 永久免费毛片在线观看 | sm免费xx网站 | 在线观看韩日电影免费 | 国产精品99久久久精品 | 欧美一级片在线播放 | 五月婷激情 | 97av影院| 日韩av免费在线电影 | 亚洲精品色婷婷 | 91自拍视频在线观看 | 青青河边草观看完整版高清 | 亚洲精品网页 | 国产成免费视频 | 国产精品白丝jk白祙 | 精品国产一区二区三区在线观看 | 欧美日韩在线精品 | 亚洲国产美女精品久久久久∴ | 日韩高清久久 | 97手机电影网 | 久久久在线免费观看 | 欧美黄色高清 | 婷婷国产v亚洲v欧美久久 | 欧美日韩不卡一区二区 | 国产精品嫩草影视久久久 | 99久久久精品 | 黄色精品国产 | 亚洲免费精品一区二区 | 国产色在线观看 | 亚洲人成免费 | 91九色性视频 | 久久久精品国产免费观看一区二区 | 国产精品免费大片视频 | 精品日韩视频 | 亚洲精品视频免费 | 激情婷婷在线观看 | 日韩免费久久 | 18性欧美xxxⅹ性满足 | 麻豆91网站| 久久99免费视频 | 狠狠操狠狠 | 久久99视频精品 | 99综合电影在线视频 | 四虎影视成人永久免费观看亚洲欧美 | 在线免费高清视频 | 亚洲成人免费在线观看 | 四虎在线视频免费观看 | 国产精品美女久久久免费 | 成人三级av | a级一a一级在线观看 | 免费在线黄色av | 欧美日韩在线观看不卡 | 91一区在线观看 | 国产手机视频在线 | 国产精品理论片在线播放 | 五月激情站| 日韩1级片 | 天天撸夜夜操 | 91av视频播放| 中文在线字幕观看电影 | 久久精品直播 | 国产高清av免费在线观看 | 天天综合导航 | 99草视频 | 久久免费看av | 国产免费激情久久 | 婷婷中文字幕 | 18久久久久 | 国产123区在线观看 国产精品麻豆91 | 色资源二区在线视频 | 久久精品精品电影网 | 国产午夜精品视频 | 免费看成年人 | 五月天婷婷免费视频 | 国产美女精品视频免费观看 | 亚洲精品高清视频 | 国产 日韩 欧美 中文 在线播放 | 亚洲国产成人高清精品 | 成人在线观看影院 | 国产精品久久久久一区二区三区共 | 国产91在线观看 | av福利在线导航 | 99热九九这里只有精品10 | 国产精品99久久久 | 国产欧美中文字幕 | 日韩在线观看你懂得 | 久久这里有精品 | 国产成人av一区二区三区在线观看 | 69av视频在线观看 | av免费高清观看 | 久久精品最新 | 中文字幕在线观看2018 | 久久一区二区三区超碰国产精品 | 麻豆系列在线观看 | 国产精品久久久久久久av大片 | 婷婷久久一区二区三区 | 日韩高清在线观看 | 丁香花在线观看视频在线 | 9色在线视频 | av不卡免费在线观看 | 国产福利免费看 | 成人免费在线观看电影 | 四虎成人精品永久免费av | 久久久久久黄 | 99精品久久只有精品 | 久草线 | 好看的国产精品视频 | 五月天开心 | 久久成人一区二区 | 在线看一级片 | 97精品国产97久久久久久免费 | 日本久久影视 | 91丨九色丨91啦蝌蚪老版 | 香蕉视频国产在线 | 久久成人在线 | 天天爱天天操 | 国产精品久久久免费看 | 九九导航 | 免费在线观看毛片网站 | 亚洲一区二区视频在线 | 久久精品视频网址 | 精品国产自在精品国产精野外直播 | 三级午夜片| 色婷婷亚洲婷婷 | 18岁免费看片 | 国产精品色婷婷视频 | 91大神dom调教在线观看 | 久久久精品国产一区二区 | 麻豆91视频 | 福利片免费看 | 婷婷丁香激情 | 亚洲成人999 | 97成人在线 | 亚洲综合成人婷婷小说 | 色在线国产| 国内精品亚洲 | 在线中文字幕播放 | 丁香五月亚洲综合在线 | 天天色棕合合合合合合 | 婷婷久久五月天 | 92精品国产成人观看免费 | 亚洲国产合集 | 国产亚洲精品久久久久久电影 | 国产精品国产三级国产aⅴ入口 | 成年人免费观看在线视频 | 人人艹视频 | 蜜桃传媒一区二区 | 国产精品6 | 国产中文字幕在线看 | 精品一区二区电影 | www.在线看片.com | 欧美亚洲久久 | 一区二区三区日韩视频在线观看 | 国产91在线观看 | 亚洲国内精品在线 | 日韩视频1区 | 久久精品亚洲精品国产欧美 | 国产精品男女啪啪 | 亚洲一级久久 | 成人在线免费观看网站 | 久久精品国产精品亚洲 | 欧美狠狠色 | 日韩色视频在线观看 | 免费看黄的 | 91免费的视频在线播放 | 高清av在线免费观看 | 亚洲精品视频在线 | 国产视频亚洲视频 | 在线观看免费一区 | 欧美在线观看视频一区二区三区 | 人人天天夜夜 | 国产精品 日韩 欧美 | 国产亚洲精品久久久久久无几年桃 | 91重口视频 | 免费色网站 | 福利av影院 | 久久精品欧美日韩精品 | 日韩精品一区二区三区第95 | 国产精品18久久久久久久久久久久 | 99免在线观看免费视频高清 | 精品91| 中文在线免费观看 | av福利免费 | 中文字幕的 | 日日干网址 | 国产精品孕妇 | 精品国产123 | 黄色三级网站在线观看 | 国产亚洲精品美女久久 | www.激情五月.com | 91视频首页 | 国产xxxx性hd极品 | 又黄又爽免费视频 | 免费福利小视频 | 69精品视频 | 500部大龄熟乱视频 欧美日本三级 | 亚洲精品黄色 | 一级特黄av | 国产精品久久久久久久久免费看 | 丰满少妇一级片 | 中文字幕在线免费看线人 | 在线观看一区 | 51久久夜色精品国产麻豆 | 91视频黄色 | 国产精品免费人成网站 | 中文字幕 91 | 天天射天天爱天天干 | 超碰在线公开 | a级一a一级在线观看 | 黄色三级免费片 | 99热精品国产 | 99国产一区二区三精品乱码 | 一区电影 | 91成人免费视频 | 六月丁香社区 | 中文字幕免费播放 | 久草免费在线 | 91精品夜夜| 天天操天天操天天操天天操天天操天天操 | 中文字幕在线影院 | 久久与婷婷 | 一区二区三区精品在线视频 | 久久天堂精品视频 | 国产美女黄网站免费 | 99视频免费观看 | 在线播放国产一区二区三区 | 日韩精品一区二区三区水蜜桃 | 福利网址在线观看 | 在线a视频免费观看 | 日韩一区二区免费在线观看 | 免费在线色电影 | 国产午夜剧场 | 国产人在线成免费视频 | 91在线免费观看网站 | 国产精品久久久久久久久久妇女 | 日韩电影一区二区三区在线观看 | 久久夜色网 | 国产a精品 | 国产 日韩 欧美 在线 | 久久综合色婷婷 | 奇米网网址 | 超碰国产97 | 成人精品在线 | 中文字幕资源网在线观看 | 国产婷婷一区二区 | 91av官网| 日韩欧美视频免费看 | 五月天亚洲精品 | 免费裸体视频网 | 免费一级黄色 | 正在播放国产一区二区 | 久久视频一区二区 | 夜色在线资源 | 久久免费毛片视频 | 中文字幕日韩国产 | 麻豆影音先锋 | 久久久福利视频 | 成年人精品 | 深夜免费福利视频 | 一级一级一片免费 | 日本在线免费看 | 国产精品免费久久久 | 视频一区二区免费 | 国产精品久久久久一区二区三区共 | 99精品国产成人一区二区 | 欧美一级特黄高清视频 | 婷婷色在线 | 免费观看一区二区 | 人人要人人澡人人爽人人dvd | 五月婷婷.com| 免费看国产黄色 | 欧美色图30p | 黄色成年网站 | 国产黄免费在线观看 | 国色综合| 久久久久久欧美二区电影网 | 婷婷色中文 | 久久毛片网站 | 91大神在线观看视频 | 日韩电影中文字幕在线观看 | 在线免费国产视频 | 国产日韩精品欧美 | 久久久久久蜜av免费网站 | 9999精品| 国产色视频一区 | 六月丁香在线视频 | 九九久久精品视频 | 香蕉97视频观看在线观看 | 欧美日韩三级在线观看 | 久久av在线播放 |