日韩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 工作流程的全部內容,希望文章能夠幫你解決所遇到的問題。

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

国产精品不卡在线播放 | 91av影视| 亚洲精品在线观看不卡 | 天天操比| 97狠狠操 | 在线91精品 | 四虎影视成人永久免费观看亚洲欧美 | 91视频在线国产 | 韩日电影在线免费看 | 精品国产乱码久久久久久浪潮 | 最新国产一区二区三区 | 欧美日韩视频 | 成人毛片一区 | 日韩理论电影在线观看 | 国产一级二级在线观看 | 国产一线天在线观看 | 色丁香久久| 日本久久片 | 三级av在线播放 | 欧美一级性生活片 | 99精品观看 | 五月婷婷久久综合 | 久久撸在线视频 | 久久成人高清视频 | 亚洲免费视频观看 | 久久免费的视频 | 久久久久久久久久久久久9999 | 欧美日韩精品二区第二页 | 免费av电影网站 | 成人免费亚洲 | 欧美男同网站 | 91视频 - 114av| 国产色女人 | 五月天精品视频 | 黄色一级免费电影 | 少妇精69xxtheporn | 最新日本中文字幕 | 亚洲欧美日韩精品一区二区 | 手机在线看a | 欧美一级电影免费观看 | 久久99久久精品国产 | 国产毛片aaa| 亚洲最大的av网站 | 色99网| 日日干网址| 日本久久高清视频 | 精品999在线观看 | a级片在线播放 | 永久黄网站色视频免费观看w | 中文字幕在线观看播放 | 久久一久久 | 国产91精品久久久久久 | 中文字幕在线视频一区二区 | 日本中文字幕观看 | 久久免费电影网 | 久久呀| 欧美激情精品久久久久久 | 成人av教育| 国产精品九色 | 午夜在线观看一区 | 久久久久久久久久久久久久免费看 | 欧美亚洲免费在线一区 | 狠狠狠色丁香婷婷综合久久88 | 狠狠躁日日躁狂躁夜夜躁av | 99久久久国产精品美女 | 免费人成在线观看 | 国产一区二区综合 | 日韩乱理 | 热re99久久精品国产99热 | 欧美午夜性 | 国产精品精品国产色婷婷 | 在线观看黄色小视频 | 国产精品入口久久 | 日韩免费电影网 | 午夜骚影 | 中文字幕在线免费97 | 日韩av视屏在线观看 | 色播五月激情五月 | 高清av中文字幕 | 欧美精品久久久久久久久免 | 久久黄色片 | 一本到视频在线观看 | 欧美激情一区不卡 | 欧美激情视频三区 | 99热.com| 黄色福利视频网站 | 欧美日韩久久不卡 | 国产视频一区二区在线播放 | 91亚洲精品久久久久图片蜜桃 | 视频国产区 | 天堂网一区二区 | 亚洲一二视频 | 精品一区二区久久久久久久网站 | 中文字幕 国产 一区 | av日韩精品 | 日韩欧美精品在线 | 天堂资源在线观看视频 | www一起操 | 伊人射| 日韩欧美亚州 | 亚洲 欧美 变态 国产 另类 | 久久成人18免费网站 | 黄色1级毛片 | 久久精品电影院 | 人人狠狠综合久久亚洲婷 | 免费福利在线视频 | 色.www| 超碰97中文| 日韩色爱 | 色婷婷激情网 | 成人av免费在线播放 | 色黄久久久久久 | 蜜臀av网站| 自拍超碰在线 | 黄色性av | 精品久久久久国产 | 丁香午夜| 99热官网 | 成人97视频 | 久久美女高清视频 | 99色视频在线 | 精品99免费视频 | 中文字幕资源站 | 欧美性免费 | 婷婷在线色| 精品久久中文 | 婷婷在线免费观看 | 午夜国产一区二区 | 久久精品一区二区三区四区 | 激情av资源 | 国产黄色资源 | 国内一级片在线观看 | 在线观看av网站 | 久久综合福利 | 亚洲手机天堂 | 免费色视频网址 | 日韩经典一区二区三区 | 天天操天天射天天舔 | 免费成人黄色av | www.在线观看av| 欧美影院久久 | 国产婷婷一区二区 | 欧美另类色图 | 黄色三级网站 | 精品日韩在线一区 | 欧美精品久久久久久 | 精品九九九 | 开心激情综合网 | 亚洲天堂精品视频在线观看 | 国产精品99久久久久久宅男 | 九九视频这里只有精品 | 免费福利在线播放 | 狠狠操操网| 色五月色开心色婷婷色丁香 | 国产91影视 | 欧美视频99 | 天天插天天爱 | 日韩黄色免费电影 | 久久人人爽人人爽人人片 | 日韩免费三区 | www.黄色片.com | 日日夜夜国产 | 国产在线日本 | av中文字幕免费在线观看 | 久草在线视频看看 | 人人爽人人爽人人爽学生一级 | 欧美三级在线播放 | 激情五月婷婷激情 | 天天干天天干天天操 | www.久热| 国产成人亚洲在线观看 | 久久激情五月激情 | 亚洲综合视频网 | 综合色站| 国产精品色 | 激情视频国产 | 成人免费大片黄在线播放 | 日韩精品一区在线播放 | 亚洲精品色婷婷 | 久久国产精品一国产精品 | 在线看片成人 | 欧美大片www | 中国精品少妇 | 国产一级视屏 | 丁香 久久 综合 | 久久久鲁 | 久久永久视频 | 国产精品精品久久久久久 | 天天干中文字幕 | 久草观看 | 国产成人99av超碰超爽 | 日韩欧美一区二区三区黑寡妇 | 夜添久久精品亚洲国产精品 | 中文字幕电影在线 | 丁香花在线视频观看免费 | 日本夜夜草视频网站 | www.com黄| 亚洲视屏在线播放 | 91日本在线播放 | 91成人网在线播放 | 成人91免费视频 | 91九色蝌蚪视频网站 | 亚洲一区二区三区四区精品 | 久久福利精品 | 啪嗒啪嗒免费观看完整版 | 99热在 | 久久久久久久久久久影院 | 色搞搞 | 国产成人福利在线观看 | 久久人人爽人人 | 国产免费资源 | 亚洲天堂网在线视频 | 亚洲激情校园春色 | 久久免费在线视频 | 91大片网站| 免费国产在线精品 | 99免费在线播放99久久免费 | 日韩激情在线 | 亚洲国产无 | 热久久电影 | 中文字幕 影院 | av一级在线观看 | 99久久久国产精品免费99 | 99精品免费久久久久久久久 | 91精品色 | 免费av视屏 | 久久久久久久久久免费 | www.久久免费视频 | 91热在线| 国产精品不卡视频 | 国产精品乱码在线 | 日本精品免费看 | 国产亚洲综合性久久久影院 | 亚洲精品国偷拍自产在线观看蜜桃 | 久久免费看av | 视频二区在线视频 | 亚洲另类视频在线观看 | 久久久精品国产一区二区三区 | 日韩精品中文字幕有码 | 日韩欧美国产激情在线播放 | 中文字幕日韩电影 | 日韩av影视在线观看 | 97精品在线观看 | 91在线中文| 欧美精品被 | 国产精品国产自产拍高清av | 国产精品久久久久久超碰 | a天堂免费| 精品中文字幕在线观看 | 黄色成人毛片 | 中文字幕文字幕一区二区 | 日韩视频一区二区三区 | 一区三区在线欧 | 亚州国产精品 | 99热精品在线 | 黄p在线播放 | 天天干夜夜擦 | 精品国产一区二区三区av性色 | 国产精品18久久久久久久久久久久 | 国产精品毛片一区视频 | 久草视频在线免费播放 | 色婷婷免费视频 | av成人黄色 | 亚洲国产精品日韩 | 国产区精品在线 | 久久亚洲国产精品 | 免费在线一区二区三区 | 天天做天天爱夜夜爽 | 超级碰碰碰碰 | 西西4444www大胆视频 | 日韩三级免费观看 | 亚洲成人资源在线观看 | 懂色av懂色av粉嫩av分享吧 | 国产精品久久久久久吹潮天美传媒 | 亚洲国产中文字幕在线视频综合 | 亚洲精品日韩在线观看 | 亚洲最快最全在线视频 | 免费看黄在线 | 国产精品福利视频 | 国产精品专区h在线观看 | 在线观看免费av网站 | 国产精品 欧美 日韩 | 精品一区二区三区久久久 | 99久久精品国产一区二区成人 | 久久不射电影院 | 五月婷婷激情 | 国产成人精品一区二区三区免费 | 黄色影院在线免费观看 | 久草五月 | 婷婷丁香激情五月 | 97视频在线播放 | 国内成人精品视频 | 99热手机在线观看 | 国产日韩在线观看一区 | 99久久夜色精品国产亚洲96 | 激情视频91 | 免费人人干| 九九久久久久99精品 | 亚洲国产精品va在线看黑人动漫 | 天天综合中文 | 欧美精品久久人人躁人人爽 | 久久成年人网站 | 亚洲精品视频第一页 | 色窝资源 | 国产精品mv | 爱av在线网| 欧美日韩国产一区 | 精品亚洲欧美无人区乱码 | 欧美大香线蕉线伊人久久 | 久久国产精品免费一区 | 午夜美女视频 | 国产精品自在线 | 欧美日韩精品在线免费观看 | 91精品久久久久久久久 | 日韩精品一区二区三区不卡 | 国产高清久久 | 免费一级片视频 | 国产精品视频免费观看 | 成 人 免费 黄 色 视频 | 久久综合色婷婷 | 亚洲精品ww | 久久国产一区二区 | 久久黄色精品视频 | 国产精品欧美久久久久三级 | 色婷婷综合久久久中文字幕 | 日韩免费小视频 | av国产在线观看 | 欧美9999 | 五月婷婷一区 | 欧美日韩伦理一区 | av中文字幕网站 | 国产美腿白丝袜足在线av | 日韩欧美在线一区二区 | 天天色天天综合 | 精品视频免费久久久看 | 色婷婷av国产精品 | 911久久 | 东方av免费在线观看 | 日韩有码中文字幕在线 | 中文字幕免费高清在线 | 在线视频精品 | 在线免费色视频 | 国产一卡二卡在线 | 96香蕉视频| 在线免费高清一区二区三区 | 久久综合天天 | 91在线看免费 | 欧美va电影| 国产精品电影一区二区 | 国产精品美女久久久久久久 | 久久黄色网页 | 97视频在线免费 | 国产成人免费观看 | 日日干夜夜草 | 日韩高清一区 | 蜜臀久久99精品久久久无需会员 | 国产精品免费在线播放 | 99精品欧美一区二区蜜桃免费 | 国产精品久久久久久吹潮天美传媒 | 麻豆系列在线观看 | av 一区二区三区四区 | 夜夜爽88888免费视频4848 | 中国精品一区二区 | 久草免费在线观看 | 西西4444www大胆无视频 | 国产精品久久久久久久久久免费 | 人人看人人| 欧美成人tv| 六月丁香婷婷网 | 成人免费在线播放 | 欧美一区二区三区四区夜夜大片 | 手机成人在线 | 美女国产 | 天天操天天色天天射 | 91色吧| av成人在线播放 | 狠狠躁日日躁狂躁夜夜躁 | 免费精品在线观看 | 亚洲欧美在线综合 | 久久久国产精品免费 | 成人在线网站观看 | 五月天亚洲综合 | 日韩二区在线观看 | 日日摸日日添日日躁av | 亚洲国产天堂av | av丝袜在线 | 在线中文字幕网站 | 亚洲精品久久久久久久蜜桃 | 国产在线理论片 | 欧美视频国产视频 | 91精品在线视频 | 麻豆一精品传二传媒短视频 | 911久久 | 丁香六月国产 | 国产精品99久久久久久久久 | 99久久精品久久久久久动态片 | 一级黄色电影网站 | 不卡的av中文字幕 | 国产成人一级 | 国产精品久久久久久久毛片 | 亚洲国产精品久久 | 日韩午夜大片 | 在线免费观看国产黄色 | 国产资源精品在线观看 | 日韩欧美专区 | 国产vs久久 | 四虎成人免费影院 | 欧美日在线 | 日本深夜福利视频 | 日韩一区二区三区观看 | 天天操夜夜摸 | 丝袜美腿av | 香蕉视频日本 | 91成人精品观看 | 97超级碰碰碰碰久久久久 | 91成人精品一区在线播放69 | 丁香在线视频 | 国产成人免费在线观看 | 欧美日韩不卡一区 | 免费看日韩片 | 91污在线观看 | 久久夜av | 日韩一级精品 | 99精品久久久久 | 在线观看成人一级片 | 国产专区视频在线观看 | 成片视频免费观看 | 亚洲色图 校园春色 | 日韩精品高清视频 | 中文字幕在线观看第三页 | 日韩素人在线观看 | 日av免费 | 亚洲精品久久久久中文字幕二区 | av在线一| 久草在线视频看看 | 婷婷丁香五 | av在线看网站 | 不卡的一区二区三区 | 日韩精品免费在线观看视频 | 91九色最新 | 欧美精品亚洲精品日韩精品 | 亚洲精品美女在线观看 | 精品视频免费 | 日日夜夜操操 | 91视频在线免费看 | 亚洲国产成人在线观看 | 国产一区免费视频 | 国模吧一区 | 国产自偷自拍 | 国际精品久久 | 欧美巨乳波霸 | 91av福利视频 | 欧美日韩国产精品一区 | 男女靠逼app | a级国产乱理伦片在线观看 亚洲3级 | 日韩中文字幕免费看 | 国产片免费在线观看视频 | av免费播放| 国产免费xvideos视频入口 | 久草在线最新免费 | 天天操夜夜做 | 日韩黄色大片在线观看 | 狠狠久久 | 美女黄色网在线播放 | 精品久久久久一区二区国产 | 国产三级国产精品国产专区50 | 97人人艹| 手机成人免费视频 | 91免费观看 | 97成人在线观看视频 | 日韩免费一区二区三区 | 久久久久久久99 | 在线午夜电影神马影院 | 精品国产观看 | 久久激情五月丁香伊人 | 中文字幕网站视频在线 | 91精品第一页 | 久久九九免费 | 波多野结衣视频一区 | 视频在线观看一区 | 日韩h在线观看 | 中文字幕一区三区 | 在线免费观看视频一区 | 国产91在线观 | 久久久精品综合 | 亚洲闷骚少妇在线观看网站 | 欧美成人一区二区 | 欧美日韩精品在线观看视频 | 日日天天干| 国产亚洲在线视频 | 成人av电影在线观看 | 国产打女人屁股调教97 | 美女福利视频 | 波多野结衣在线观看视频 | 亚洲一区二区视频在线播放 | 国产精品乱码高清在线看 | 国产一区二区免费看 | 国产伦精品一区二区三区… | 江苏妇搡bbbb搡bbbb | 色五月色开心色婷婷色丁香 | 五月婷婷综合激情 | 日韩在线网| 日韩欧美在线观看一区二区 | 六月婷操| 日韩精品中文字幕在线不卡尤物 | 欧美夫妻性生活电影 | 日韩在线观看网址 | 探花视频网站 | 狠狠网亚洲精品 | 国产精品一区欧美 | 涩涩资源网 | 精品一区电影 | 丝袜美女视频网站 | av亚洲产国偷v产偷v自拍小说 | 国产成人精品一区二区三区 | 国产成人综合精品 | 久久婷婷一区 | 亚洲电影院 | 24小时日本在线www免费的 | 国产午夜精品久久久久久久久久 | 伊人狠狠色 | 国产成人黄色片 | 中文字幕一区二区三 | 五月婷婷中文网 | 久久综合九色综合欧美就去吻 | 亚洲精品福利在线观看 | 在线综合色 | 超碰99人人 | 国产视频日韩视频欧美视频 | 日韩精品久久中文字幕 | 五月婷婷开心中文字幕 | 九九热免费精品视频 | 手机av资源| 久草视频国产 | 久久99精品视频 | 日本乱视频 | 激情动态 | 在线观看中文字幕视频 | 日日麻批40分钟视频免费观看 | 亚洲在线不卡 | a级国产片 | 人人插人人费 | 日韩免费观看一区二区三区 | 精品久久久免费视频 | 亚洲精品乱码久久久久久9色 | 最近日本韩国中文字幕 | 免费视频91 | 久久久久女人精品毛片九一 | 亚洲涩涩网 | 久久免费国产精品 | 国产主播大尺度精品福利免费 | 精品美女国产在线 | 国产午夜麻豆影院在线观看 | 91精品秘密在线观看 | av中文字幕在线免费观看 | 久操视频在线免费看 | av片无限看 | 99视频这里有精品 | 首页中文字幕 | 五月天激情电影 | 一级黄色免费网站 | 久久亚洲专区 | 99av国产精品欲麻豆 | 欧美伦理一区二区三区 | av免费看电影 | 亚洲精品在线资源 | 国产999精品视频 | 天天艹天天爽 | 久99久精品视频免费观看 | 久久爱影视i | 蜜臀av一区二区 | 综合国产在线观看 | www.久久com| 一区二区三区 中文字幕 | 在线看国产视频 | 国产 日韩 欧美 在线 | 丁香六月色 | 伊人国产视频 | 国产视频在线观看一区 | 91大神免费在线观看 | 国产精品二区三区 | 久久久人人人 | 狠狠搞,com | 亚洲第一色 | 国产午夜免费视频 | 正在播放一区 | 97香蕉久久超级碰碰高清版 | .国产精品成人自产拍在线观看6 | 国产在线传媒 | 久久综合久久综合久久综合 | 亚洲国产日韩在线 | 免费看久久久 | 丁香视频全集免费观看 | 国产精品久久网站 | 国产精品一区二区av影院萌芽 | 亚洲精品三级 | 91完整版观看 | 国产91精品一区二区麻豆亚洲 | 麻花豆传媒一二三产区 | 8x8x在线观看视频 | 九色porny真实丨国产18 | 国内丰满少妇猛烈精品播放 | 3d黄动漫免费看 | 在线观看视频一区二区三区 | 日韩美女高潮 | 国产欧美综合在线观看 | 天天干天天射天天插 | 免费观看性生交 | 久久久久久草 | 九九九热精品 | 丁香5月婷婷久久 | 伊人五月天综合 | 久久伦理 | 久久久亚洲成人 | 欧美精品做受xxx性少妇 | 天天要夜夜操 | 麻豆久久久 | 久一在线| 夜色成人网 | 精品免费国产一区二区三区四区 | av在线之家电影网站 | 伊人婷婷 | 久久久久免费看 | 在线最新av | 久久综合福利 | 九草视频在线 | 91精品国产99久久久久久久 | 国产最顶级的黄色片在线免费观看 | 日韩av影片在线观看 | www成人精品| 国产精品成人一区二区 | 欧美高清视频不卡网 | 99精品久久只有精品 | 久久国产精品一二三区 | 久久免费视频在线观看6 | 精品在线免费观看 | 天天在线视频色 | 日韩在线短视频 | 久久99久久99精品免费看小说 | 99免费在线播放99久久免费 | 色婷婷激情网 | 久久精品欧美日韩精品 | 欧美精品亚洲精品日韩精品 | 国内精品国产三级国产aⅴ久 | 天天色天天射天天干 | 国产自在线观看 | 深夜免费小视频 | 日韩大片免费观看 | 欧美aaa级片 | 国产人成一区二区三区影院 | av免费电影网站 | 国产视频97 | 在线中文字幕视频 | 中文亚洲欧美日韩 | 色久综合 | 黄网站色视频免费观看 | 久久久久女人精品毛片 | 国产精品国产三级国产 | 2019精品手机国产品在线 | 久久综合久久久久88 | 亚洲一区二区天堂 | 久久婷婷一区 | 久久视频精品在线观看 | 六月丁香色婷婷 | 一区二区三区www | 成人在线播放网站 | 国内三级在线观看 | 波多野结衣视频在线 | 少妇搡bbb| 国产伦精品一区二区三区照片91 | 黄色软件大全网站 | 黄色1级大片| 狠狠操在线 | 久久女教师 | 国产精品va在线观看入 | 91免费在线| 色99之美女主播在线视频 | 国产乱对白刺激视频在线观看女王 | 99久久精品国产欧美主题曲 | 中文字幕一区二区在线观看 | 久久国产精品99久久久久久老狼 | 九色在线 | 超碰在线最新网址 | 欧美一二三视频 | 亚洲激情一区二区三区 | 天天激情综合 | 午夜精品久久久久久久爽 | 国产精品久久久久久久久蜜臀 | 午夜av激情 | 久久久免费播放 | 国产91大片| 久久99久久精品国产 | 久久 地址 | 在线亚洲欧美日韩 | 日韩在线免费电影 | 久久久久国产精品午夜一区 | 99久久婷婷国产一区二区三区 | 天天艹天天 | 国产91免费观看 | av色一区| 免费视频色 | 四虎成人网 | 国产精品免费视频一区二区 | 日韩国产高清在线 | 国产精品久久久久久久久免费看 | 欧美精品你懂的 | 亚洲精品动漫在线 | 色婷婷综合视频在线观看 | 五月婷在线视频 | www成人精品| 奇米影视777四色米奇影院 | 国产99久久精品 | 久久人人爽爽 | 久久免费99精品久久久久久 | 97综合网| 亚洲国产美女精品久久久久∴ | 国产日韩欧美精品在线观看 | 天天色天天操天天爽 | 国产精品久免费的黄网站 | 亚洲欧美视频在线观看 | 96av在线视频 | 国产精品国产三级国产专区53 | 在线亚洲天堂网 | 久久久久国产精品免费免费搜索 | 91人人视频在线观看 | 正在播放亚洲精品 | 99热这里有精品 | 日韩理论片在线观看 | 久久黄色片子 | 日韩手机在线观看 | 热热热热热色 | 婷婷亚洲五月 | 精品久久久久久久久中文字幕 | 中文字幕资源站 | 超碰在线人人97 | 午夜精品成人一区二区三区 | 久久久久久久久网站 | 免费黄色av| av久久在线| 亚洲精品9 | 91成人网在线 | 成人天堂网 | 国产成人免费在线 | 中文在线字幕免 | 综合五月| 97超碰资源站 | 精品av在线播放 | 99久久精品国产一区二区三区 | 精品少妇一区二区三区在线 | 精品国产欧美一区二区 | 成年人免费观看在线视频 | 精品国产免费看 | 国产中文字幕久久 | 亚洲精品视频在线播放 | 97视频免费播放 | 久久婷五月 | 欧美久久久久久久久久久久 | 一区 在线 影院 | 综合激情网... | 国产精品3 | 天天天干天天射天天天操 | 国产在线精品福利 | 久久久久综合精品福利啪啪 | 精品国产乱码久久久久 | 久久久久成人精品亚洲国产 | 中文字幕丝袜美腿 | 精品久久久久久久久久久院品网 | 亚洲精品国精品久久99热一 | 久久看视频 | 久久精品视频国产 | 波多野结衣一区二区三区中文字幕 | 99热在线免费观看 | 91精品国产亚洲 | 国产专区在线播放 | 亚洲欧美经典 | 不卡的av电影在线观看 | 亚洲精品裸体 | 五月综合色 | 久久99国产精品久久99 | а天堂中文最新一区二区三区 | 奇米影视四色8888 | 很黄很污的视频网站 | 一区av在线播放 | 亚洲日本在线视频观看 | 亚洲电影久久 | 日韩毛片精品 | 日韩av在线免费看 | 精品国产99国产精品 | 91污污视频在线观看 | 免费av的网站 | a成人在线| 亚洲 中文 在线 精品 | 天天操天天弄 | 久久久99精品免费观看 | 国内偷拍精品视频 | 国产免费成人av | 成人av电影网址 | 精品99在线 | 国产精品久久久久久五月尺 | 成人免费观看a | 国产精彩在线视频 | 久久综合久久伊人 | 久久综合久久综合这里只有精品 | 伊人夜夜| 免费毛片一区二区三区久久久 | 日韩欧美在线观看一区 | 久99久视频 | 日韩在线观看 | 欧美在线视频免费 | 日韩在线中文字幕视频 | 日韩欧美区 | 欧美一级片免费 | 日韩欧美在线免费 | 91资源在线免费观看 | 中文字幕亚洲精品在线观看 | 日韩欧美在线不卡 | 人人干人人草 | 精品国产电影一区二区 | 人人草在线视频 | 亚洲国产免费看 | a在线免费观看视频 | 日韩精品欧美视频 | 91精品国自产在线观看 | 一级黄色片在线免费看 | 欧美激情精品久久久 | 91成人精品一区在线播放69 | 国产一级免费片 | 欧美一级黄色网 | 亚洲国产剧情 | 欧美成人xxx | 亚洲 欧美 精品 | www色| 9999免费视频 | 久久久久久国产精品亚洲78 | 毛片随便看 | 亚州精品在线视频 | 免费黄色av | 波多野结衣精品 | 中文av资源站 | 欧美日比视频 | 99九九免费视频 | 欧美精品视 | 菠萝菠萝蜜在线播放 | 欧美日韩国产综合网 | 国产99re| 午夜免费福利视频 | 夜添久久精品亚洲国产精品 | 亚洲成人频道 | www.天天综合 | 日韩精品第1页 | 欧美日产一区 | 国产日韩欧美在线影视 | 国内久久久| 久久免费视频6 | 日本久久精品视频 | 成人a在线| 久久精品国产亚洲a | 99久久婷婷国产精品综合 | 国产69久久| 久久久久久久网 | 亚洲精品国产综合99久久夜夜嗨 | 亚洲全部视频 | av 一区 二区 久久 | 九九热精品视频在线播放 | 亚洲免费在线看 | 深爱开心激情 | 黄色一级大片在线观看 | 婷婷久久一区 | 天天干国产 | 国产午夜精品av一区二区 | 欧洲一区二区三区精品 | 69av国产| 国产精品福利无圣光在线一区 | 国产九九九视频 | 99热精品久久| 国产老太婆免费交性大片 | 久久精品一二三区白丝高潮 | 日韩,中文字幕 | 欧美精品v国产精品v日韩精品 | 色偷偷中文字幕 | 黄色在线视频网址 | 日韩两性视频 | 99视频黄 | 日本成人黄色片 | 麻豆免费在线视频 | 激情网站网址 | 亚洲精品视频久久 | 色婷婷av国产精品 | 欧美黑人xxxx猛性大交 | 国产在线观看免 | 色悠悠久久综合 | 精品国产成人在线 | 狠狠的日| av 一区二区三区四区 | 亚洲成人av在线 | 中文字幕免费高清在线 | 久久精品日产第一区二区三区乱码 | 香蕉日日 | 在线国产精品一区 | 欧美亚洲一区二区在线 | 韩国精品在线观看 | 久久资源总站 | 欧美三级高清 | 日韩中文字幕亚洲一区二区va在线 | 成人app在线免费观看 | 国产精品美女毛片真酒店 | 看国产黄色片 | 成人黄色电影视频 | 一区二区三区免费在线观看视频 | 久久人人爽人人爽人人 | 香蕉久久久久久久 | 国产成视频在线观看 | 日本黄色免费在线观看 | 伊人五月天.com | 中文字幕乱码视频 | 色综合久久久久久中文网 | 麻豆传媒视频观看 | 免费在线观看国产精品 | 亚洲一区二区视频 | 成人黄大片| 97视频免费在线看 | 国产手机视频精品 | 午夜精品成人一区二区三区 | 天天操天天摸天天干 | 国产精品久久视频 | 成人小视频在线观看免费 | 女人高潮一级片 | 欧美专区日韩专区 | 中文字幕免费高 | 日日夜夜精品免费 | 成人久久精品视频 | 韩国av免费在线观看 | 久久午夜精品 | 国产成a人亚洲精v品在线观看 | 97热在线观看 | 伊甸园永久入口www 99热 精品在线 | 在线播放视频一区 | 免费在线精品视频 | 欧美日在线 | 国产精品精品国产色婷婷 | 亚洲精品资源 | 国产精品久久久久高潮 | 天堂在线v | 久久艹在线 | 激情五月六月婷婷 | 国产精品99久久久久久宅男 | 在线91精品 | 国产精品观看在线亚洲人成网 | ,久久福利影视 | 久久久久久久久久久久久久av | 黄色毛片视频 | 中文字幕乱视频 | 亚洲激情精品 | 欧美精品一区在线发布 | 精品天堂av | 久久国产午夜精品理论片最新版本 | 丁香婷婷色 | 国产在线一区观看 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 高潮久久久久久 | 亚洲国产精品推荐 | 国产精品亚 | 2021国产精品 | 九九九九精品 | 国内精品久久久久久久久久久 | 韩国一区二区三区视频 | 日韩理论片在线 | 欧美极度另类性三渗透 | 我要色综合天天 | 中文字幕在线中文 | 91中文字幕在线播放 | 99亚洲国产精品 | 中文字幕精品一区久久久久 | 91精品国产99久久久久久久 | 国产精品久久99综合免费观看尤物 | 久久免费精彩视频 | a√天堂资源 | 麻豆免费观看视频 | 国产精品18p| 欧美精品在线一区二区 | 在线看av的网址 | 国产精品麻豆视频 | 精品一区 在线 | www五月| 韩国一区在线 | 国产精品午夜在线观看 | 欧美激情第八页 | 黄网站免费看 | 久久精品99精品国产香蕉 | 久久99久久99精品免观看软件 | 久久婷婷国产色一区二区三区 | 精品99久久| 四虎影视8848dvd| 国产亚洲精品v | 少妇做爰k8经典 | 亚洲午夜精品在线观看 | 精品夜夜嗨av一区二区三区 | 成年人免费在线 |