乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Layer Tree 創(chuàng)建

       wusiqi111 2019-10-29

      站在老羅的肩膀上:https://blog.csdn.net/luoshengyang/article/details/50941980

      網(wǎng)頁的Graphics Layer Tree是根據(jù)Paint Layer Tree創(chuàng)建的,而Graphics Layer Tree與CC模塊創(chuàng)建的Layer Tree的節(jié)點(diǎn)是一一對(duì)應(yīng)的關(guān)系,如圖1所示:

      圖1 Graphics Layer Tree與CC Layer Tree的關(guān)系

           也就是說,每一個(gè)Graphics Layer都對(duì)應(yīng)有一個(gè)CC Layer。不過,Graphics Layer與CC Layer不是直接的一一對(duì)應(yīng)的,它們是透過另外兩個(gè)Layer才對(duì)應(yīng)起來的,如圖2所示:

      圖2 Graphics Layer與CC Layer的對(duì)應(yīng)關(guān)系

             中間的兩個(gè)Layer分別是WebContentLayerImpl和WebLayerImpl,它們是屬于Content層的對(duì)象。Graphics Layer與CC Layer的對(duì)應(yīng)關(guān)系,是在Graphics Layer的創(chuàng)建過程中建立起來的,接下來我們就通過源碼分析這種對(duì)應(yīng)關(guān)系的建立過程。

      GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client)
          : client_(client),
            ... {
        ...
        layer_ = cc::PictureLayer::Create(this);
        layer_->SetIsDrawable(draws_content_ && contents_visible_);
        layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr());
      }                                                    
      

      Graphics Layer通過GraphicsLayer::AddChild形成父子關(guān)系的(從而形成Graphics Layer Tree),如下所示:

      void GraphicsLayer::AddChild(GraphicsLayer* child_layer) {
        AddChildInternal(child_layer);
        UpdateChildList();
      }

      首先調(diào)用成員函數(shù)AddChildInternal將參數(shù)childLayer描述的一個(gè)Graphics Layer作為當(dāng)前正在處理的Graphics Layer的子Graphics Layer,如下所示: 

      void GraphicsLayer::AddChildInternal(GraphicsLayer* child_layer) {
        ...  if (child_layer->Parent())
          child_layer->RemoveFromParent();
      
        child_layer->SetParent(this);
        children_.push_back(child_layer);
      }

      這一步執(zhí)行完成后,Graphics Layer之間就建立了父子關(guān)系?;氐紾raphicsLayer類的成員函數(shù)AddChild中,它接下來還會(huì)調(diào)用另外一個(gè)成員函數(shù)UpdateChildList,用來在CC Layer之間建立父子關(guān)系,從而形CC Layer Tree。

      void GraphicsLayer::UpdateChildList() {  // child_host point to PictureLayer
        cc::Layer* child_host = layer_.get();
        child_host->RemoveAllChildren();
      
        ...  for (size_t i = 0; i < children_.size(); ++i)
          child_host->AddChild(children_[i]->CcLayer());  for (size_t i = 0; i < link_highlights_.size(); ++i)
          child_host->AddChild(link_highlights_[i]->Layer());
      }

      其中child_host指向的是當(dāng)前Graphics Layer對(duì)應(yīng)的一個(gè)PictureLayer對(duì)象,并把它所有的Child Graphics Layer對(duì)應(yīng)的PictureLayer調(diào)用AddChild添加到它的子節(jié)點(diǎn),AddChild調(diào)用InsertChild實(shí)現(xiàn)如下

      void Layer::AddChild(scoped_refptr<Layer> child) {
        InsertChild(child, inputs_.children.size());
      }
      
      
      void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) {
        DCHECK(IsPropertyChangeAllowed());
        child->RemoveFromParent();
        AddDrawableDescendants(child->NumDescendantsThatDrawContent() +
                               (child->DrawsContent() ? 1 : 0));
        child->SetParent(this);
        child->SetSubtreePropertyChanged();
      
        index = std::min(index, inputs_.children.size());
        inputs_.children.insert(inputs_.children.begin() + index, child);
        SetNeedsFullTreeSync();
      }

      Layer類的成員函數(shù)InsertChild所做的第一件事情是將當(dāng)前正在處理的Picture Layer設(shè)置為參數(shù)child描述的Pictrue Layer的父Picture Layer,并且將參數(shù)child描述的Pictrue Layer保存在當(dāng)前正在處理的Picture Layer的子Picture Layer列表中。Layer類的成員函數(shù)InsertChild所做的第二件事情是調(diào)用另外一個(gè)成員函數(shù)SetNeedsFullTreeSync發(fā)出一個(gè)通知,要在CC Layer Tree與CC Pending Layer Tree之間做一個(gè)Tree結(jié)構(gòu)同步。

            Layer類的成員函數(shù)SetNeedsFullTreeSync的實(shí)現(xiàn)如下所示:

      void Layer::SetNeedsFullTreeSync() {  if (!layer_tree_host_)    return;
      
        layer_tree_host_->SetNeedsFullTreeSync();
      }void LayerTreeHost::SetNeedsFullTreeSync() {
        needs_full_tree_sync_ = true;
        property_trees_.needs_rebuild = true;
        SetNeedsCommit();
      }

      Layer類的成員變量layer_tree_host_指向的是一個(gè)LayerTreeHost對(duì)象,用來管理CC Layer Tree的。Layer類的成員函數(shù)SetNeedsFullTreeSync所做的事情就是調(diào)用這個(gè)LayerTreeHost對(duì)象的成員函數(shù)SetNeedsFullTreeSync通知它CC Layer Tree結(jié)構(gòu)發(fā)生了變化,需要將這個(gè)變化同步到CC Pending Layer Tree中去。

             這一步執(zhí)行完成之后,就可以在CC模塊中得到一個(gè)Layer Tree,這個(gè)Layer Tree與Blink中的Graphics Layer Tree在結(jié)構(gòu)上是完全同步的,并且這個(gè)同步過程是由Blink控制的。這個(gè)同步過程之所以要由Blink控制,是因?yàn)镃C Layer Tree是根據(jù)Graphics Layer Tree創(chuàng)建的,而Graphics Layer Tree又是由Blink管理的。

             Blink現(xiàn)在還需要做的另外一件重要的事情是告訴CC模塊,哪一個(gè)Picture Layer是CC Layer Tree的根節(jié)點(diǎn),這樣CC模塊才可以對(duì)整個(gè)CC Layer Tree進(jìn)行管理。Blink會(huì)在創(chuàng)建Graphics Layer Tree的根節(jié)點(diǎn)的時(shí)候,將該根節(jié)點(diǎn)對(duì)應(yīng)的Picture Layer設(shè)置到CC模塊中去,以便后者將其作為CC Layer Tree的根節(jié)點(diǎn)。

             Graphics Layer Tree的根節(jié)點(diǎn)是什么時(shí)候創(chuàng)建的呢?從前面Chromium網(wǎng)頁加載過程簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃這個(gè)系列的文章可以知道,Graphics Layer Tree的根節(jié)點(diǎn)對(duì)應(yīng)于Paint Layer Tree的根節(jié)點(diǎn),Paint Layer Tree的根節(jié)點(diǎn)又對(duì)應(yīng)于Layout Object Tree的根節(jié)點(diǎn),因此我們就從Layout Object Tree的根節(jié)點(diǎn)的創(chuàng)建過程開始,分析Graphics Layer Tree的根節(jié)點(diǎn)的創(chuàng)建過程。

            Document調(diào)用SetStyle給Layout Object Tree的節(jié)點(diǎn)設(shè)置CSS屬性,RebuildLayoutTree會(huì)創(chuàng)建相應(yīng)的Layout Layer。在設(shè)置Paint Layer Tree的根節(jié)點(diǎn)的CSS屬性的過程中,會(huì)觸發(fā)Graphics Layer Tree的根節(jié)點(diǎn)的創(chuàng)建,因此接下來我們繼續(xù)分析Paint Layer類的成員函數(shù)StyleDidChange的實(shí)現(xiàn),如下所示:

      void PaintLayer::StyleDidChange(StyleDifference diff,                                const ComputedStyle* old_style) {
        UpdateScrollableArea();  if (AttemptDirectCompositingUpdate(diff, old_style))    return;  if (PaintLayerStackingNode::StyleDidChange(this, old_style))
          MarkAncestorChainForDescendantDependentFlagsUpdate();
        ...
      }
      bool PaintLayerStackingNode::StyleDidChange(PaintLayer* paint_layer,                                            const ComputedStyle* old_style) {
        ...  // Need to force requirements update, due to change of stacking order.
        paint_layer->SetNeedsCompositingRequirementsUpdate();
        DirtyStackingContextZOrderLists(paint_layer);  if (paint_layer->StackingNode()) {    if (should_be_stacking_context)
            paint_layer->StackingNode()->DirtyZOrderLists();    else
            paint_layer->StackingNode()->ClearZOrderLists();
        }  if (was_stacked != should_be_stacked) {    if (!paint_layer->GetLayoutObject().DocumentBeingDestroyed() &&
              !paint_layer->IsRootLayer() && paint_layer->Compositor()) {
            paint_layer->Compositor()->SetNeedsCompositingUpdate(
                kCompositingUpdateRebuildTree);
          }
        }  return true;
      }

      在從非Stacking Context變?yōu)镾tacking Context的情況下,DirtyStackingContextZOrderLists將Stacking Context標(biāo)記為Dirty狀態(tài),這樣以后在需要的時(shí)候就會(huì)根據(jù)該Stacking Context的子元素的z-index重新構(gòu)建Graphics Layer Tree。

      void PaintLayerStackingNode::DirtyStackingContextZOrderLists(
          PaintLayer* layer) {  if (PaintLayerStackingNode* stacking_node =
                AncestorStackingContextNode(layer))
          stacking_node->DirtyZOrderLists();
      }
      
      
      void PaintLayerStackingNode::DirtyZOrderLists() {  if (pos_z_order_list_)
          pos_z_order_list_->clear();  if (neg_z_order_list_)
          neg_z_order_list_->clear();
        z_order_lists_dirty_ = true;  if (!Layer()->GetLayoutObject().DocumentBeingDestroyed() && Compositor())
          Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
      }
      
      
      void PaintLayerCompositor::SetNeedsCompositingUpdate(
          CompositingUpdateType update_type) {
        DCHECK_NE(update_type, kCompositingUpdateNone);
        pending_update_type_ = std::max(pending_update_type_, update_type);  if (Page* page = GetPage())
          page->Animator().ScheduleVisualUpdate(layout_view_.GetFrame());
        Lifecycle().EnsureStateAtMost(DocumentLifecycle::kLayoutClean);
      }

      DirtyZOrderLists首先是將用來保存子元素的兩個(gè)列表清空。其中一個(gè)列表用來保存z-index為正數(shù)的子元素,另一個(gè)列表用來保存z-index為負(fù)數(shù)的子元素。這些子元素在各自的列表中均是按照從小到大的順序排列的。有了這個(gè)順序之后,Graphics Layer Tree就可以方便地按照z-index順序創(chuàng)建出來。接下來將成員變量m_zOrderListsDirty的值設(shè)置為true,就將自己的狀態(tài)標(biāo)記為Dirty,以后就會(huì)重新根據(jù)子元素的z-index值,將它們分別保存在對(duì)應(yīng)的列表中。最后判斷當(dāng)前加載的網(wǎng)頁有沒有被銷毀。如果沒有被銷毀,就會(huì)調(diào)用另外一個(gè)成員函數(shù)Compositor,獲得一個(gè)PaintLayerCompositor對(duì)象。該對(duì)象是用來管理當(dāng)前加載的網(wǎng)頁的Graphics Layer Tree的。調(diào)用它的成員函數(shù)SetNeedsCompositingUpdate,用來通知它需要重建Graphics Layer Tree。

            回到 Document::UpdateStyleAndLayout在更新layout時(shí),會(huì)調(diào)用EnableCompositingModeIfNeeded將網(wǎng)頁的Render Layer Tree的根節(jié)點(diǎn)設(shè)置為一個(gè)Compositing Layer,也就是要為它創(chuàng)建一個(gè)Graphics Layer。       

      void PaintLayerCompositor::EnableCompositingModeIfNeeded() {
        ...  if (RootShouldAlwaysComposite()) {
          ...
          SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
          SetCompositingModeEnabled(true);
        }
      }

           只有在采用硬件加速渲染網(wǎng)頁的情況下,才需要?jiǎng)?chuàng)建Graphics Layer。在兩種情況下,需要為Render Layer Tree的根節(jié)點(diǎn)創(chuàng)建Graphics Layer。第一種情況是當(dāng)前網(wǎng)頁加載在Main Frame中。第二種情況是當(dāng)前網(wǎng)頁不是加載在Main Frame,例如是通過iframe嵌入在Main Frame中,但是它是可滾動(dòng)的,通過RootShouldAlwaysComposite判斷。

             我們假設(shè)當(dāng)前網(wǎng)頁是加載在Main Frame中的,由于剛打開,PaintLayerCompositor類的成員變量layout_view_是剛剛創(chuàng)建的,這意味它需要執(zhí)行一個(gè)Layout操作,因此EnableCompositingModeIfNeeded為Paint Layer Tree的根節(jié)點(diǎn)創(chuàng)建一個(gè)Graphics Layer,作為Graphics Layer Tree的根節(jié)點(diǎn)。

      void PaintLayerCompositor::SetCompositingModeEnabled(bool enable) {  if (enable == compositing_)    return;
      
        compositing_ = enable;  if (compositing_)
          EnsureRootLayer();  else
          DestroyRootLayer();
          ...
      }
      void PaintLayerCompositor::EnsureRootLayer() {  if (root_layer_attachment_ != kRootLayerUnattached)    return;  // intention of this step is ?  if (IsMainFrame())
          GetVisualViewport().CreateLayerTree();
      
        AttachCompositorTimeline();
        AttachRootLayer();
      }

      通過AttachRootLayer將Graphics Layer Tree的根節(jié)點(diǎn)設(shè)置給Blink的使用者,即Chromium的Content層

      void PaintLayerCompositor::AttachRootLayer() {  // In Slimming Paint v2, PaintArtifactCompositor is responsible for the root
        // layer.
        if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())    return;  if (layout_view_.GetFrame()->IsLocalRoot()) {
          root_layer_attachment_ = kRootLayerPendingAttachViaChromeClient;
        } else {
          ...
          root_layer_attachment_ = kRootLayerAttachedViaEnclosingFrame;
        }
      }

      由此,對(duì)于Paint Layer在更新時(shí)也會(huì)AttachRootGraphicsLayer, 最終會(huì)在LayerTreeHost::SetRootLayer中設(shè)置根節(jié)點(diǎn)。

      void PaintLayerCompositor::UpdateIfNeeded(
          DocumentLifecycle::LifecycleState target_state,
          CompositingReasonsStats& compositing_reasons_stats) {
          ...    if (root_layer_attachment_ == kRootLayerPendingAttachViaChromeClient) {      if (Page* page = layout_view_.GetFrame()->GetPage()) {
              page->GetChromeClient().AttachRootGraphicsLayer(RootGraphicsLayer(),
                                                            layout_view_.GetFrame());
              root_layer_attachment_ = kRootLayerAttachedViaChromeClient;
          }
          ...
      }
      void ChromeClientImpl::AttachRootGraphicsLayer(GraphicsLayer* root_layer,
                                                     LocalFrame* local_frame) {
        ...
        WebLocalFrameImpl* web_frame =
            WebLocalFrameImpl::FromFrame(local_frame)->LocalRoot();
        ...  if (web_frame->FrameWidgetImpl())
          web_frame->FrameWidgetImpl()->SetRootGraphicsLayer(root_layer);
      }
      
      
      void WebViewFrameWidget::SetRootGraphicsLayer(GraphicsLayer* layer) {
        web_view_->SetRootGraphicsLayer(layer);
      }
      
      
      
      void WebViewImpl::SetRootGraphicsLayer(GraphicsLayer* graphics_layer) {
        ...  if (graphics_layer) {    // assign root of CCLayer 
          root_layer_ = root_graphics_layer_->CcLayer();
          UpdateDeviceEmulationTransform();
          layer_tree_view_->SetRootLayer(root_layer_);
          ...
      }
      
      
      
      void LayerTreeView::SetRootLayer(scoped_refptr<cc::Layer> layer) {
        layer_tree_host_->SetRootLayer(std::move(layer));
      }
      
      void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
        ...
        root_layer_ = root_layer;  if (root_layer_.get()) {
          DCHECK(!root_layer_->parent());
          root_layer_->SetLayerTreeHost(this);
        }
      }
      
      void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
        Layer::SetLayerTreeHost(host);
        ...
      }
      
      
      void Layer::SetLayerTreeHost(LayerTreeHost* host) {
        ...
      
        layer_tree_host_ = host;
        InvalidatePropertyTreesIndices();
      
        ...
      }

      從這里就會(huì)調(diào)用前面提到的成員函數(shù)StartCompositor激活調(diào)度器。


      前面說Layer類的成員變量layer_tree_host_指向的是一個(gè)LayerTreeHost對(duì)象,用來管理CC Layer Tree的,現(xiàn)在來看它的創(chuàng)建過程,

      通過前面的RenderWidget::InitializeLayerTreeView 調(diào)用,走多線程分支

      void LayerTreeView::Initialize(    const cc::LayerTreeSettings& settings,
          std::unique_ptr<cc::UkmRecorderFactory> ukm_recorder_factory) {
        ...  if (!is_threaded) {    // Single-threaded layout tests, and unit tests.
          layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
        } else {
          layer_tree_host_ =
              cc::LayerTreeHost::CreateThreaded(compositor_thread_, &params);
        }
      }
      
      
      std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded(
          scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
          InitParams* params) {
        ...
        std::unique_ptr<LayerTreeHost> layer_tree_host(      new LayerTreeHost(params, CompositorMode::THREADED));
        layer_tree_host->InitializeThreaded(params->main_task_runner,
                                            impl_task_runner);  return layer_tree_host;
      }
      
      
      void LayerTreeHost::InitializeThreaded(
          scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
          scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
        task_runner_provider_ =
            TaskRunnerProvider::Create(main_task_runner, impl_task_runner);
        std::unique_ptr<ProxyMain> proxy_main =
            std::make_unique<ProxyMain>(this, task_runner_provider_.get());
        InitializeProxy(std::move(proxy_main));
      }
      void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) {
        TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
        DCHECK(task_runner_provider_);
      
        proxy_ = std::move(proxy);
        proxy_->Start();
        ...
      }
      
      
      void ProxyMain::Start() {
        {
          ...
          CompletionEvent completion;
          ImplThreadTaskRunner()->PostTask(
              FROM_HERE, base::BindOnce(&ProxyMain::InitializeOnImplThread,
                                        base::Unretained(this), &completion));
          completion.Wait();
        }
      
        started_ = true;
      }

      這里創(chuàng)建了一個(gè)ProxyMain對(duì)象,保存在成員變量proxy_中, 調(diào)用Start向Compositor線程的消息隊(duì)列發(fā)送了一個(gè)Task,并且等待這個(gè)Task完成。這個(gè)Task綁定了ProxyMain類的成員函數(shù)InitializeImplOnImplThread,因此接下來ProxyMain類的成員函數(shù)InitializeImplOnImplThread就會(huì)在Compositor線程中執(zhí)行,如下所示:

       ThreadProxy類的成員函數(shù)InitializeImplOnImplThread主要是做了三件事情。

            1. 調(diào)用前面創(chuàng)建的LayerTreeHost對(duì)象的成員函數(shù)CreateLayerTreeHostImpl函數(shù)創(chuàng)建了一個(gè)LayerTreeHostImpl對(duì)象,并且保存在內(nèi)部的一個(gè)CompositorThreadOnly對(duì)象的成員變量layer_tree_host_impl中。前面創(chuàng)建的LayerTreeHost對(duì)象可以通過調(diào)用成員函數(shù)layer_tree_host_獲得。內(nèi)部的CompositorThreadOnly對(duì)象可以通過調(diào)用成員函數(shù)impl獲得。創(chuàng)建出來的LayerTreeHostImpl對(duì)象以后負(fù)責(zé)管理CC Pending Layer Tree和CC Active Layer Tree

          2. 調(diào)用Scheduler類的靜態(tài)成員函數(shù)Create創(chuàng)建了一個(gè)Scheduler對(duì)象。這個(gè)Scheduler對(duì)象以后就負(fù)責(zé)在Main線程與Compositor線程之間調(diào)度渲染工作。

            3. 將參數(shù)completion描述的Completion Event設(shè)置為有信號(hào),這樣正在等待的Main線程就可以喚醒繼續(xù)執(zhí)行其它工作了。

            LayerTreeHost類的成員函數(shù)CreateLayerTreeHostImpl創(chuàng)建LayerTreeHostImpl對(duì)象的過程,如下所示:

      std::unique_ptr<LayerTreeHostImpl>
      LayerTreeHost::CreateLayerTreeHostImpl(
          LayerTreeHostImplClient* client) {
        ...  std::unique_ptr<MutatorHost> mutator_host_impl =
            mutator_host_->CreateImplInstance(supports_impl_scrolling);  std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
            settings_, client, task_runner_provider_.get(),
            rendering_stats_instrumentation_.get(), task_graph_runner_,      std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_));
        ...  return host_impl;
      }std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(    const LayerTreeSettings& settings,
          LayerTreeHostImplClient* client,
          TaskRunnerProvider* task_runner_provider,
          RenderingStatsInstrumentation* rendering_stats_instrumentation,
          TaskGraphRunner* task_graph_runner,    std::unique_ptr<MutatorHost> mutator_host,    int id,
          scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner) {  return base::WrapUnique(new LayerTreeHostImpl(
            settings, client, task_runner_provider, rendering_stats_instrumentation,
            task_graph_runner, std::move(mutator_host), id,      std::move(image_worker_task_runner)));
      }
      
      
      LayerTreeHostImpl::LayerTreeHostImpl(    const LayerTreeSettings& settings,
          LayerTreeHostImplClient* client,
          TaskRunnerProvider* task_runner_provider,
          RenderingStatsInstrumentation* rendering_stats_instrumentation,
          TaskGraphRunner* task_graph_runner,    std::unique_ptr<MutatorHost> mutator_host,    int id,
          scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner)
          : client_(client),
            task_runner_provider_(task_runner_provider),
            ...
            tile_manager_(this,
                          GetTaskRunner(),                    std::move(image_worker_task_runner),
                          is_synchronous_single_threaded_
                              ? std::numeric_limits<size_t>::max()
                              : settings.scheduled_raster_task_limit,
                          settings.ToTileManagerSettings()),
            ...
            task_graph_runner_(task_graph_runner),
            ...,
            is_animating_for_snap_(false) {
        ...
        active_tree_ = std::make_unique<LayerTreeImpl>(      this, new SyncedProperty<ScaleGroup>, new SyncedBrowserControls,      new SyncedElasticOverscroll);
        active_tree_->property_trees()->is_active = true;
        ...
      }

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多