Android-View绘制原理(04)-生成Surface

前面View绘制原理中Vsync流程基本上已经分析完毕。前文分析了performTraversals的四个重要流程,第一步就是relayoutWindow,它的作用之一就是为界面生成Surface。本文将详细介绍这个relayoutWindow关于生成Surface的部分原理。

1. SurfaceControl.

这是一个稍微有一点难理解的类,而且的创建过程也非常晦涩。我们来看一下它的原理

首先在ViewRootImpl初始化的时候,就会调用SurfaceControl和Surface的构造函数生成它们的实例
frameworks/base/core/java/android/view/ViewRootImpl.java

    public final Surface mSurface = new Surface();
    private final SurfaceControl mSurfaceControl = new SurfaceControl();

frameworks/base/core/java/android/view/SurfaceControl.java

    public SurfaceControl() {
    }

frameworks/base/core/java/android/view/Surface.java

public Surface() {
    }

这个里虽然生成了Surface和SurfaceControl对象,但是因为它没有生成底层的对应的对象,所以是无效的,还不能用于绘制

2. ViewRootImpl.relayoutWindow.

private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException {
         ...
        int relayoutResult = mWindowSession.relayout(mWindow, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
                mTempControls, mSurfaceSize);
        mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
        if (mSurfaceControl.isValid()) {
            if (!useBLAST()) {
                mSurface.copyFrom(mSurfaceControl);
            } else {
                final Surface blastSurface = getOrCreateBLASTSurface();
                // If blastSurface == null that means it hasn't changed since the last time we
                // called. In this situation, avoid calling transferFrom as we would then
                // inc the generation ID and cause EGL resources to be recreated.
                if (blastSurface != null) {
                    mSurface.transferFrom(blastSurface);
                }
            }
            if (mAttachInfo.mThreadedRenderer != null) {
                if (HardwareRenderer.isWebViewOverlaysEnabled()) {
                    addPrepareSurfaceControlForWebviewCallback();
                    addASurfaceTransactionCallback();
                }
                mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
            }
        } else {
            destroySurface();
        }
    ...
    }

这个方法内部,调用了mWindowSession.relayoutWindow方法,并且传入了mSurfaceControl, 这是一个IPC方法,因为SurfaceControl也实现了Parcelable接口,所以可以跨进程传递。当方法返回来之后,接着判断mSurfaceControl.isValid()

public boolean isValid() {
        return mNativeObject != 0;
    }

就是看看mNativeObject是否为0, 初始化时时空函数,因此肯定为0, 如果此时不为零,它就是在mWindowSession.relayout内赋值了。因此我们来看看mWindowSeesion.relayout作了什么操作。

3 APP与WMS通信

ViewRootImpl有一个mWindowSeesion成员,是构造ViewRootImpl的时候通过调用WindowManagerGlobal.getWindowSession获取的


 public ViewRootImpl(Context context, Display display) {
        this(context, display, WindowManagerGlobal.getWindowSession(),
                false /* useSfChoreographer */);
    }

 public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
            boolean useSfChoreographer) {
        mContext = context;
        mWindowSession = session;
        ...
        }
 @UnsupportedAppUsage
    public static IWindowSession getWindowSession() {
          ...
          IWindowManager windowManager = getWindowManagerService();
          sWindowSession = windowManager.openSession(
                 new IWindowSessionCallback.Stub() {
                    @Override
                         public void onAnimatorScaleChanged(float scale) {
                              ValueAnimator.setDurationScale(scale);
                          }
            });
         
            return sWindowSession;
        }
    }

于是IPC呼叫到到WindowManagerService.openSession方法
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

 @Override
    public IWindowSession openSession(IWindowSessionCallback callback) {
        return new Session(this, callback);
    }

返回一个Session对象,它继承自IWindowSession.Stub ,所以是工作在服务端的实际干活的对象,传送到客户端后,客户端可以获取到句柄并转换成IWindowSession接口,然后远程呼叫这个Session的addToDisplay和relayout等方法, 这些方法内部,会调用WMS的相对应的方法,
frameworks/base/services/core/java/com/android/server/wm/Session.java

class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
@Override
    public int relayout(IWindow window, WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
            ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
      
        ...
        int res = mService.relayoutWindow(this, window, attrs,
                requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
                outActiveControls, outSurfaceSize);
         ....
        return res;
    }
   ...
 }

4. WindowManagerService

WindnowManagerServicec初始化的时候会和SurfaceFlinger服务建立会话,这样后面就可以直接调用SurfaceFlinger的方法。

frameworks/base/core/java/android/view/ViewRootImpl.java

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
            int userId) {
                   ...
                    
                  res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(), userId,
                            mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
                            mTempControls);
                  ...
   }

这是上面介绍过的App与WMS的远程调用
frameworks/base/services/core/java/com/android/server/wm/Session.java

 @Override
    public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
            int viewVisibility, int displayId, InsetsState requestedVisibility,
            InputChannel outInputChannel, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls) {
        return mService.addWindow(this, window, attrs, viewVisibility, displayId,
                UserHandle.getUserId(mUid), requestedVisibility, outInputChannel, outInsetsState,
                outActiveControls);
    }

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
            int displayId, int requestUserId, InsetsState requestedVisibility,
            InputChannel outInputChannel, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls) {
           ...
           final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);    
           ...
    }
private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) {
        if (token != null) {
            final WindowToken wToken = mRoot.getWindowToken(token);
            if (wToken != null) {
                return wToken.getDisplayContent();
            }
        }

        return mRoot.getDisplayContentOrCreate(displayId);
    }

调用RootWindowContainer创建一个DisplayContent,并调用addChild将其加入到RootWindowContainer的下一级。
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

DisplayContent getDisplayContentOrCreate(int displayId) {
        DisplayContent displayContent = getDisplayContent(displayId);
        if (displayContent != null) {
            return displayContent;
        }
       ...
        displayContent = new DisplayContent(display, this);
        addChild(displayContent, POSITION_BOTTOM);
        return displayContent;
    }

DisplayContent有一个成员变量mSession是SurfaceSession类型,它是在申明时初始化的,因此调用构造函数即可以初始化mSession,它就代表和SurfaceFlinger的会话。它实际持有一个mNativeClient指针,指向一个SurfaceComposerClient对象,即SurfaceFlinger的客户端。
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
      ...
      private final SurfaceSession mSession = new SurfaceSession();
      ...
}

frameworks/base/core/java/android/view/SurfaceSession.java

public final class SurfaceSession {
  
    private long mNativeClient; // SurfaceComposerClient*

    private static native long nativeCreate();
    private static native void nativeDestroy(long ptr);

  
    public SurfaceSession() {
        mNativeClient = nativeCreate();
   }

frameworks/base/core/jni/android_view_SurfaceSession.cpp

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

frameworks/native/libs/gui/SurfaceComposerClient.cpp

SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT)
{
}

SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
    : mStatus(NO_ERROR), mClient(client)
{
}

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

到这里就生成了一个SurfaceComposerClient对象,通过这个对象可以和ComposerService的实现者SurfaceFlinger通信,并调用了createConnection这个远程函数来创建一个连接conn后赋值给mClient。生成的这个SurfaceComposerClient的指针返回给JAVA层,保存在SurfaceSession.mNativeClient.

到这里就具备了和SurfaceFlinger通信的能力。

5 创建SurfaceControl

在ViewRootImpl里面构造了一个SurfaceControl,但是它只是一个空白的对象,不能使用,现在来看看有效的SurfaceControl是怎么生成的。我们把app远程调用部分省略了,直接进入到WMS的relayoutWindow方法,它的内容非常多,这里仅仅介绍一下创建SurfaceControl的逻辑

public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
        ...
        synchronized (mGlobalLock) {
            final WindowState win = windowForClientLocked(session, client, false);
           ...
            win.setViewVisibility(viewVisibility);
           ...
            if (shouldRelayout) {
                try {
                    result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
                }
            }
           ...
        return result;
    }

首先找到这个WindowState对象(它在WMS代表一个window,在次之前,已经通过session.addToDisplay添加进来),然后调用createSurfaceControl方法来创建一个WindowSurfaceController对象

private int createSurfaceControl (SurfaceControl outSurfaceControl, int result,
            WindowState win, WindowStateAnimator winAnimator) {
      
            WindowSurfaceController surfaceController;
            ...
            surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
           ...
            surfaceController.getSurfaceControl(outSurfaceControl);
            ....
            return result;
    }

内部调用winAnimator来创建一个WindowSurfaceController对象,然后,将该对象复制给outSurfaceControl,而这个outSurfaceControl就是ViewRootImpl中创建的对象。此后,ViewRootImpl的mSurfaceControl变成有效可用。 但是如何生成这个可用对象的,还需要继续分析。

 WindowSurfaceController createSurfaceLocked(int windowType) {
        ...
        mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
                    height, format, flags, this, windowType);
        return mSurfaceController;
    }

生成WindowSurfaceController返回给回去。在构造这个对象时,内部会生成一个新的SurfaceControl
frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java

WindowSurfaceController(String name, int w, int h, int format,
            int flags, WindowStateAnimator animator, int windowType) {
      ...
        final SurfaceControl.Builder b = win.makeSurface()
                .setParent(win.getSurfaceControl())
                .setName(name)
                .setBufferSize(w, h)
                .setFormat(format)
                .setFlags(flags)
                .setMetadata(METADATA_WINDOW_TYPE, windowType)
                .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
                .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
                .setCallsite("WindowSurfaceController");

        final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
                & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);

        if (useBLAST) {
            b.setBLASTLayer();
        }

        mSurfaceControl = b.build();
    }

这里调用WindowState生成了一个SurfaceControl.Builder ,通过它的build来生成SurfaceControl,但是逻辑有一点绕:

SurfaceControl.Builder makeSurface() {
        final WindowContainer p = getParent();
        return p.makeChildSurface(this);
    }
    
SurfaceControl.Builder makeChildSurface(WindowContainer child) {
        final WindowContainer p = getParent();
        // Give the parent a chance to set properties. In hierarchy v1 we rely
        // on this to set full-screen dimensions on all our Surface-less Layers.
        return p.makeChildSurface(child)
                .setParent(mSurfaceControl);
    }

这里存在多态的情况.win的类型是WindowState,它继承自WindowContainer,它调用getParent返回的也是一个WindowContainer,好像会无限循环找到根,但是因为在父容器里有一级是我们上面分析过的DisplayContent,它重写了makeChildSurface方法
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

SurfaceControl.Builder makeChildSurface(WindowContainer child) {
        SurfaceSession s = child != null ? child.getSession() : getSession();
        final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();
        if (child == null) {
            return b;
        }

        return b.setName(child.getName())
                .setParent(mSurfaceControl);
    }

在这里它阻断了这个递归,并且调用了mWmService.makeSurfaceBuilder(s)来生成Builder对象。 这个DisplayContent我们上面也介绍过,它持有一个SurfaceSession成员,这里正好用它来生成SurfaceControl。生成了Builder之后调用build生成SurfaceControl对象。
frameworks/base/core/java/android/view/SurfaceControl.java

public SurfaceControl build() {
           ...
            if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
                setBLASTLayer();
            }

            return new SurfaceControl(
                    mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
                    mLocalOwnerView, mCallsite);
        }

这里调用的构造方法和ViewRootImpl中调用的不同,传了非常多的参数包括用于和SurfaceFling通信的session,生成layer类型的flags等,这表示它将生成一个有效的SurfaceControl。

private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
            SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
            String callsite) {
        ...
        mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, metaParcel);
        ...
        mNativeHandle = nativeGetHandle(mNativeObject);
        mCloseGuard.openWithCallSite("release", callsite);
    }

这里会进入到了SurfaceControl的JNI层
frameworks/base/core/jni/android_view_SurfaceControl.cpp

static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
        jobject metadataParcel) {
   
    sp<SurfaceControl> surface;
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        client = SurfaceComposerClient::getDefault();
    }
    ...
    status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, flags, parentHandle, std::move(metadata));
    
    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());
}

nativeCreate的参数sessionOb是一个SurfaceSession,它来自DisplayContent,在其初始化时生成了这个对象,并连接SurfaceFlinger创建回话。
这里先调用 android_view_SurfaceSession_getClient(env, sessionObj)获取到SurfaceSession对象client,它是一个SurfaceComposerClient类型的对象,然后在调用它的createSurfaceChecked方法,

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;
    sp<IBinder> handle;
    sp<IGraphicBufferProducer> gbp;
       ...
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata), &handle, &gbp, &id, &transformHint);
        ...
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}

于是就远程呼叫Client的createSurface方法,同时会传入一个handle的地址,这个handle将存放即将创建的Layer的handle,以及gbp的地址用于保存producer。最后经这个handle为参数,构造SurfaceControl对象。也就是说SurfaceControl的handle是指向一个Layer的handle。在JAVA层,SurfaceControl的构造方法调用nativeCreate之后,也调用了nativeGetHandle方法,就是来获取Layer的handle指针,并保存到JAVA层的mNativeHandle

 mNativeObject = nativeCreate(session, name, w, h, format, flags,
                    parent != null ? parent.mNativeObject : 0, metaParcel);
static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
    SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
    return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
}

接着我们继续看看mClient->createSurface是如何生成Layer的。
frameworks/native/services/surfaceflinger/Client.cpp

status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
                               uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle, outLayerId, nullptr, outTransformHint);
}

进一步调用mFlinger->createLayer

status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle, int32_t* outLayerId,
                                     const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
    ...
    status_t result = NO_ERROR;

    sp<Layer> layer;

    std::string uniqueName = getUniqueLayerName(name.string());

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
        case ISurfaceComposerClient::eFXSurfaceBufferState: {
            result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,  std::move(metadata), handle, &layer);
           ...
        } break;
        case ISurfaceComposerClient::eFXSurfaceEffect:
           
            result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
                                       std::move(metadata), handle, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceContainer:
            result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
                                          std::move(metadata), handle, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

    bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,
                            outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }
    mInterceptor->saveSurfaceCreation(layer);

    setTransactionFlags(eTransactionNeeded);
    *outLayerId = layer->sequence;
    return result;
}

上层创建一个SurfaceConftrol实质上是在SurfaceFlinger创建一个Layer,这里会根据Layer的flag生成不同的Layer,通常情况传入的flag包含的是eFXSurfaceBufferState(blast)这个位开关。因此将进入createBufferStateLayer这个方法:

status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, sp<IBinder>* handle,
                                                sp<Layer>* outLayer) {
    LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
    args.textureName = getNewTexture();
    sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
    *handle = layer->getHandle();
    *outLayer = layer;

    return NO_ERROR;
}

这里调用getFactory().createBufferStateLayer()去创建,创建完之后即那个layer的handler赋值给handle,layer赋值为outLayer。
这样就构造好了Layer,并返回回去。
frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

sp<BufferStateLayer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
    return new BufferStateLayer(args);
}

frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp

BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}

BufferQueueLayer::~BufferQueueLayer() {
    mContentsChangedListener->abandon();
    mConsumer->abandon();
}

继承自BufferLayer, frameworks/native/services/surfaceflinger/BufferLayer.cpp


BufferLayer::BufferLayer(const LayerCreationArgs& args)
      : Layer(args),
        mTextureName(args.textureName),
        mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {
    ALOGV("Creating Layer %s", getDebugName());

    mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);

    mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
    mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
}

继承自Layer frameworks/native/services/surfaceflinger/Layer.cpp

Layer::Layer(const LayerCreationArgs& args)
      : mFlinger(args.flinger),
        mName(args.name),
        mClientRef(args.client),
        mWindowType(static_cast<InputWindowInfo::Type>(
                args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
    
    ...
}

void Layer::onFirstRef() {
    mFlinger->onLayerFirstRef(this);
}

引用到Layer的时候,会调用mFlinger->onLayerFirstRef(this);

void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
    mNumLayers++;
    if (!layer->isRemovedFromCurrentState()) {
        mScheduler->registerLayer(layer);
    }
}

再调用mScheduler->registerLayer(layer)
frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp

void Scheduler::registerLayer(Layer* layer) {
    scheduler::LayerHistory::LayerVoteType voteType;
       ...
        voteType = scheduler::LayerHistory::LayerVoteType::Heuristic;
    }
    mLayerHistory->registerLayer(layer, voteType);
}

frameworks/native/services/surfaceflinger/Scheduler/LayerHistory.cpp

void LayerHistory::registerLayer(Layer* layer, LayerVoteType type) {
    std::lock_guard lock(mLock);
    for (const auto& info : mLayerInfos) {
        LOG_ALWAYS_FATAL_IF(info.first == layer, "%s already registered", layer->getName().c_str());
    }
    auto info = std::make_unique<LayerInfo>(layer->getName(), layer->getOwnerUid(), type);
    mLayerInfos.emplace_back(layer, std::move(info));
}

将生成layer记录到历史。

当Layer创建好了之后,会去获取这个Layer的handle

sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);
    if (mGetHandleCalled) {
        ALOGE("Get handle called twice" );
        return nullptr;
    }
    mGetHandleCalled = true;
    return new Handle(mFlinger, this);
}

frameworks/native/services/surfaceflinger/Layer.h

 class Handle : public BBinder, public LayerCleaner {
    public:
        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
              : LayerCleaner(flinger, layer, this), owner(layer) {}
        const String16& getInterfaceDescriptor() const override { return kDescriptor; }

        static const String16 kDescriptor;
        wp<Layer> owner;
    };

这handle里保存了surface 和 layer的引用,它也是一个IBinder类型的对象。

到这里SurfaceControl的nativeCreate方法就结束了,它通过SurfaceSession连接SurfaceFlingger,然后远程呼叫SurfaceFlinger创建一个Client连接,之后远程调用这个client的createLayer方法,进而调用到SurfaceFlinger的Factory创建一个BufferQueueLayer对象,然后将这个Layer的handle赋值到surfacecontrol.handle指针,然后将surfacecontrol的指针至返回到JAVA层,保存到SurfaceControl的mNativeObject。

至此创建有效的SurfaceControl的流程结束,它在SurfaceFlinger端创建了一个Layer,并在surfaceControl中保存了这个Layer的远程句柄。

6. BLASTBufferQueue

如果mWindowSession.relayout之后,mSurfaceControl将会变成有效的,此时会判断blast是否开启(blast特性时12新推出的,它默认开启的),所以进入到getOrCreateBLASTSurface,在这里将会生成一个BLASTBufferQueue, 。而原来的 mSurface.copyFrom(mSurfaceControl),我们将在最后来对比分析一下。

private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
           ...
        int relayoutResult = mWindowSession.relayout(mWindow, ..., mSurfaceControl, ...);
      
        if (mSurfaceControl.isValid()) {
            if (!useBLAST()) {
                mSurface.copyFrom(mSurfaceControl);
            } else {
                final Surface blastSurface = getOrCreateBLASTSurface();
                ...
                if (blastSurface != null) {
                    mSurface.transferFrom(blastSurface);
                }
            }
           ...
    }
Surface getOrCreateBLASTSurface() {
        if (!mSurfaceControl.isValid()) {
            return null;
        }

        Surface ret = null;
        if (mBlastBufferQueue == null) {
            mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y,
                mWindowAttributes.format);
            // We only return the Surface the first time, as otherwise
            // it hasn't changed and there is no need to update.
            ret = mBlastBufferQueue.createSurface();
        } else {
            mBlastBufferQueue.update(mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y,
                mWindowAttributes.format);
        }

        return ret;
    }

如果mBlastBufferQueue == null,则传入mSurfaceControl新创建一个mBlastBufferQueue,然后调用这个 BufferQueue.createSurface()来创建一个Surface;如果已经存在了,则进行更新操作mBlastBufferQueue.update(mSurfaceControl,...)。分析一下这个create的逻辑
frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java

public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
            @PixelFormat.Format int format) {
        mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
    }

构造方法调用nativeCreate创建底层数据,它传入了sc.mNativeObject,,在JNI层就可通过这个指针访问这个SurfaceControl对象
frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp

static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
                          jlong width, jlong height, jint format) {
    ...
    std::string name = str8.string();
    sp<BLASTBufferQueue> queue =
            new BLASTBufferQueue(name, reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format);
    queue->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(queue.get());
}

nativeCreate函数将surfaceControl指针转换成SurfaceControl*指针,然后以此为参数生成了一个BLASTBufferQueue的对象queue,然后返回这个queue的指针给JAVA层并保存在mNativeObject。所以在JAVA层,BLASTBufferQueue的mNativeObject实质是指向一个BLASTBufferQueue对象,其持有一个SurfaceControl。
frameworks/native/libs/gui/BLASTBufferQueue.cpp

BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
                                   int width, int height, int32_t format)
      : mSurfaceControl(surface),
      ...{
    createBufferQueue(&mProducer, &mConsumer);  
     ...
    // safe default, most producers are expected to override this
    mProducer->setMaxDequeuedBufferCount(2);
    ...
}

createBufferQueue,并且传入了mProducer和mConsumer的地址,表示这个方法在内容生成对应的对象,并将值用这个两个指针指向他们。

void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                                         sp<IGraphicBufferConsumer>* outConsumer) {
    LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BLASTBufferQueue: outProducer must not be NULL");
    LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BLASTBufferQueue: outConsumer must not be NULL");

    sp<BufferQueueCore> core(new BufferQueueCore());
    LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");

    sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));
    LOG_ALWAYS_FATAL_IF(producer == nullptr,
                        "BLASTBufferQueue: failed to create BBQBufferQueueProducer");

    sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
    consumer->setAllowExtraAcquire(true);
    LOG_ALWAYS_FATAL_IF(consumer == nullptr,
                        "BLASTBufferQueue: failed to create BufferQueueConsumer");

    *outProducer = producer;
    *outConsumer = consumer;
}

首先生成一个BufferQueueCore对象core,然后以这个core分别生成producer和consumer。最后将producer和consumer存入的指针指向他们。
这个core相当于一个容器,里面管理存放buffer,producer和consuer都持有这个core,这就是一个典型的生产者-消费者模型,core就是缓存仓库

BBQBufferQueueProducer继承自BufferQueueProducer,间接就继承自BnGraphicBufferProducer 说明它工作在服务端,是真正干活的对象。它是buffer的生产者,它会从core中取空闲的buffer出来绘制,绘制完后再放回去core。即dequeueBuffer 和queueBuffer 两个方法。
frameworks/native/libs/gui/BLASTBufferQueue.cpp

class BBQBufferQueueProducer : public BufferQueueProducer {
public:
    BBQBufferQueueProducer(const sp<BufferQueueCore>& core)
          : BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/) {}

frameworks/native/libs/gui/include/gui/BufferQueueProducer.h

class BufferQueueProducer : public BnGraphicBufferProducer {

frameworks/native/libs/gui/BufferQueueProducer.cpp

BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
        bool consumerIsSurfaceFlinger) :
    mCore(core),
    mSlots(core->mSlots),
   ...

再来看看消费者,它是继承自BnGraphicBufferConsumer,因此也是工作的服务端直接干活的对象
frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h

class BufferQueueConsumer : public BnGraphicBufferConsumer {

frameworks/native/libs/gui/BufferQueueConsumer.cpp

BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
   mCore(core),
   mSlots(core->mSlots),
   mConsumerName() {}

这里的producer和consumer同时依赖core这个仓库,并直接操作它的slots。consumer的主要方法就是acquireBuffer和releaseBuffer。

到这里ViewRootImpl的mBlastBufferQueue就初始化完成了。

7. BBQSurface

生成了BLASTBufferQueue之后会调用createSurface或者update来创建或者更新surface。我们来看一下createSurface的流程
frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java

public Surface createSurface() {
        return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
    }

直接进入JNI 的nativeGetSurface函数
frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp

static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr,
                                jboolean includeSurfaceControlHandle) {
    sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
    return android_view_Surface_createFromSurface(env,
                                                  queue->getSurface(includeSurfaceControlHandle));
}

通过传入的ptr指针转换成BLASTBufferQueue对象queue,然后调用getSurface方法
frameworks/native/libs/gui/BLASTBufferQueue.cpp

sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
    std::unique_lock _lock{mMutex};
    sp<IBinder> scHandle = nullptr;
    if (includeSurfaceControlHandle && mSurfaceControl) {
        scHandle = mSurfaceControl->getHandle();
    }
    return new BBQSurface(mProducer, true, scHandle, this);
}

此处的参数includeSurfaceControlHandle == flase,所以scHandle为null,然后传入mProducer生成一个BBQSurface

class BBQSurface : public Surface {
private:
    std::mutex mMutex;
    sp<BLASTBufferQueue> mBbq;
    bool mDestroyed = false;

public:
    BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
               const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
          : Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {
          ...
    }
};

Surface是继承自ANativeWindow,代表一个nativewindow,它的定义在如下,这种继承关系表达有一些费解。

class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>

构造方法:

Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp, const sp<IBinder>& surfaceControlHandle)
      : mGraphicBufferProducer(bufferProducer),
       ...{
    ...
    mSurfaceControlHandle = surfaceControlHandle;
}

可以看到构建的Surface其实是它的子类BBQSurface,这里传入参数controledByApp == true,说明它是由APP自己控制的,surfaceControlHandle == nullptr, 同时接受一个producer,说这Surface的角色是producer,由surface来产生buffer数据。 surface的dequeueBuffer和enqueueBuffer最终会调用到producer对应的方法。

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ...
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,
                                                            dqInput.height, dqInput.format,
                                                            dqInput.usage, &mBufferAge,
                                                            dqInput.getTimestamps ?
                                                                    &frameTimestamps : nullptr);
    ...
}

int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
    ...
    status_t result = mGraphicBufferProducer->dequeueBuffers(dequeueInput, &dequeueOutput);
    ...
}

具体的逻辑就不在详细展开。我需要记住的是如何生成者个Surface对象,它实质上是一个BBQSurface,代表者生产者。最后通过调用一个JNI函数android_view_Surface_createFromSurface来获构建一个Surface个对象,返回给JAVA层。

jobject android_view_Surface_createFromSurface(JNIEnv* env, const sp<Surface>& surface) {
    jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz,
            gSurfaceClassInfo.ctor, (jlong)surface.get());
    if (surfaceObj == NULL) {
        if (env->ExceptionCheck()) {
            ALOGE("Could not create instance of Surface from IGraphicBufferProducer.");
            LOGE_EX(env);
            env->ExceptionClear();
        }
        return NULL;
    }
    surface->incStrong(&sRefBaseOwner);
    return surfaceObj;
}
 gSurfaceClassInfo.ctor = GetMethodIDOrDie(env, gSurfaceClassInfo.clazz, "<init>", "(J)V");

这里将反射调用Surface的私有构造方法:并将BBQSurface的指针保存到Surface.mNativeObject.
frameworks/base/core/java/android/view/Surface.java

private Surface(long nativeObject) {
        synchronized (mLock) {
            setNativeObjectLocked(nativeObject);
        }
    }

创建好这个Surface之后,需要将它保存到ViewRootImpl的mSurface中去,可以理解为将blastSurface的nativeObject赋值给mSurface

if (blastSurface != null) {
      mSurface.transferFrom(blastSurface);
}

8. 不开启Blast的情况.

虽然现在默认是开始blast的,但是我们也可以分析一下不开始blast的情况,它调用的是一个copyFrom方法,从mSurfaceControl中来创建一个surface。

 if (!useBLAST()) {
          mSurface.copyFrom(mSurfaceControl);
}

frameworks/base/core/java/android/view/Surface.java

public void copyFrom(SurfaceControl other) {
        if (other == null) {
            throw new IllegalArgumentException("other must not be null");
        }

        long surfaceControlPtr = other.mNativeObject;
        if (surfaceControlPtr == 0) {
            throw new NullPointerException(
                    "null SurfaceControl native object. Are you using a released SurfaceControl?");
        }
        long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
        updateNativeObject(newNativeObject);
    }

这个里通过调用一个native方法nativeGetFromSurfaceControl返回一个surface的指针给上层保存,然后将新的newNativeObject保存到mNativeObject, 从而完成创建。我们看一下这个native方法.

static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong nativeObject,
        jlong surfaceControlNativeObj) {
    Surface* self(reinterpret_cast<Surface *>(nativeObject));
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));

    // If the underlying IGBP's are the same, we don't need to do anything.
    if (self != nullptr &&
            IInterface::asBinder(self->getIGraphicBufferProducer()) ==
            IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {
        return nativeObject;
    }

    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }

    return reinterpret_cast<jlong>(surface.get());
}

入参有一个surfaceControlNativeObj,获取到它指向的SurfaceControl对象,然后调用它的getSurface方法返回一个surface
frameworks/native/libs/gui/SurfaceControl.cpp

sp<Surface> SurfaceControl::getSurface()
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == nullptr) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}
sp<Surface> SurfaceControl::generateSurfaceLocked()
{
    uint32_t ignore;
    auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
                                 ISurfaceComposerClient::eOpaque);
    mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
                                       flags, mHandle, {}, &ignore);
    mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);

    // This surface is always consumed by SurfaceFlinger, so the
    // producerControlledByApp value doesn't matter; using false.
    mSurfaceData = mBbq->getSurface(true);

    return mSurfaceData;
}

这个再其次调用了mClient->createSurface,这个mClient是一个SurfaceComposerClient对象,这个前面分析过,它将与SurfaceFlinger的Client进行远程通信。
frameworks/native/services/surfaceflinger/Client.cpp

status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
                               uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle, outLayerId, nullptr, outTransformHint);
}

但是这里调用的方法直接返回一个对象赋给mBbqChild,而mBbqChild是一个SurfaceControl类型的成员。因此不是单纯的IPC调用。看看定义:

sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
                                                        PixelFormat format, uint32_t flags,
                                                        const sp<IBinder>& parentHandle,
                                                        LayerMetadata metadata,
                                                        uint32_t* outTransformHint) {
    sp<SurfaceControl> s;
    createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),
                         outTransformHint);
    return s;
}

原来是调用createSurfaceChecked,它内部生成了一个SurfaceControl,保存到s然后返回。

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;

        uint32_t transformHint = 0;
        int32_t id = -1;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &id, &transformHint);

        if (outTransformHint) {
            *outTransformHint = transformHint;
        }
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}

所以又生成了一个新的SurfaceControl返回回去
然后生成一个BLASTBufferQueue,之后再调用它的getSurface来创建surface,但是传入的参数是true

mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);

    // This surface is always consumed by SurfaceFlinger, so the
    // producerControlledByApp value doesn't matter; using false.
    mSurfaceData = mBbq->getSurface(true);
p<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
    std::unique_lock _lock{mMutex};
    sp<IBinder> scHandle = nullptr;
    if (includeSurfaceControlHandle && mSurfaceControl) {
        scHandle = mSurfaceControl->getHandle();
    }
    return new BBQSurface(mProducer, true, scHandle, this);
}

此时的includeSurfaceControlHandle == true,mSurfaceControl 是上面创建的child。因此scHandle是指向Layer的Handle,然后生成的BBQSurface也将持有该Handle。

9. 总结

  • 通过分析APP与WMS和SurfaceFlinger的IPC通信,详细介绍了创建SurfaceControl以及Surface的流程
  • SurfaceControl持有SurfaceFlinger进程中创建的Layer的handle
  • Surface是通过BlastBufferQueue生成的一个BBQSurface,它继承自Surface,Surface是ANativeWindow的子类,它持有一个生产者,主要有dequeueBuffer和enqueueBuffer方法。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,468评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,620评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,427评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,160评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,197评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,334评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,775评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,444评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,628评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,459评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,508评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,210评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,767评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,850评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,076评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,627评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,196评论 2 341

推荐阅读更多精彩内容