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

歡迎訪問 生活随笔!

生活随笔

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

Android

android 队列执行动画,Android 重学系列 渲染图层-图元缓冲队列初始化

發布時間:2025/3/15 Android 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 队列执行动画,Android 重学系列 渲染图层-图元缓冲队列初始化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

經過上一篇文章,對開機啟動動畫的流程梳理,引出了實際上在開機啟動動畫中,并沒有Activity,而是通過OpenGL es進行渲染,最后通過某種方式,把數據交給Android渲染系統。

本文,先來探索在調用OpenGL es進行渲染的前期準備。

正文

讓我們回憶一下,上一篇開機動畫OpenGL es 使用步驟,大致分為如下幾個:

1.SurfaceComposerClient::getBuiltInDisplay 從SF中查詢可用的物理屏幕

2.SurfaceComposerClient::getDisplayInfo 從SF中獲取屏幕的詳細信息

3.session()->createSurface 通過Client創建繪制平面控制中心

4.t.setLayer(control, 0x40000000) 設置當前layer的層級

5.control->getSurface 獲取真正的繪制平面對象

6.eglGetDisplay 獲取opengl es的默認主屏幕,加載OpenGL es

7.eglInitialize 初始化屏幕對象和著色器緩存

8.eglChooseConfig 自動篩選出最合適的配置

9.eglCreateWindowSurface 從Surface中創建一個opengl es的surface

10.eglCreateContext 創建當前opengl es 的上下文

11.eglQuerySurface 查找當前環境的寬高屬性

12.eglMakeCurrent 把上下文Context,屏幕display還有渲染面surface,線程關聯起來。

13.調用OpenGL es本身特性,繪制頂點,紋理等。

eglSwapBuffers 交換繪制好的緩沖區

15.銷毀資源

我們就沿著這個邏輯看看在這個過程中Android的渲染系統在其中擔任了什么角色。

SurfaceComposerClient::getBuiltInDisplay

sp SurfaceComposerClient::getBuiltInDisplay(int32_t id) {

return ComposerService::getComposerService()->getBuiltInDisplay(id);

}

ComposerService本質上是ISurfaceComposer 一個BpBinder對象,對應著BnBinder對象是SF,也就到了SF的getBuiltInDisplay。

SF getBuiltInDisplay

sp SurfaceFlinger::getBuiltInDisplay(int32_t id) {

if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {

return nullptr;

}

return mBuiltinDisplays[id];

}

還記得我初始化第一篇聊過這個數據結構嗎?mBuiltinDisplays 將會持有根據每一個displayID也同時displayType持有一個BBinder作為核心。然而此時的BBinder只是一個通信基礎,還沒有任何處理命令的邏輯。我們需要看下面那個方法做了什么?

SurfaceComposerClient::getDisplayInfo

status_t SurfaceComposerClient::getDisplayConfigs(

const sp& display, Vector* configs)

{

return ComposerService::getComposerService()->getDisplayConfigs(display, configs);

}

int SurfaceComposerClient::getActiveConfig(const sp& display) {

return ComposerService::getComposerService()->getActiveConfig(display);

}

status_t SurfaceComposerClient::getDisplayInfo(const sp& display,

DisplayInfo* info) {

Vector configs;

status_t result = getDisplayConfigs(display, &configs);

if (result != NO_ERROR) {

return result;

}

int activeId = getActiveConfig(display);

if (activeId < 0) {

ALOGE("No active configuration found");

return NAME_NOT_FOUND;

}

*info = configs[static_cast(activeId)];

return NO_ERROR;

}

該方法通過了兩次Binder通信進行屏幕數據的獲取,第一次getDisplayConfigs,如果成功則getDisplayConfigs獲取第二次。

SF getDisplayConfigs

status_t SurfaceFlinger::getDisplayConfigs(const sp& display,

Vector* configs) {

...

int32_t type = NAME_NOT_FOUND;

for (int i=0 ; i<:num_builtin_display_types i>

if (display == mBuiltinDisplays[i]) {

type = i;

break;

}

}

if (type < 0) {

return type;

}

// TODO: Not sure if display density should handled by SF any longer

class Density {

static int getDensityFromProperty(char const* propName) {

char property[PROPERTY_VALUE_MAX];

int density = 0;

if (property_get(propName, property, nullptr) > 0) {

density = atoi(property);

}

return density;

}

public:

static int getEmuDensity() {

return getDensityFromProperty("qemu.sf.lcd_density"); }

static int getBuildDensity() {

return getDensityFromProperty("ro.sf.lcd_density"); }

};

configs->clear();

ConditionalLock _l(mStateLock,

std::this_thread::get_id() != mMainThreadId);

for (const auto& hwConfig : getHwComposer().getConfigs(type)) {

DisplayInfo info = DisplayInfo();

float xdpi = hwConfig->getDpiX();

float ydpi = hwConfig->getDpiY();

//默認主屏幕的獲取DPI的法則

if (type == DisplayDevice::DISPLAY_PRIMARY) {

// The density of the device is provided by a build property

float density = Density::getBuildDensity() / 160.0f;

if (density == 0) {

// the build doesn't provide a density -- this is wrong!

// use xdpi instead

ALOGE("ro.sf.lcd_density must be defined as a build property");

density = xdpi / 160.0f;

}

if (Density::getEmuDensity()) {

xdpi = ydpi = density = Density::getEmuDensity();

density /= 160.0f;

}

info.density = density;

// TODO: this needs to go away (currently needed only by webkit)

sp hw(getDefaultDisplayDeviceLocked());

info.orientation = hw ? hw->getOrientation() : 0;

} else {

...

}

info.w = hwConfig->getWidth();

info.h = hwConfig->getHeight();

info.xdpi = xdpi;

info.ydpi = ydpi;

info.fps = 1e9 / hwConfig->getVsyncPeriod();

info.appVsyncOffset = vsyncPhaseOffsetNs;

info.presentationDeadline = hwConfig->getVsyncPeriod() -

sfVsyncPhaseOffsetNs + 1000000;

info.secure = true;

if (type == DisplayDevice::DISPLAY_PRIMARY &&

mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {

std::swap(info.w, info.h);

}

configs->push_back(info);

}

return NO_ERROR;

}

能看到這里BBinder實際并不是作為通信使用,而是作為對象標示。用來篩選出對應的屏幕的type是什么。

核心是下面這一段,先從HWComposer中獲取該id的屏幕的信息,并且保存在DisplayInfo。我們關注Density,也就是dpi是怎么計算的。

解釋一下dpi是什么,dpi是對角線每一個英寸下有多少像素。

計算就很簡單就是一個普通勾股定理即可。

其實這個數值是由ro.sf.lcd_density和qemu.sf.lcd_density屬性決定的。當然如果ro.sf.lcd_density沒有數值,則density則是由HWC的getConfigs的xdpi/160決定。最后找找qemu.sf.lcd_density,如果有數值,則xdpi,ydpi全部都是它,但是density則是qemu.sf.lcd_density數值/160.換句話說,qemu.sf.lcd_density這個LCD全局參數起了決定性的因素。

當然,沒有設置這兩個屬性,xdpi和ydpi則是默認的從HWC獲取出來的數據,density 為xdpi/160f。

當然此時還會判斷整個屏幕的橫豎狀態,最后在做一次寬高的顛倒。

HWComposer getConfigs

std::vector<:shared_ptr hwc2::display::config>>

HWComposer::getConfigs(int32_t displayId) const {

RETURN_IF_INVALID_DISPLAY(displayId, {});

auto& displayData = mDisplayData[displayId];

auto configs = mDisplayData[displayId].hwcDisplay->getConfigs();

if (displayData.configMap.empty()) {

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

displayData.configMap[i] = configs[i];

}

}

return configs;

}

還記得在SF初始化中,當onHotPlugin進入到HWC之后,先添加到HWCDevice中,之后就會添加到mDisplayData中。其實就是HWC::Display對象。而這個對象在初始化的時候就會讀取對應配置保存起來。

文件:/frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.cpp

void Display::loadConfigs()

{

ALOGV("[%" PRIu64 "] loadConfigs", mId);

std::vector<:config> configIds;

auto intError = mComposer.getDisplayConfigs(mId, &configIds);

auto error = static_cast(intError);

if (error != Error::None) {

return;

}

for (auto configId : configIds) {

loadConfig(configId);

}

}

void Display::loadConfig(hwc2_config_t configId)

{

ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);

auto config = Config::Builder(*this, configId)

.setWidth(getAttribute(configId, Attribute::Width))

.setHeight(getAttribute(configId, Attribute::Height))

.setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))

.setDpiX(getAttribute(configId, Attribute::DpiX))

.setDpiY(getAttribute(configId, Attribute::DpiY))

.build();

mConfigs.emplace(configId, std::move(config));

}

int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)

{

int32_t value = 0;

auto intError = mComposer.getDisplayAttribute(mId, configId,

static_cast<:icomposerclient::attribute>(attribute),

&value);

auto error = static_cast(intError);

if (error != Error::None) {

ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,

configId, to_string(attribute).c_str(),

to_string(error).c_str(), intError);

return -1;

}

return value;

}

我們找到對應保存硬件的configId,最后通過getDisplayAttribute查找,每一個屬性是什么。

此時就會到Hal層中讀取屏幕信息。根據上兩節的UML圖就能知道本質上是通過hw_device_t和硬件進行通信,那么我們就繼續以msm8960為基準閱讀。

文件:/hardware/qcom/display/msm8960/libhwcomposer/hwc.cpp

int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,

uint32_t config, const uint32_t* attributes, int32_t* values) {

hwc_context_t* ctx = (hwc_context_t*)(dev);

//If hotpluggable displays are inactive return error

if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {

return -1;

}

//From HWComposer

static const uint32_t DISPLAY_ATTRIBUTES[] = {

HWC_DISPLAY_VSYNC_PERIOD,

HWC_DISPLAY_WIDTH,

HWC_DISPLAY_HEIGHT,

HWC_DISPLAY_DPI_X,

HWC_DISPLAY_DPI_Y,

HWC_DISPLAY_NO_ATTRIBUTE,

};

const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /

sizeof(DISPLAY_ATTRIBUTES)[0]);

for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {

switch (attributes[i]) {

case HWC_DISPLAY_VSYNC_PERIOD:

values[i] = ctx->dpyAttr[disp].vsync_period;

break;

case HWC_DISPLAY_WIDTH:

values[i] = ctx->dpyAttr[disp].xres;

ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,

ctx->dpyAttr[disp].xres);

break;

case HWC_DISPLAY_HEIGHT:

values[i] = ctx->dpyAttr[disp].yres;

ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,

ctx->dpyAttr[disp].yres);

break;

case HWC_DISPLAY_DPI_X:

values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);

break;

case HWC_DISPLAY_DPI_Y:

values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);

break;

default:

ALOGE("Unknown display attribute %d",

attributes[i]);

return -EINVAL;

}

}

return 0;

}

其實這個時候就是檢測dpyAttr對應id中所有的ydpi,xdpi,xres,xdpi,vsync_period的信息。這個數組很熟悉,就是onHotPlugin的時候,通過uevent線程的socket回調上來的信息。

SF getActiveConfig

int SurfaceFlinger::getActiveConfig(const sp& display) {

if (display == nullptr) {

ALOGE("%s : display is nullptr", __func__);

return BAD_VALUE;

}

sp device(getDisplayDevice(display));

if (device != nullptr) {

return device->getActiveConfig();

}

return BAD_VALUE;

}

此時繼續在用BBinder作為key,找到DisplayDevice,使用DisplayDevice的getActiveConfig。而這個對象是什么?其實就是onHotPlugin的時候,調用setupNewDisplayDeviceInternal,裝載進來的參數。

if (state.type < DisplayDevice::DISPLAY_VIRTUAL) {

hw->setActiveConfig(getHwComposer().getActiveConfigIndex(state.type));

}

而這個參數還是調用了HWC的getActiveConfigIndex,從Hal中設置了活躍的ConfigId到DisplayDevice中。之后就能拿到這個活躍的ID了。

HWC的getActiveConfigIndex 本質上還是調用了HAL的getActiveConfig方法。而這個方法又是依賴setActiveConfig保存在HWC2On1Adapter::Display中。

什么時候設置呢?還記得我在WMS系列中聊過的RootWindowConatiner的嗎?它會調用performSurfacePlacement調用DisplayManagerService的performTraversal,通過SF設置當前活躍屏幕的id。它作為所有窗口的根窗口。同時在Activity onResume刷新界面之時,ViewRootImpl的performTraversals會調用聊到了WMS的relayout方法,這個方法刷新WMS中某個窗口的界面的時刻將會performSurfacePlacement。

通過這個方法,把WMS,DMS,SF全部串聯起來。

小結

思路有點跑遠了,getDisplayInfo實際做的事情拿到當前活躍的屏幕的屏幕信息。

SurfaceComposerClient createSurface

我們來回憶下,這個方法是怎么使用的:

sp control = session()->createSurface(String8("BootAnimation"),

dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);

能看到開機動畫設置Surface,設置了Surface的名字,寬高以及Surface的像素格式是RGB-565.

注意,這里是整個SF渲染畫面前期準備最為核心的步驟。

sp SurfaceComposerClient::createSurface(

const String8& name,

uint32_t w,

uint32_t h,

PixelFormat format,

uint32_t flags,

SurfaceControl* parent,

int32_t windowType,

int32_t ownerUid)

{

sp s;

createSurfaceChecked(name, w, h, format, &s, flags, parent, windowType, ownerUid);

return s;

}

status_t SurfaceComposerClient::createSurfaceChecked(

const String8& name,

uint32_t w,

uint32_t h,

PixelFormat format,

sp* outSurface,

uint32_t flags,

SurfaceControl* parent,

int32_t windowType,

int32_t ownerUid)

{

sp sur;

status_t err = mStatus;

if (mStatus == NO_ERROR) {

sp handle;

sp parentHandle;

sp gbp;

if (parent != nullptr) {

parentHandle = parent->getHandle();

}

err = mClient->createSurface(name, w, h, format, flags, parentHandle,

windowType, ownerUid, &handle, &gbp);

ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));

if (err == NO_ERROR) {

*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);

}

}

return err;

}

此時會調用SF的Client的createSurface創建一個SurfaceControl。能看到傳入了一個十分重要的對象IGraphicBufferProducer,這個對象就是圖元生產者。

Client createSurface

status_t Client::createSurface(

const String8& name,

uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,

const sp& parentHandle, int32_t windowType, int32_t ownerUid,

sp* handle,

sp* gbp)

{

sp parent = nullptr;

if (parentHandle != nullptr) {

auto layerHandle = reinterpret_cast<:handle>(parentHandle.get());

parent = layerHandle->owner.promote();

if (parent == nullptr) {

return NAME_NOT_FOUND;

}

}

if (parent == nullptr) {

bool parentDied;

parent = getParentLayer(&parentDied);

// If we had a parent, but it died, we've lost all

// our capabilities.

if (parentDied) {

return NAME_NOT_FOUND;

}

}

/*

* createSurface must be called from the GL thread so that it can

* have access to the GL context.

*/

class MessageCreateLayer : public MessageBase {

SurfaceFlinger* flinger;

Client* client;

sp* handle;

sp* gbp;

status_t result;

const String8& name;

uint32_t w, h;

PixelFormat format;

uint32_t flags;

sp* parent;

int32_t windowType;

int32_t ownerUid;

public:

MessageCreateLayer(SurfaceFlinger* flinger,

const String8& name, Client* client,

uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,

sp* handle, int32_t windowType, int32_t ownerUid,

sp* gbp,

sp* parent)

: flinger(flinger), client(client),

handle(handle), gbp(gbp), result(NO_ERROR),

name(name), w(w), h(h), format(format), flags(flags),

parent(parent), windowType(windowType), ownerUid(ownerUid) {

}

status_t getResult() const { return result; }

virtual bool handler() {

result = flinger->createLayer(name, client, w, h, format, flags,

windowType, ownerUid, handle, gbp, parent);

return true;

}

};

sp msg = new MessageCreateLayer(mFlinger.get(),

name, this, w, h, format, flags, handle,

windowType, ownerUid, gbp, &parent);

mFlinger->postMessageSync(msg);

return static_cast( msg.get() )->getResult();

}

該方法做了如下事情:

1.首先檢測當前的需要繪制的面Layer是否有父Layer。有則獲取parent的Layer。

2.構造一個Handler,等到下一個Loop才進行操作。這個操作就是通過SF調用createLayer創建一個Layer。注意這里繼續把Binder接口IGraphicBufferProducer繼續傳下去。

SF createLayer

status_t SurfaceFlinger::createLayer(

const String8& name,

const sp& client,

uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,

int32_t windowType, int32_t ownerUid, sp* handle,

sp* gbp, sp* parent)

{

if (int32_t(w|h) < 0) {

ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",

int(w), int(h));

return BAD_VALUE;

}

status_t result = NO_ERROR;

sp layer;

String8 uniqueName = getUniqueLayerName(name);

switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {

case ISurfaceComposerClient::eFXSurfaceNormal:

result = createBufferLayer(client,

uniqueName, w, h, flags, format,

handle, gbp, &layer);

break;

case ISurfaceComposerClient::eFXSurfaceColor:

result = createColorLayer(client,

uniqueName, w, h, flags,

handle, &layer);

break;

default:

result = BAD_VALUE;

break;

}

if (result != NO_ERROR) {

return result;

}

// window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java

// TODO b/64227542

if (windowType == 441731) {

windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL

layer->setPrimaryDisplayOnly();

}

layer->setInfo(windowType, ownerUid);

result = addClientLayer(client, *handle, *gbp, layer, *parent);

if (result != NO_ERROR) {

return result;

}

...

return result;

}

核心的邏輯分為2步驟:

1.createBufferLayer 創建圖層

2.addClientLayer 把圖層添加到Client

能看到在SF在這個時候會根據當前傳進來的type創建不同的Layer,分別是:

1.ISurfaceComposerClient::eFXSurfaceNormal 對應BufferLayer

2.ISurfaceComposerClient::eFXSurfaceColor 對應 ColorLayer

eFXSurfaceNormal = 0x00000000,

eFXSurfaceColor = 0x00020000,

eFXSurfaceMask = 0x000F0000,

分別分別是指這2個數值。在這個時候默認0,創建的是BufferLayer。那么這兩個Layer(圖層)有什么區別呢?其實ColorLayer一般不會使用,BufferLayer內置一套消費者生產者的圖元消費邏輯,能夠持續不斷的更新圖元。然而ColorLayer中沒有這些邏輯比較小巧,我們可以理解成一個無法變動的圖層。在現在的復雜的UI交互里面,用武之地比較少。

以后遇到再解析ColorLayer,我們需要集中精力給BufferLayer。

createBufferLayer 創建圖層

status_t SurfaceFlinger::createBufferLayer(const sp& client,

const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,

sp* handle, sp* gbp, sp* outLayer)

{

// initialize the surfaces

switch (format) {

case PIXEL_FORMAT_TRANSPARENT:

case PIXEL_FORMAT_TRANSLUCENT:

format = PIXEL_FORMAT_RGBA_8888;

break;

case PIXEL_FORMAT_OPAQUE:

format = PIXEL_FORMAT_RGBX_8888;

break;

}

sp layer = new BufferLayer(this, client, name, w, h, flags);

status_t err = layer->setBuffers(w, h, format, flags);

if (err == NO_ERROR) {

*handle = layer->getHandle();

*gbp = layer->getProducer();

*outLayer = layer;

}

return err;

}

這里會判斷傳進來的format,如果是需要設定透明色,則強制設置format為RGBA_8888模式。最后生成一個BufferLayer,把BufferLayer中的句柄以及圖元生產者返回客戶端(此時是SurfaceComposerClient中的SurfaceControl)。

Layer的初始化

Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w,

uint32_t h, uint32_t flags)

: contentDirty(false),

sequence(uint32_t(android_atomic_inc(&sSequence))),

mFlinger(flinger),

mPremultipliedAlpha(true),

mName(name),

mTransactionFlags(0),

mPendingStateMutex(),

mPendingStates(),

mQueuedFrames(0),

mSidebandStreamChanged(false),

mActiveBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),

mCurrentTransform(0),

mOverrideScalingMode(-1),

mCurrentOpacity(true),

mCurrentFrameNumber(0),

mFrameLatencyNeeded(false),

mFiltering(false),

mNeedsFiltering(false),

mProtectedByApp(false),

mClientRef(client),

mPotentialCursor(false),

mQueueItemLock(),

mQueueItemCondition(),

mQueueItems(),

mLastFrameNumberReceived(0),

mAutoRefresh(false),

mFreezeGeometryUpdates(false),

mCurrentChildren(LayerVector::StateSet::Current),

mDrawingChildren(LayerVector::StateSet::Drawing) {

mCurrentCrop.makeInvalid();

uint32_t layerFlags = 0;

if (flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;

if (flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;

if (flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;

mName = name;

mTransactionName = String8("TX - ") + mName;

mCurrentState.active.w = w;

mCurrentState.active.h = h;

mCurrentState.flags = layerFlags;

mCurrentState.active.transform.set(0, 0);

mCurrentState.crop.makeInvalid();

mCurrentState.finalCrop.makeInvalid();

mCurrentState.requestedFinalCrop = mCurrentState.finalCrop;

mCurrentState.requestedCrop = mCurrentState.crop;

mCurrentState.z = 0;

mCurrentState.color.a = 1.0f;

mCurrentState.layerStack = 0;

mCurrentState.sequence = 0;

mCurrentState.requested = mCurrentState.active;

mCurrentState.appId = 0;

mCurrentState.type = 0;

// drawing state & current state are identical

mDrawingState = mCurrentState;

const auto& hwc = flinger->getHwComposer();

const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY);

nsecs_t displayPeriod = activeConfig->getVsyncPeriod();

mFrameTracker.setDisplayRefreshPeriod(displayPeriod);

CompositorTiming compositorTiming;

flinger->getCompositorTiming(&compositorTiming);

mFrameEventHistory.initializeCompositorTiming(compositorTiming);

}

只需要知道它持有了HWC,flinger等對象即可。

BufferLayer的初始化

BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, const String8& name,

uint32_t w, uint32_t h, uint32_t flags)

: Layer(flinger, client, name, w, h, flags),

mConsumer(nullptr),

mTextureName(UINT32_MAX),

mFormat(PIXEL_FORMAT_NONE),

mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),

mBufferLatched(false),

mPreviousFrameNumber(0),

mUpdateTexImageFailed(false),

mRefreshPending(false) {

ALOGV("Creating Layer %s", name.string());

mFlinger->getRenderEngine().genTextures(1, &mTextureName);

mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);

if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false;

mCurrentState.requested = mCurrentState.active;

// drawing state & current state are identical

mDrawingState = mCurrentState;

}

這里面做了兩件比較重要的事情:

1.genTextures借助RenderEngine生成名字為mTextureName紋理對象

2.初始化Texture對象,綁定mTextureName。Texture是一個紋理矩陣的輔助類很簡單。

BufferLayer onFirstRef 設置圖元緩沖隊列

僅僅只是有BufferLayer還不夠,需要建立起一套生產者,消費者還需要更多東西。在實例化之后的onFirstRef才是真正的核心。

void BufferLayer::onFirstRef() {

// Creates a custom BufferQueue for SurfaceFlingerConsumer to use

sp producer;

sp consumer;

BufferQueue::createBufferQueue(&producer, &consumer, true);

mProducer = new MonitoredProducer(producer, mFlinger, this);

mConsumer = new BufferLayerConsumer(consumer,

mFlinger->getRenderEngine(), mTextureName, this);

mConsumer->setConsumerUsageBits(getEffectiveUsage(0));

mConsumer->setContentsChangedListener(this);

mConsumer->setName(mName);

if (mFlinger->isLayerTripleBufferingDisabled()) {

mProducer->setMaxDequeuedBufferCount(2);

}

const sp hw(mFlinger->getDefaultDisplayDevice());

updateTransformHint(hw);

}

在Layer中,我們明確能看到消費者和生產者字樣。通過BufferQueue::createBufferQueue 創建核心的生產者和消費者之后最后包裝,暴露外面的對象如下:

1.IGraphicBufferProducer 圖元生產者對應MonitoredProducer

2.IGraphicBufferConsumer 圖元消費者對應BufferLayerConsumer

緊接著有一個核心的邏輯,圖元消費者設置了ContentsChangedListener監聽,當需要刷新的時候,將會回調這個接口讓消費者消費。

BufferQueue::createBufferQueue 創建核心的生產者和消費者

void BufferQueue::createBufferQueue(sp* outProducer,

sp* outConsumer,

bool consumerIsSurfaceFlinger) {

sp core(new BufferQueueCore());

sp producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));

sp consumer(new BufferQueueConsumer(core));

*outProducer = producer;

*outConsumer = consumer;

}

整個核心有3個對象:

1.BufferQueueCore 緩沖隊列

2.BufferQueueProducer 圖元生產者

3.BufferQueueConsumer 圖元消費者

BufferQueueCore 初始化

BufferQueueCore::BufferQueueCore() :

mMutex(),

mIsAbandoned(false),

mConsumerControlledByApp(false),

mConsumerName(getUniqueName()),

mConsumerListener(),

mConsumerUsageBits(0),

mConsumerIsProtected(false),

mConnectedApi(NO_CONNECTED_API),

mLinkedToDeath(),

mConnectedProducerListener(),

mSlots(),

mQueue(),

mFreeSlots(),

mFreeBuffers(),

mUnusedSlots(),

mActiveBuffers(),

mDequeueCondition(),

mDequeueBufferCannotBlock(false),

mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),

mDefaultWidth(1),

mDefaultHeight(1),

mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),

mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),

mMaxAcquiredBufferCount(1),

mMaxDequeuedBufferCount(1),

mBufferHasBeenQueued(false),

mFrameCounter(0),

mTransformHint(0),

mIsAllocating(false),

mIsAllocatingCondition(),

mAllowAllocation(true),

mBufferAge(0),

mGenerationNumber(0),

mAsyncMode(false),

mSharedBufferMode(false),

mAutoRefresh(false),

mSharedBufferSlot(INVALID_BUFFER_SLOT),

mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE,

HAL_DATASPACE_UNKNOWN),

mLastQueuedSlot(INVALID_BUFFER_SLOT),

mUniqueId(getUniqueId())

{

int numStartingBuffers = getMaxBufferCountLocked();

for (int s = 0; s < numStartingBuffers; s++) {

mFreeSlots.insert(s);

}

for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;

s++) {

mUnusedSlots.push_front(s);

}

}

int BufferQueueCore::getMaxBufferCountLocked() const {

int maxBufferCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +

((mAsyncMode || mDequeueBufferCannotBlock) ? 1 : 0);

// limit maxBufferCount by mMaxBufferCount always

maxBufferCount = std::min(mMaxBufferCount, maxBufferCount);

return maxBufferCount;

}

在Core中初始化了一個很重要Slot數組。我發現Android系統很喜歡Slot這種設計,rosalloc也是類似的設計。slot我暫時稱為插槽。

能看到在這個插槽中準備了如下大小的當前Layer最大能申請的圖元數以及最大入隊圖元數,此時兩個同步模式的標志位都為false,因此就實際上maxBufferCount為2。mMaxBufferCount為一個編譯常量64。

因此此時會設置大小為2的mFreeSlot,也就是2個大小空閑插槽。同時設置剩下62個為mUnusedSlots,是不使用的插槽。

這個插槽,我們能夠知道實際就是一個緩沖隊列,等待圖元插進來。

BufferQueueProducer 圖元生產者初始化

class BufferQueueProducer : public BnGraphicBufferProducer,

private IBinder::DeathRecipient

這個對象就是上面IGraphicBufferProducer,因此這個對象會在SF的Layer中存在一個,同時會傳遞給客戶端。

BufferQueueProducer::BufferQueueProducer(const sp& core,

bool consumerIsSurfaceFlinger) :

mCore(core),

mSlots(core->mSlots),

mConsumerName(),

mStickyTransform(0),

mConsumerIsSurfaceFlinger(consumerIsSurfaceFlinger),

mLastQueueBufferFence(Fence::NO_FENCE),

mLastQueuedTransform(0),

mCallbackMutex(),

mNextCallbackTicket(0),

mCurrentCallbackTicket(0),

mCallbackCondition(),

mDequeueTimeout(-1) {}

關鍵是把當前的Slot傳遞進來。

BufferQueueConsumer 圖元消費者初始化

BufferQueueConsumer::BufferQueueConsumer(const sp& core) :

mCore(core),

mSlots(core->mSlots),

mConsumerName() {}

這里也很簡單,持有了Slot緩沖隊列。接下來看看他的包裹類。

BufferLayerConsumer 初始化

BufferLayerConsumer::BufferLayerConsumer(const sp& bq,

RE::RenderEngine& engine, uint32_t tex, Layer* layer)

: ConsumerBase(bq, false),

mCurrentCrop(Rect::EMPTY_RECT),

mCurrentTransform(0),

mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),

mCurrentFence(Fence::NO_FENCE),

mCurrentTimestamp(0),

mCurrentDataSpace(ui::Dataspace::UNKNOWN),

mCurrentFrameNumber(0),

mCurrentTransformToDisplayInverse(false),

mCurrentSurfaceDamage(),

mCurrentApi(0),

mDefaultWidth(1),

mDefaultHeight(1),

mFilteringEnabled(true),

mRE(engine),

mTexName(tex),

mLayer(layer),

mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) {

memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix));

mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);

}

它除了持有一個IGraphicBufferConsumer之外,還初始化了一個類型為mat4的mtxIdentity矩陣。如果熟悉著色器語言就知道這個的含義。它就是一個4*4矩陣。

class BufferLayerConsumer : public ConsumerBase

可以看到他是繼承了ConsumerBase,看看ConsumerBase初始化做了什么。

ConsumerBase 初始化

ConsumerBase::ConsumerBase(const sp& bufferQueue, bool controlledByApp) :

mAbandoned(false),

mConsumer(bufferQueue),

mPrevFinalReleaseFence(Fence::NO_FENCE) {

// Choose a name using the PID and a process-unique ID.

mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());

wp listener = static_cast(this);

sp proxy = new BufferQueue::ProxyConsumerListener(listener);

status_t err = mConsumer->consumerConnect(proxy, controlledByApp);

if (err != NO_ERROR) {

...

} else {

mConsumer->setConsumerName(mName);

}

}

在ConsumerBase初始化中把當前這個對象轉化為ConsumerListener,因為它繼承了ConsumerListener。同時mConsumer就是IGraphicBufferConsumer也就是上面的BufferQueueConsumer對象。把當前對象封裝成IConsumerListener,調用了consumerConnect注冊監聽,把行為鏈接到真正的消費者中。

BufferQueueConsumer consumerConnect

virtual status_t consumerConnect(const sp& consumer,

bool controlledByApp) {

return connect(consumer, controlledByApp);

}

status_t BufferQueueConsumer::connect(

const sp& consumerListener, bool controlledByApp) {

...

Mutex::Autolock lock(mCore->mMutex);

if (mCore->mIsAbandoned) {

...

return NO_INIT;

}

mCore->mConsumerListener = consumerListener;

mCore->mConsumerControlledByApp = controlledByApp;

return NO_ERROR;

}

此時就在BufferQueueCore中設置了消費者監聽回調。

BufferLayerConsumer setContentsChangedListener

接下來BufferLayerConsumer還需要注冊一個新的監聽是關于內容發生了變化也界面需要刷新的監聽。

文件:/frameworks/native/services/surfaceflinger/BufferLayerConsumer.cpp

void BufferLayerConsumer::setContentsChangedListener(const wp& listener) {

setFrameAvailableListener(listener);

Mutex::Autolock lock(mMutex);

mContentsChangedListener = listener;

}

此時會調用ConsumeBase的setFrameAvailableListener

ConsumeBase setFrameAvailableListener

void ConsumerBase::setFrameAvailableListener(

const wp& listener) {

Mutex::Autolock lock(mFrameAvailableMutex);

mFrameAvailableListener = listener;

}

這樣就完成了整個監聽的循環。類的嵌套太多,讓我畫一張UML圖來整理下。

Layer與緩沖隊列的設計.png

總結一句話就是,因為FrameAvailableListener最終進入到BufferQueueCore中。當生產者生產了一個圖元的時候就會從core中獲取FrameAvailableListener調用監聽,進入到ConsumeBase中,進一步的回調到BufferLayer中。最后到BufferLayer和SF執行后面的繪制步驟。

addClientLayer

status_t SurfaceFlinger::addClientLayer(const sp& client,

const sp& handle,

const sp& gbc,

const sp& lbc,

const sp& parent)

{

{

Mutex::Autolock _l(mStateLock);

...

if (parent == nullptr) {

mCurrentState.layersSortedByZ.add(lbc);

} else {

if (parent->isPendingRemoval()) {

ALOGE("addClientLayer called with a removed parent");

return NAME_NOT_FOUND;

}

parent->addChild(lbc);

}

if (gbc != nullptr) {

mGraphicBufferProducerList.insert(IInterface::asBinder(gbc).get());

...

}

mLayersAdded = true;

mNumLayers++;

}

client->attachLayer(handle, lbc);

return NO_ERROR;

}

如果當前的圖層Layer沒有任何父Layer,則存儲在mCurrentState的layersSortedByZ,也就是Z軸的最末尾,也就是當前渲染圖層的最上層。如果有就綁定給父Layer。

最后生產者隊列需要插入到mGraphicBufferProducerList全局集合中。

最后調用client的attachLayer把Client的Binder和生產者綁定起來。

Client attachLayer

void Client::attachLayer(const sp& handle, const sp& layer)

{

Mutex::Autolock _l(mLock);

mLayers.add(handle, layer);

}

這樣也同時存儲在Client上。

SurfaceControl 的初始化

經過上面的流程,完成了整一套的圖元緩沖隊列的構造。現在讓我們回到SurfaceComposerClient中,繼續SurfaceControl的初始化。

文件:/frameworks/native/libs/gui/SurfaceControl.cpp

SurfaceControl::SurfaceControl(

const sp& client,

const sp& handle,

const sp& gbp,

bool owned)

: mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)

{

}

此時SurfaceControl同時持有了Client的Binder,圖元生產者以及SurfaceComposerClient服務。

SurfaceControl 生產Surface

當SurfaceControl有了之后,需要繪制像素,是繪制在SurfaceControl生成的Surface上。

sp SurfaceControl::generateSurfaceLocked() const

{

// This surface is always consumed by SurfaceFlinger, so the

// producerControlledByApp value doesn't matter; using false.

mSurfaceData = new Surface(mGraphicBufferProducer, false);

return mSurfaceData;

}

sp SurfaceControl::getSurface() const

{

Mutex::Autolock _l(mLock);

if (mSurfaceData == 0) {

return generateSurfaceLocked();

}

return mSurfaceData;

}

其實就是把圖元生產者設置到Surface中。

Surface的初始化

Surface才是面向我們客戶端,開發者的繪制圖層。我們不會直接操作圖元生產者。一切的事情都交給Surface來發送。這里面包含了很重要的圖元發送等邏輯。

class Surface

: public ANativeObjectBase

可以看到繼承了一個ANativeObjectBase模版類,這個模版類只是處理引用計數,不過設計的很精巧,可以學習。

template

typename NATIVE_BASE = android_native_base_t>

class ANativeObjectBase : public NATIVE_TYPE, public REF

{

public:

// Disambiguate between the incStrong in REF and NATIVE_TYPE

void incStrong(const void* id) const {

REF::incStrong(id);

}

void decStrong(const void* id) const {

REF::decStrong(id);

}

protected:

typedef ANativeObjectBase BASE;

ANativeObjectBase() : NATIVE_TYPE(), REF() {

NATIVE_TYPE::common.incRef = incRef;

NATIVE_TYPE::common.decRef = decRef;

}

static inline TYPE* getSelf(NATIVE_TYPE* self) {

return static_cast(self);

}

static inline TYPE const* getSelf(NATIVE_TYPE const* self) {

return static_cast(self);

}

static inline TYPE* getSelf(NATIVE_BASE* base) {

return getSelf(reinterpret_cast(base));

}

static inline TYPE const * getSelf(NATIVE_BASE const* base) {

return getSelf(reinterpret_cast(base));

}

static void incRef(NATIVE_BASE* base) {

ANativeObjectBase* self = getSelf(base);

self->incStrong(self);

}

static void decRef(NATIVE_BASE* base) {

ANativeObjectBase* self = getSelf(base);

self->decStrong(self);

}

};

使用了模版了決定了繼承關系。換句話說其實相當于一個Hook,在不改變設計結構下,增加了引用的特性。

ANativeWindow 結構體

struct ANativeWindow

{

#ifdef __cplusplus

ANativeWindow()

: flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)

{

common.magic = ANDROID_NATIVE_WINDOW_MAGIC;

common.version = sizeof(ANativeWindow);

memset(common.reserved, 0, sizeof(common.reserved));

}

/* Implement the methods that sp expects so that it

can be used to automatically refcount ANativeWindow's. */

void incStrong(const void* /*id*/) const {

common.incRef(const_cast(&common));

}

void decStrong(const void* /*id*/) const {

common.decRef(const_cast(&common));

}

#endif

struct android_native_base_t common;

/* flags describing some attributes of this surface or its updater */

const uint32_t flags;

/* min swap interval supported by this updated */

const int minSwapInterval;

/* max swap interval supported by this updated */

const int maxSwapInterval;

/* horizontal and vertical resolution in DPI */

const float xdpi;

const float ydpi;

intptr_t oem[4];

int (*setSwapInterval)(struct ANativeWindow* window,

int interval);

int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,

struct ANativeWindowBuffer** buffer);

int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer);

int (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer);

int (*query)(const struct ANativeWindow* window,

int what, int* value);

int (*perform)(struct ANativeWindow* window,

int operation, ... );

int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer);

int (*dequeueBuffer)(struct ANativeWindow* window,

struct ANativeWindowBuffer** buffer, int* fenceFd);

int (*queueBuffer)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer, int fenceFd);

int (*cancelBuffer)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer, int fenceFd);

};

實際上,我們就能看到不少線索,別看叫做Window,實際上ANativeWindow不是作為圖元存儲的結構體,能從結構體中的方法指針看得出,實際上ANativeWindow是用來控制ANativeWindowBuffer 像素緩存的。大致上有四個操作,queueBuffer 圖元入隊,dequeueBuffer 圖元出隊,lockBuffer 圖元鎖定,query圖元查找等。當然還有setSwapInterval交換緩沖。

我們再轉過頭看看整個Surface的初始化。

Surface::Surface(const sp& bufferProducer, bool controlledByApp)

: mGraphicBufferProducer(bufferProducer),

mCrop(Rect::EMPTY_RECT),

mBufferAge(0),

mGenerationNumber(0),

mSharedBufferMode(false),

mAutoRefresh(false),

mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),

mSharedBufferHasBeenQueued(false),

mQueriedSupportedTimestamps(false),

mFrameTimestampsSupportsPresent(false),

mEnableFrameTimestamps(false),

mFrameEventHistory(std::make_unique()) {

// Initialize the ANativeWindow function pointers.

ANativeWindow::setSwapInterval = hook_setSwapInterval;

ANativeWindow::dequeueBuffer = hook_dequeueBuffer;

ANativeWindow::cancelBuffer = hook_cancelBuffer;

ANativeWindow::queueBuffer = hook_queueBuffer;

ANativeWindow::query = hook_query;

ANativeWindow::perform = hook_perform;

ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;

ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;

ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;

ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;

const_cast(ANativeWindow::minSwapInterval) = 0;

const_cast(ANativeWindow::maxSwapInterval) = 1;

mReqWidth = 0;

mReqHeight = 0;

mReqFormat = 0;

mReqUsage = 0;

mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;

mDataSpace = Dataspace::UNKNOWN;

mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;

mTransform = 0;

mStickyTransform = 0;

mDefaultWidth = 0;

mDefaultHeight = 0;

mUserWidth = 0;

mUserHeight = 0;

mTransformHint = 0;

mConsumerRunningBehind = false;

mConnectedToCpu = false;

mProducerControlledByApp = controlledByApp;

mSwapIntervalZero = false;

}

在Surface初始化的時候,同時為每一個方法指針都賦值了,讓Surface擁有了操作的能力。

總結

關于BufferQueue 圖元緩沖隊列的初始化就到這里。在這個初始化流程中,初步的搭建了整個生產者-消費者模型。剩下的步驟就是生產圖元,寫入生產者,生產者把數據寫進緩沖隊列,通知消費者進行消費。

后面的步驟,我們慢慢再聊。老規矩用一幅圖總結整個流程。

SF的生產者消費者模型.png

總結一遍流程,本文總結了開機動畫1-5的步驟。

getBuiltInDisplay 從BuiltInDisplay數組中獲取當前的屏幕

getDisplayInfo 從SF中獲取活躍的屏幕信息

createSurface 通過SF的Client對象創建了一個圖元生產者,并且賦值給SurfaceControl中。

setLayer 設置layer 圖層在Z軸上的層級

getSurface 通過SurfaceControl生產Surface對象,真正進行交互是Surface對象。

有了這些基礎之后,下一篇文章就來聊聊,Android在OpenGL es上的封裝。

總結

以上是生活随笔為你收集整理的android 队列执行动画,Android 重学系列 渲染图层-图元缓冲队列初始化的全部內容,希望文章能夠幫你解決所遇到的問題。

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

在线播放国产精品 | 国产精品a级 | 超碰国产在线播放 | 丁香激情综合久久伊人久久 | 国产三级精品在线 | 特级西西444www大胆高清无视频 | 日韩字幕 | 久久久免费精品国产一区二区 | 天天搞天天干天天色 | 中文字幕丝袜制服 | 久久这里只有精品9 | 日韩一级电影在线观看 | 中文字幕在线观看播放 | www178ccom视频在线| 91看片在线播放 | 狠狠色丁香久久婷婷综合丁香 | 亚洲天堂网站 | 国产97视频 | 欧美日韩一级久久久久久免费看 | 超碰成人免费电影 | 国产精品三级视频 | 精品一区二区在线观看 | 久久精品亚洲国产 | 国产精品视频地址 | 91av小视频 | 国产精品中文字幕av | 国产不卡高清 | 97视频入口免费观看 | 在线视频麻豆 | 成年人看片 | 亚洲国产中文字幕在线观看 | 91精品一区二区三区蜜臀 | 国产精品自产拍在线观看网站 | 成人在线视频论坛 | 国产精品永久 | 五月情婷婷 | 一区二区三区在线免费播放 | 99久久久国产精品免费观看 | 久久精品国产免费看久久精品 | 九色精品免费永久在线 | 久久精品国产一区二区电影 | 一级成人在线 | 色大片免费看 | 免费亚洲黄色 | 麻豆久久久久久久 | 久久久精品网 | 波多野结衣视频在线 | 久久综合加勒比 | 九九热有精品 | 麻豆视频在线免费观看 | 在线观看免费福利 | 精品免费观看视频 | 亚洲精品视频在线观看免费 | 97偷拍视频| 国产精品亚 | 中文字幕在线观看播放 | 黄色一级大片免费看 | 黄色av电影网 | 午夜精品久久久久99热app | 久久一区二区三区超碰国产精品 | 国产一级二级在线播放 | 97视频久久久 | 天天激情在线 | 中文字幕电影高清在线观看 | 久久久穴 | 99久久精品国产观看 | 天天操天天是 | 免费黄色看片 | av在线一级 | 久久久久99999 | 欧美日韩精| 久久精品一区二区 | 日韩影视大全 | 99超碰在线观看 | a午夜在线| 国产成人一区二区在线观看 | 成 人 黄 色 视频免费播放 | 99视频免费| 国产精品久久久久久婷婷天堂 | 国产在线精品国自产拍影院 | 91xav| 日韩免费一级电影 | 精品av在线播放 | 婷五月激情| 国产一区成人在线 | 欧美三级高清 | 婷婷丁香激情五月 | 天天激情综合网 | 色资源二区在线视频 | 欧美精品久久久久久久 | 99免费在线视频观看 | 久久久久久影视 | 久久精品视频中文字幕 | 亚洲一区久久久 | 欧美性做爰猛烈叫床潮 | 91精品免费看 | 五月天天色 | 麻豆视频免费观看 | 免费观看的黄色 | 亚洲欧美视频网站 | 中文字幕乱码一区二区 | 欧美另类网站 | 精品国产成人 | 日韩免费福利 | 成人毛片久久 | 天天艹日日干 | 国产精品一区二区在线观看 | 久草视频免费播放 | 国产 中文 日韩 欧美 | 午夜av在线电影 | 成人毛片久久 | 成人cosplay福利网站 | 成人av影视在线 | 午夜视频在线观看一区二区三区 | 亚洲人成在线电影 | 欧美精品亚洲精品日韩精品 | 粉嫩av一区二区三区四区在线观看 | 国产中年夫妇高潮精品视频 | 天天射天天艹 | 中文字幕精品三级久久久 | 国产一区二区手机在线观看 | 中文网丁香综合网 | 亚洲专区视频在线观看 | 97超视频免费观看 | 国产成人亚洲精品自产在线 | 曰韩精品 | 激情xxxx| 一区二区视频网站 | 亚洲精品乱码久久久久久高潮 | 亚洲成人家庭影院 | 中文字幕三区 | 成人a大片| 又粗又长又大又爽又黄少妇毛片 | 欧美a视频在线观看 | 81国产精品久久久久久久久久 | 亚洲日本va中文字幕 | 在线观看av黄色 | 欧美一二三四在线 | 黄色大全在线观看 | 日韩最新中文字幕 | 97国产在线 | 免费看成人片 | 天天草网站 | 免费涩涩网站 | 99热在线这里只有精品 | 国产一区精品在线观看 | 国产精品一区二区在线 | 成人黄色在线播放 | 国产97av | 九九九电影免费看 | 色婷婷国产精品一区在线观看 | 久久综合久久伊人 | 国产精品一区二区三区在线播放 | 欧美日韩精品影院 | 国产色a在线观看 | 成人av网站在线观看 | 91麻豆文化传媒在线观看 | 久久成年人网站 | 99精品国产成人一区二区 | 91亚色视频| 亚洲欧美日本一区二区三区 | 日本九九视频 | 久久免费99精品久久久久久 | 99视频一区二区 | 毛片网免费 | av免费看在线 | 五月开心激情 | 亚洲国产精品小视频 | 国内外激情视频 | 久久夜色网 | 精品人妖videos欧美人妖 | 一区二区三区www | 国产成人一区二区啪在线观看 | 91av蜜桃| 91电影福利 | 人人干天天射 | 狠狠色伊人亚洲综合网站色 | 91mv.cool在线观看 | 狠狠狠狠狠操 | 黄色电影小说 | 成人av网站在线播放 | 国产美女网站在线观看 | 精品免费99久久 | 在线观看成人一级片 | 久久这里只有精品视频首页 | 久久激情日本aⅴ | 欧美一区在线观看视频 | 午夜视频在线观看网站 | 成人亚洲欧美 | 国产欧美精品xxxx另类 | 国产成人精品亚洲精品 | 欧美成人亚洲 | www一起操 | 在线观看av国产 | 国产午夜精品一区 | 91av电影网| 中文字幕在线第一页 | 99久高清在线观看视频99精品热在线观看视频 | 97超视频在线观看 | 亚洲最新精品 | 免费三级影片 | 最新国产精品久久精品 | 四虎欧美| 欧美日韩国产二区 | 国产精品国产三级在线专区 | 91精品啪在线观看国产 | 99热精品国产一区二区在线观看 | 在线免费av网站 | 日韩va欧美va亚洲va久久 | 中文字幕在线观看2018 | 亚洲国产合集 | 国产亚洲一级高清 | 免费看片成年人 | 欧美成人性网 | 在线观看一区 | 国产在线2020 | 亚洲精品国产精品国自产在线 | 有码视频在线观看 | 欧美一级xxxx | 色伊人网 | 九九日九九操 | 天天干天天天 | 久草在线免 | 91高清免费在线观看 | 丁香国产视频 | 中文字幕五区 | 午夜色站 | 91在线资源| 天天干,狠狠干 | 精品日韩在线一区 | 精品久久五月天 | 欧美日韩精品免费观看 | 亚洲最大成人免费网站 | 欧美激情视频一二三区 | 成人97视频一区二区 | 9热精品 | 国产亚洲视频系列 | 精品九九九 | 五月天中文在线 | 国产日韩欧美在线 | 最近免费观看的电影完整版 | 精品一区二区电影 | 天天综合操 | 91人人澡 | 91中文在线| 国精产品999国精产品视频 | 亚洲成人精品在线 | 在线一级片 | 中文字幕在线观看免费高清电影 | 在线免费视频一区 | 国产色影院 | 国产一级精品在线观看 | 超碰97国产精品人人cao | 欧美日韩高清一区二区 国产亚洲免费看 | 91一区二区在线 | 日日夜夜噜噜噜 | 欧美性脚交 | 久久久资源网 | 久草在线费播放视频 | 在线日韩亚洲 | 国产亚洲视频中文字幕视频 | 久久草av| 国内精品视频在线播放 | 天天综合色| 国精产品999国精产品视频 | 久久免视频 | 中文av字幕在线观看 | 久久在现| 免费美女av | av网站有哪些 | 国产精品久久久久免费 | 日韩av专区 | 日韩精品免费在线观看视频 | 五月婷婷网站 | a色视频| 婷婷国产v亚洲v欧美久久 | 中文av一区二区 | 狠狠色丁香九九婷婷综合五月 | 99se视频在线观看 | av电影免费在线 | 亚洲动漫在线观看 | 啪一啪在线 | 亚洲精品88欧美一区二区 | 99久久精品一区二区成人 | 黄色高清视频在线观看 | 久久精品国产第一区二区三区 | 欧美激情xxxx性bbbb | 在线观影网站 | 最近中文字幕完整高清 | 久久五月网 | 久久激五月天综合精品 | 在线视频亚洲 | 999久久精品 | 日韩| 97国产在线播放 | 97免费在线观看 | 国产精品九色 | 久久 精品一区 | 麻豆视频国产在线观看 | 午夜精品99久久免费 | 亚洲欧美日韩精品久久奇米一区 | 激情偷乱人伦小说视频在线观看 | 婷婷丁香在线视频 | 色就色,综合激情 | 午夜精品一区二区三区在线播放 | 超碰人人在 | 久久精品国产成人 | 欧美日韩性生活 | 亚洲国产影院 | 天天色宗合 | 久久久电影网站 | 成人黄色在线观看视频 | 国内外成人在线视频 | 国产一区视频免费在线观看 | 九九久久久久久久久激情 | 国产97在线视频 | 又爽又黄又刺激的视频 | 久久深夜福利免费观看 | 91视频网址入口 | 日日爽夜夜爽 | 麻豆果冻剧传媒在线播放 | 免费观看国产精品视频 | 国产精品久久久久久一区二区三区 | 日本最大色倩网站www | 亚洲精品国产精品乱码在线观看 | 夜夜躁天天躁很躁波 | 成人免费ⅴa | 黄色在线观看网站 | 97在线看片 | 日日摸日日添夜夜爽97 | 日韩av手机在线观看 | 日本护士三级少妇三级999 | 免费观看版 | 有码中文在线 | 精品九九九 | 色一色在线 | 国产精品久久久久久久久久妇女 | 国产aa免费视频 | av网站在线免费观看 | 青青五月天 | 久久精品99久久久久久2456 | 日韩av女优视频 | 青青草国产精品视频 | 欧美日韩一级久久久久久免费看 | 日韩黄色大片在线观看 | 天天操夜夜看 | 亚洲精品视频免费 | 久久久久成 | 成人免费毛片aaaaaa片 | 日韩精品免费在线观看 | 色狠狠婷婷 | 中文字幕日韩电影 | 看污网站 | 在线中文字幕av观看 | 中文字幕成人在线观看 | 午夜视频导航 | 国产二区免费视频 | 国产小视频精品 | 在线 精品 国产 | 国产精品视频永久免费播放 | 在线视频一区二区 | av网站免费看 | 国产精品综合av一区二区国产馆 | 欧美日韩一区久久 | 天天操夜夜操国产精品 | 综合色在线观看 | 日韩欧美一级二级 | 黄色片网站 | 国产精品第一页在线观看 | 热99久久精品 | 国产午夜一级毛片 | 五月综合激情网 | 狠狠的操你 | 一区二区三区在线观看 | 91精品在线播放 | 精品国产黄色片 | 日本99热 | 亚洲另类视频在线观看 | av免费网站观看 | 成人免费视频视频在线观看 免费 | 亚洲午夜精品久久久 | 国产精品 亚洲精品 | 国内精品久久久久影院男同志 | 日日摸日日碰 | 国产视频资源在线观看 | 国产精品久久久久三级 | 欧美一级专区免费大片 | 色婷婷www| 97在线免费视频观看 | 麻豆精品传媒视频 | 天堂av最新网址 | 国产精品毛片完整版 | 99国产精品久久久久老师 | 日韩欧美一区二区在线播放 | 99久热在线精品 | 国产麻豆精品久久一二三 | 欧美va日韩va | 国内久久看 | 国产高清在线 | 欧美不卡视频在线 | 天天做日日爱夜夜爽 | 久久这里只有精品首页 | av免费在线播放 | 91麻豆精品91久久久久同性 | www.啪啪.com| 人人爽人人澡 | 九草在线视频 | 日本精品xxxx | 国产成人一区二区精品非洲 | 99热精品免费观看 | 亚洲精品午夜国产va久久成人 | 成人国产精品久久久久久亚洲 | 在线国产福利 | 婷婷福利影院 | 色婷婷激情四射 | 日韩在线观看视频中文字幕 | 日韩亚洲精品电影 | 免费看污黄网站 | 国产精品淫 | 色综合久久88色综合天天免费 | 最新成人av| 91麻豆精品国产91久久久久 | 成人九九视频 | 奇米7777狠狠狠琪琪视频 | 在线天堂中文www视软件 | 天天艹天天爽 | 色视频在线观看免费 | 热久久视久久精品18亚洲精品 | 久久精品日产第一区二区三区乱码 | 91免费的视频在线播放 | 久久久久久久久久久黄色 | 日韩免费在线 | 四虎免费在线观看视频 | 女人久久久久 | 国产高清视频 | 日日爽天天 | 在线之家免费在线观看电影 | 在线观看中文字幕亚洲 | 久久久精品电影 | 婷婷色六月天 | 久久午夜影院 | 久操视频在线 | 色99在线| 国产91精品久久久久 | 色综合天天视频在线观看 | 久久精品国产精品亚洲 | www.人人干 | 亚洲午夜久久久久久久久 | 精品一区二区久久久久久久网站 | 亚洲精品在线观看不卡 | 天天玩天天操天天射 | 久久久久久久久久久久久国产精品 | 婷婷免费视频 | 亚洲一区网站 | 久久综合网色—综合色88 | 中文字幕在线观看免费高清完整版 | 欧洲亚洲国产视频 | 久久精品高清 | 日韩3区 | 国产成人一区二区三区在线观看 | 午夜精品一区二区三区免费视频 | 国产成人91 | av电影 一区二区 | 欧美一级电影在线观看 | 婷婷九月激情 | 欧美成人基地 | 免费a级毛片在线看 | 天天综合精品 | 国产片免费在线观看视频 | 国产精品免费不卡 | 亚洲午夜精品久久久久久久久久久久 | 免费黄色网止 | 日韩视频一区二区在线 | 色成人亚洲网 | 欧美va天堂va视频va在线 | 波多野结衣精品视频 | 狠狠狠色丁香婷婷综合激情 | 中文字幕中文字幕 | 欧美一级特黄高清视频 | 69国产成人综合久久精品欧美 | 国产丝袜美腿在线 | 欧美日韩高清国产 | 欧美激情精品久久久久久变态 | 91精品久久久久久久91蜜桃 | 亚洲国产精品激情在线观看 | 9在线观看免费高清完整版在线观看明 | 最近更新好看的中文字幕 | 久久www免费视频 | 国产精品久久久av | 日日夜日日干 | 99热高清 | av看片在线观看 | 国产一级黄| 日韩中文字幕视频在线观看 | 国产香蕉97碰碰碰视频在线观看 | 亚洲乱码精品 | 亚洲伦理精品 | 欧美精品亚洲精品日韩精品 | 国产免费成人av | 丰满少妇在线观看网站 | 永久免费毛片在线观看 | 久久久久久片 | 婷婷综合视频 | 久热电影 | 日本在线视频一区二区三区 | 久草电影免费在线观看 | 日韩91精品 | 视频在线一区二区三区 | 久久国产a | 亚洲理论片| 香蕉视频91| 欧美尹人 | 中文字幕4 | 欧美色道 | av三级在线免费观看 | 国产精品6 | 色婷婷88av视频一二三区 | 免费亚洲成人 | 中文字幕首页 | 999精品在线 | 成人在线免费视频观看 | 香蕉影院在线 | 91麻豆精品久久久久久 | 六月婷婷久香在线视频 | 麻豆精品国产传媒 | 婷婷亚洲综合 | 欧美日韩一区二区三区在线观看视频 | 五月天.com | 国产又粗又猛又色又黄视频 | 美女性爽视频国产免费app | 99爱精品在线 | 国产成人精品日本亚洲999 | 91精品久久香蕉国产线看观看 | 国产成人精品综合久久久久99 | 亚洲精品国产精品国自产观看浪潮 | 日韩在线精品视频 | 国产精品成人av电影 | 免费在线黄色av | 麻豆91在线观看 | 91综合久久一区二区 | 97福利视频 | 国产精品久久久久久久久毛片 | 特级xxxxx欧美 | 中文不卡视频在线 | 婷婷av色综合 | 91中文字幕视频 | 人人干人人草 | 91久久精品日日躁夜夜躁国产 | 欧美另类交人妖 | 亚洲妇女av | 在线免费中文字幕 | 91精品少妇偷拍99 | 91九色porny在线 | 国产精品一区二区三区电影 | 久久久久久亚洲精品 | 国内久久久久久 | 91精品成人| 91精品视频免费看 | 久久久人| 成年人黄色av| 久草在线最新 | 91九色丨porny丨丰满6 | 91在线看免费 | 99视频免费看 | 国产精品视频永久免费播放 | 久久99久久久久 | 久久久久久久久久久久久9999 | 亚洲三级黄 | 日本中文字幕在线免费观看 | 亚洲国产精品电影在线观看 | 黄色成人av网址 | 国产精品网站 | 狠狠操精品 | 一级黄色片在线观看 | 欧美激情精品 | 国产在线日韩 | 亚洲高清91 | 久久综合色婷婷 | 色午夜影院 | 中文字幕免费高清在线 | 特级黄色一级 | 97日日 | 欧美成人精品三级在线观看播放 | 999久久国产 | 国产精品视频地址 | 国产成人精品国内自产拍免费看 | 日本不卡123区 | sm免费xx网站| 色噜噜噜 | 特级西西www44高清大胆图片 | 日韩一区二区三区免费视频 | 99在线视频免费观看 | 日本韩国精品一区二区在线观看 | 久久久高清免费视频 | 色综合久久五月天 | 久久免费中文视频 | 色婷婷www| 中文字幕在线视频一区二区 | 国产精品99蜜臀久久不卡二区 | 亚洲精品456在线播放第一页 | 久久久精品久久日韩一区综合 | 亚洲网久久 | 99精品在线 | 免费日韩三级 | 日韩在线视频线视频免费网站 | 91丨九色丨国产丨porny精品 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 天天草天天干天天 | 91久久电影| 日本高清免费中文字幕 | 91久久奴性调教 | 免费91麻豆精品国产自产在线观看 | 国产麻豆精品传媒av国产下载 | 天天躁天天操 | 国产亚洲精品女人久久久久久 | 国产精品久久久久久久久久久久午 | 91成人免费视频 | 国产成人精品综合久久久久99 | 视频一区二区精品 | 中文字幕频道 | 精品视频www | 国产精品一区二区三区免费视频 | 精品久久视频 | 亚洲精品福利在线 | www国产亚洲精品久久麻豆 | 久久精品久久久久 | 亚洲欧美久久 | 中文字幕第一 | 色婷婷激婷婷情综天天 | 啪啪免费观看网站 | 99视频在线观看视频 | 9在线观看免费高清完整版在线观看明 | 亚洲第一区在线播放 | 日韩中文在线字幕 | 色91在线视频 | 国产手机av| 人人搞人人搞 | www.神马久久 | 国产在线观看a | 亚洲区另类春色综合小说校园片 | 狠狠狠色狠狠色综合 | 成年人av在线播放 | 亚洲婷婷网 | 国产麻豆视频网站 | 97精品欧美91久久久久久 | 欧洲亚洲女同hd | 中文字幕日韩高清 | 69久久久| 97精品国产手机 | 国产欧美在线一区二区三区 | 国产青草视频在线观看 | 天天色天天艹 | 国产精品va在线观看入 | 中文字幕在线第一页 | av亚洲产国偷v产偷v自拍小说 | 四季av综合网站 | 国产精品久久电影观看 | 免费日韩高清 | 久久免费公开视频 | 婷婷av综合| 1区2区视频| 国产成人精品一区二区三区网站观看 | 日韩精品视频一二三 | 中文字幕在线播放日韩 | 麻豆视频在线看 | 99免在线观看免费视频高清 | 免费网站在线观看成人 | 久在线观看 | 国产欧美日韩视频 | 久草视频免费在线观看 | 99爱国产精品 | 91丨九色丨蝌蚪丰满 | 国产精品午夜免费福利视频 | 成人国产精品电影 | 成人四虎影院 | 三级黄色网址 | 狠狠色丁香婷婷综合久小说久 | 五月天电影免费在线观看一区 | 日韩精品高清不卡 | 久久久影院一区二区三区 | 日韩精品欧美视频 | 国产免费资源 | 在线观看视频一区二区三区 | 免费色视频在线 | 久久久国产精品久久久 | 久久久精品国产一区二区电影四季 | 手机av在线免费观看 | 亚洲精品欧美专区 | 国产日本在线 | 国产福利免费在线观看 | 99九九99九九九视频精品 | 天天爽人人爽 | 欧美午夜一区二区福利视频 | 亚洲国产中文字幕 | 国产成人777777 | 国产精品国产精品 | 国产成人精品午夜在线播放 | 国产高清视频网 | 视频三区在线 | 97香蕉超级碰碰久久免费软件 | 日韩在线观看中文 | 亚洲精品午夜久久久久久久 | 91中文字幕在线 | www欧美色 | 超碰av在线播放 | 91久久国产综合精品女同国语 | 久久精品久久久精品美女 | 亚洲人成人在线 | 亚洲专区路线二 | 亚洲黄色三级 | av高清一区二区三区 | 黄色网址av | 91福利视频久久久久 | 国产视频91在线 | 蜜桃视频在线观看一区 | 久久激情视频免费观看 | 免费网站看v片在线a | 91亚洲永久精品 | 久色 网| 午夜三级影院 | 日韩一区二区免费在线观看 | 亚洲美女免费视频 | www.福利 | 夜夜摸夜夜爽 | 一区二区三区免费看 | 99久久国产免费看 | 日韩啪啪小视频 | 久久女同性恋中文字幕 | 欧美日韩在线精品一区二区 | 五月婷婷视频在线 | 欧美一级电影在线观看 | 久久无码精品一区二区三区 | 午夜精品久久久久 | 欧美国产精品久久久久久免费 | 国产高清视频色在线www | 又爽又黄又刺激的视频 | 久草a在线 | 黄色官网在线观看 | 精品国产乱码久久久久久1区2匹 | 久久国产成人午夜av影院宅 | 日韩电影在线视频 | 国产精品久久久久久久久搜平片 | 96精品高清视频在线观看软件特色 | 欧美日韩二区三区 | 97国产一区二区 | 国产九色在线播放九色 | adn—256中文在线观看 | 91在线你懂的 | 超碰在线成人 | 91爱爱电影 | 黄色免费网站大全 | 久久在线影院 | 久久草在线精品 | 91新人在线观看 | 在线观看免费一级片 | 天天射天天操天天色 | 久久久91精品国产一区二区精品 | 国产不卡在线观看视频 | 亚洲国产小视频在线观看 | 久久国产精品99国产精 | 天天干,天天射,天天操,天天摸 | 91久久精品一区 | 激情婷婷在线观看 | 国产成人久久精品亚洲 | 久久九九久久精品 | 亚洲伊人色 | av高清免费 | 欧美精品一区二区三区一线天视频 | 999电影免费在线观看 | 96视频在线| 久久av网址 | 久久精品亚洲综合专区 | 国产亚洲视频在线观看 | 日韩成人免费在线电影 | 久久久久国产免费免费 | 高清av中文字幕 | 中文字幕在线有码 | 成人动图| 亚洲成a人片综合在线 | 色大片免费看 | 久久不射电影院 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 亚洲三级国产 | 国产理论一区二区三区 | 九九久久久久久久久激情 | 91精品视频播放 | 国产精品久久久久久久av电影 | 国产精品美女久久久免费 | 亚洲麻豆精品 | 中文字幕频道 | 日韩欧美在线影院 | 天天操天天操天天 | www视频在线观看 | 婷婷国产在线 | 亚洲三级在线 | 国产亚洲精品美女 | 色噜噜日韩精品欧美一区二区 | 欧洲激情在线 | 在线直播av | 午夜av免费观看 | 成人一级电影在线观看 | 96超碰在线| 视频在线在亚洲 | 日日夜夜网站 | 麻豆果冻剧传媒在线播放 | 狠狠干夜夜爱 | 成人黄色大片在线免费观看 | 伊人婷婷 | av资源免费观看 | 国产香蕉视频在线观看 | 91精品国产91久久久久福利 | 91自拍视频在线观看 | 中文有码在线视频 | 亚洲日本黄色 | 激情 婷婷 | 九九亚洲精品 | 青春草视频 | 91福利视频免费 | 国产高清亚洲 | 亚洲最新在线 | 日韩精品一区二 | 久久婷婷亚洲 | 国产在线美女 | 97超碰色| 成人久久毛片 | 婷香五月 | 欧美美女激情18p | 婷婷播播网 | 午夜电影av| 亚洲精品免费在线播放 | 午夜神马福利 | 国产99久久九九精品免费 | 久久国产成人午夜av影院宅 | 日本中文字幕视频 | 美女精品在线 | 在线观看免费av网站 | 九九免费观看全部免费视频 | 欧美黄色成人 | 久久99久久99精品免费看小说 | www色婷婷com | 干狠狠| 亚洲精品国产精品国 | 国产亚洲情侣一区二区无 | 国产成人精品一区二区三区福利 | 91最新视频 | 人人插人人费 | 日韩午夜电影院 | 国内精品中文字幕 | 婷婷久久网 | 97人人射| 日韩最新av在线 | 久久久免费观看 | 亚洲一区二区三区四区在线视频 | 国产精品免费观看国产网曝瓜 | 国产精品二区在线观看 | 天天操夜夜做 | 国产 在线观看 | 97精品国自产拍在线观看 | 久久国产片 | 蜜臀av性久久久久av蜜臀妖精 | 91精品国产一区二区在线观看 | 国产精品久久久一区二区 | 91av看片 | 久久人人爽人人人人片 | 黄色软件网站在线观看 | 午夜丰满寂寞少妇精品 | 亚洲精品视频免费观看 | 国产精品美女久久久免费 | 国产黄大片| 在线播放亚洲 | 日韩电影在线视频 | 国产高清精品在线 | av黄色免费在线观看 | 成人在线小视频 | 欧美成人影音 | 中文字幕高清在线 | 91看片淫黄大片在线播放 | 在线国产高清 | 国产精品免费久久 | www.狠狠操.com | 欧美在线99| 久综合网| 日韩av一区二区在线 | 2023av| 91香蕉视频 | 国产精品久久久久久久久久久久午夜 | 久久天天躁夜夜躁狠狠85麻豆 | 精品亚洲免a| 黄色a大片| 久久伊99综合婷婷久久伊 | 日韩激情影院 | 免费观看成人 | 91久久国产精品 | 中文字幕黄网 | 成人a免费看 | 天天干夜夜夜 | 久久草网 | 欧洲精品久久久久毛片完整版 | 日韩在线视频精品 | 午夜精品一区二区三区在线 | www视频在线观看 | 99久高清在线观看视频99精品热在线观看视频 | 人人澡人摸人人添学生av | 亚洲激情视频在线 | 日韩在线免费小视频 | 国产啊v在线观看 | 中国一级特黄毛片大片久久 | 8090yy亚洲精品久久 | 国产成人免费观看 | 特级毛片网 | 99精品国产一区二区三区麻豆 | 欧美精品亚洲精品日韩精品 | 99精品在这里 | 黄色大片中国 | 日本一区二区三区免费看 | 婷婷综合五月天 | 国产精品中文字幕在线播放 | 精品免费一区二区三区 | 韩国在线一区二区 | 久久人人爽人人片 | 久久精品日本啪啪涩涩 | 亚洲国产人午在线一二区 | 97色在线视频 | 国产精品区免费视频 | www日韩欧美 | 超碰97网站| 在线黄色观看 | 国内丰满少妇猛烈精品播 | 日韩激情久久 | 亚洲六月丁香色婷婷综合久久 | 日韩在线播放视频 | 97人人超碰在线 | 色婷婷www | 国产专区在线播放 | 午夜精品久久久久99热app | 国产在线观看不卡 | 91大神视频网站 | 青青色影院| 中文亚洲欧美日韩 | 视频成人永久免费视频 | 成人免费一级片 | 国产精品二区在线 | 99视频一区 | 国内综合精品午夜久久资源 | 久久这里只有精品首页 | 91九色精品国产 | a亚洲视频 | 国产精品手机视频 | 久久天天躁夜夜躁狠狠85麻豆 | 奇米影视999| 亚洲色图美腿丝袜 | av成人动漫在线观看 | 国产在线精品一区二区不卡了 | 久久久久久国产精品亚洲78 | 国产网站在线免费观看 | 天天在线操 | 久久久久亚洲精品男人的天堂 | 人人dvd| 中文字幕中文 | 99久久er热在这里只有精品66 | 波多野结衣一区三区 | 一区二区三区在线电影 | 天天操天 | 免费日韩视频 | 欧美怡红院视频 | 成人免费色 | 久久精品99国产精品酒店日本 | 精品国产一区二区三区在线 | 色综合久久五月 | 日韩精品中文字幕在线 | 国产成人av电影 | 日韩av成人在线观看 | 伊人av综合| 视频一区二区三区视频 | 2022久久国产露脸精品国产 | 在线观看日韩视频 | 香蕉视频4aa | 中文字幕乱在线伦视频中文字幕乱码在线 | av在线网站大全 | 91经典在线 | 日韩免费在线观看网站 | 色综合久久久久久久 | 久久 在线| 国产精品毛片一区二区 | 亚洲一区精品人人爽人人躁 | 在线国产激情视频 | 亚洲精品在线播放视频 | 国产午夜精品av一区二区 | 日韩一区二区三 | 亚洲国产精品成人精品 | 日本字幕网 | 97偷拍在线视频 | 97视频在线看 | 日本女人在线观看 | 国产在线探花 | 日韩精品不卡在线观看 | 久草香蕉在线 | 欧美一级高清片 |