Commit 61d65e5d authored by Illia Martyniuk's avatar Illia Martyniuk Committed by Commit Bot

VizDevTools: Observing static FrameSink tree

Providing the possibility to track registered FrameSinkIds and created
FrameSinks but without any updates. Since there's no general root of all
FrameSinks we create a dummy root in DevTools and use it as a root of
the FrameSink tree.

Currently presubmit doesn't pass because of the checkdeps violations. It
complains about components/ui_detools/css_agent.h and
components/ui_devtools/devtools_server.h included in viz_main_impl.cc file.

Bug: 816802
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: I0fe43236ca7778668ea55bb5b945bd2526d16091
Reviewed-on: https://chromium-review.googlesource.com/998413
Commit-Queue: Illia Martyniuk <illiam@google.com>
Reviewed-by: default avatarYi Xu <yiyix@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550782}
parent f8085cad
...@@ -32,6 +32,8 @@ std::string UIElement::GetTypeName() const { ...@@ -32,6 +32,8 @@ std::string UIElement::GetTypeName() const {
return "Widget"; return "Widget";
case UIElementType::VIEW: case UIElementType::VIEW:
return "View"; return "View";
case UIElementType::FRAMESINK:
return "FrameSink";
} }
NOTREACHED(); NOTREACHED();
return std::string(); return std::string();
......
...@@ -23,7 +23,7 @@ class Array; ...@@ -23,7 +23,7 @@ class Array;
} }
// UIElement type. // UIElement type.
enum UIElementType { WINDOW, WIDGET, VIEW, ROOT }; enum UIElementType { WINDOW, WIDGET, VIEW, ROOT, FRAMESINK };
class UI_DEVTOOLS_EXPORT UIElement { class UI_DEVTOOLS_EXPORT UIElement {
public: public:
......
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//components/viz/viz.gni")
source_set("viz_views") {
sources = [
"dom_agent_viz.cc",
"dom_agent_viz.h",
"frame_sink_element.cc",
"frame_sink_element.h",
"overlay_agent_viz.cc",
"overlay_agent_viz.h",
]
deps = [
"//components/ui_devtools",
"//components/viz/service",
]
}
include_rules = [
"+components/viz/common",
"+components/viz/service",
]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/ui_devtools/viz_views/dom_agent_viz.h"
#include "components/ui_devtools/root_element.h"
#include "components/ui_devtools/ui_element.h"
#include "components/ui_devtools/viz_views/frame_sink_element.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
namespace ui_devtools {
using namespace ui_devtools::protocol;
DOMAgentViz::DOMAgentViz(viz::FrameSinkManagerImpl* frame_sink_manager)
: frame_sink_manager_(frame_sink_manager) {}
DOMAgentViz::~DOMAgentViz() {
Clear();
}
std::unique_ptr<DOM::Node> DOMAgentViz::BuildTreeForFrameSink(
UIElement* frame_sink_element,
const viz::FrameSinkId& frame_sink_id) {
frame_sink_elements_.emplace(frame_sink_id, frame_sink_element);
std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create();
// Once the FrameSinkElement is created it calls this function to build its
// subtree. So we iterate through |frame_sink_element|'s children and
// recursively build the subtree for them.
for (auto& child : frame_sink_manager_->GetChildrenByParent(frame_sink_id)) {
bool is_registered = registered_frame_sink_ids_.find(child) !=
registered_frame_sink_ids_.end();
bool is_client_connected = client_connected_frame_sinks_.find(child) !=
client_connected_frame_sinks_.end();
UIElement* f_s_element = new FrameSinkElement(
child, frame_sink_manager_, this, frame_sink_element, false /*is_root*/,
is_registered, is_client_connected);
children->addItem(BuildTreeForFrameSink(f_s_element, child));
frame_sink_element->AddChild(f_s_element);
}
std::unique_ptr<DOM::Node> node =
BuildNode("FrameSink", frame_sink_element->GetAttributes(),
std::move(children), frame_sink_element->node_id());
return node;
}
protocol::Response DOMAgentViz::enable() {
InitFrameSinkSets();
return protocol::Response::OK();
}
protocol::Response DOMAgentViz::disable() {
Clear();
return DOMAgent::disable();
}
std::vector<UIElement*> DOMAgentViz::CreateChildrenForRoot() {
std::vector<UIElement*> children;
// Step 1. Add created RootFrameSinks and detached FrameSinks.
for (auto& frame_sink_id : client_connected_frame_sinks_) {
const viz::CompositorFrameSinkSupport* support =
frame_sink_manager_->GetFrameSinkForId(frame_sink_id);
// Do nothing if it's a non-detached non-root FrameSink.
if (support && !support->is_root() &&
attached_frame_sinks_.find(frame_sink_id) !=
attached_frame_sinks_.end())
continue;
bool is_registered = registered_frame_sink_ids_.find(frame_sink_id) !=
registered_frame_sink_ids_.end();
bool is_root = support && support->is_root();
UIElement* frame_sink_element = new FrameSinkElement(
frame_sink_id, frame_sink_manager_, this, element_root(), is_root,
is_registered, true /*is_client_connected*/);
children.push_back(frame_sink_element);
}
// Step 2. Add registered but not created FrameSinks. If a FrameSinkId was
// registered but not created we don't really know whether it's a root or not.
// And we don't know any information about the hierarchy. Therefore we process
// FrameSinks that are in the correct state first and only after that we
// process registered but not created FrameSinks. We consider them unembedded
// as well.
for (auto& frame_sink_id : registered_frame_sink_ids_) {
if (client_connected_frame_sinks_.find(frame_sink_id) !=
client_connected_frame_sinks_.end())
continue;
UIElement* frame_sink_element = new FrameSinkElement(
frame_sink_id, frame_sink_manager_, this, element_root(),
false /*is_root*/, true /*is_registered*/,
false /*is_client_connected*/);
children.push_back(frame_sink_element);
}
return children;
}
std::unique_ptr<DOM::Node> DOMAgentViz::BuildTreeForUIElement(
UIElement* ui_element) {
if (ui_element->type() == UIElementType::FRAMESINK) {
return BuildTreeForFrameSink(ui_element,
FrameSinkElement::From(ui_element));
}
return nullptr;
}
void DOMAgentViz::Clear() {
attached_frame_sinks_.clear();
client_connected_frame_sinks_.clear();
frame_sink_elements_.clear();
registered_frame_sink_ids_.clear();
}
void DOMAgentViz::InitFrameSinkSets() {
for (auto& entry : frame_sink_manager_->GetRegisteredFrameSinkIds())
registered_frame_sink_ids_.insert(entry);
for (auto& entry : frame_sink_manager_->GetCreatedFrameSinkIds())
client_connected_frame_sinks_.insert(entry);
// Init the |attached_frame_sinks_| set. All RootFrameSinks and accessible
// from roots are attached. All the others are detached.
for (auto& frame_sink_id : client_connected_frame_sinks_) {
const viz::CompositorFrameSinkSupport* support =
frame_sink_manager_->GetFrameSinkForId(frame_sink_id);
// Start only from roots.
if (!support || !support->is_root())
continue;
SetAttachedFrameSink(frame_sink_id);
}
}
void DOMAgentViz::SetAttachedFrameSink(const viz::FrameSinkId& frame_sink_id) {
attached_frame_sinks_.insert(frame_sink_id);
for (auto& child : frame_sink_manager_->GetChildrenByParent(frame_sink_id))
SetAttachedFrameSink(child);
}
} // namespace ui_devtools
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_DOM_AGENT_VIZ_H_
#define COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_DOM_AGENT_VIZ_H_
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "components/ui_devtools/DOM.h"
#include "components/ui_devtools/dom_agent.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
namespace viz {
class FrameSinkManagerImpl;
}
namespace ui_devtools {
class DOMAgentViz : public DOMAgent {
public:
explicit DOMAgentViz(viz::FrameSinkManagerImpl* frame_sink_manager);
~DOMAgentViz() override;
private:
std::unique_ptr<protocol::DOM::Node> BuildTreeForFrameSink(
UIElement* frame_sink_element,
const viz::FrameSinkId& frame_sink_id);
// DOM::Backend:
protocol::Response enable() override;
protocol::Response disable() override;
// DOMAgent:
std::vector<UIElement*> CreateChildrenForRoot() override;
std::unique_ptr<protocol::DOM::Node> BuildTreeForUIElement(
UIElement* ui_element) override;
// Every time the frontend disconnects we don't destroy DOMAgent so once we
// establish the connection again we need to clear the FrameSinkId sets
// because they may carry obsolete data. Then we initialize these with alive
// FrameSinkIds. Clears the sets of FrameSinkIds that correspond to created
// FrameSinks, registered FrameSinkIds and those that have corresponding
// FrameSinkElements created.
void Clear();
// Initializes the sets of FrameSinkIds that correspond to registered
// FrameSinkIds and created FrameSinks.
void InitFrameSinkSets();
// Mark a FrameSink that has |frame_sink_id| and all its subtree as attached.
void SetAttachedFrameSink(const viz::FrameSinkId& frame_sink_id);
// These sets are used to create and update the DOM tree.
base::flat_set<viz::FrameSinkId> registered_frame_sink_ids_;
base::flat_set<viz::FrameSinkId> client_connected_frame_sinks_;
// This is used to track created FrameSinkElements and will be used for
// updates in a FrameSink tree.
base::flat_map<viz::FrameSinkId, UIElement*> frame_sink_elements_;
// This is used to denote attached FrameSinks.
base::flat_set<viz::FrameSinkId> attached_frame_sinks_;
viz::FrameSinkManagerImpl* frame_sink_manager_;
DISALLOW_COPY_AND_ASSIGN(DOMAgentViz);
};
} // namespace ui_devtools
#endif // COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_DOM_AGENT_VIZ_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/ui_devtools/viz_views/frame_sink_element.h"
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/ui_element_delegate.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/service/surfaces/surface_manager.h"
namespace ui_devtools {
FrameSinkElement::FrameSinkElement(
const viz::FrameSinkId& frame_sink_id,
viz::FrameSinkManagerImpl* frame_sink_manager,
UIElementDelegate* ui_element_delegate,
UIElement* parent,
bool is_root,
bool is_registered,
bool is_client_connected)
: UIElement(UIElementType::FRAMESINK, ui_element_delegate, parent),
frame_sink_id_(frame_sink_id),
frame_sink_manager_(frame_sink_manager),
is_root_(is_root),
is_registered_(is_registered),
is_client_connected_(is_client_connected) {}
FrameSinkElement::~FrameSinkElement() {}
std::vector<std::pair<std::string, std::string>>
FrameSinkElement::GetCustomProperties() const {
std::vector<std::pair<std::string, std::string>> v;
// Hierarchical information about the FrameSink.
v.push_back(std::make_pair("Is root", is_root_ ? "true" : "false"));
v.push_back(
std::make_pair("Is registered", is_registered_ ? "true" : "false"));
v.push_back(std::make_pair("Is connected by client",
is_client_connected_ ? "true" : "false"));
// LastUsedBeingFrameArgs information.
const viz::CompositorFrameSinkSupport* support =
frame_sink_manager_->GetFrameSinkForId(frame_sink_id_);
if (support) {
const viz::BeginFrameArgs args =
static_cast<const viz::BeginFrameObserver*>(support)
->LastUsedBeginFrameArgs();
v.push_back(std::make_pair("SourceId", std::to_string(args.source_id)));
v.push_back(
std::make_pair("SequenceNumber", std::to_string(args.sequence_number)));
v.push_back(std::make_pair(
"FrameType",
std::string(viz::BeginFrameArgs::TypeToString(args.type))));
}
return v;
}
void FrameSinkElement::GetBounds(gfx::Rect* bounds) const {
const viz::CompositorFrameSinkSupport* support =
frame_sink_manager_->GetFrameSinkForId(frame_sink_id_);
if (!support) {
*bounds = gfx::Rect();
return;
}
// Get just size of last activated surface that corresponds to this frame
// sink.
viz::Surface* srfc = frame_sink_manager_->surface_manager()->GetSurfaceForId(
support->last_activated_surface_id());
if (srfc)
*bounds = gfx::Rect(srfc->size_in_pixels());
else
*bounds = gfx::Rect();
}
void FrameSinkElement::SetBounds(const gfx::Rect& bounds) {}
void FrameSinkElement::GetVisible(bool* visible) const {
// Currently not real data.
*visible = true;
}
void FrameSinkElement::SetVisible(bool visible) {}
std::unique_ptr<protocol::Array<std::string>> FrameSinkElement::GetAttributes()
const {
auto attributes = protocol::Array<std::string>::create();
attributes->addItem("FrameSinkId");
attributes->addItem(frame_sink_id_.ToString());
attributes->addItem("Title");
attributes->addItem(
frame_sink_manager_->surface_manager()->GetFrameSinkDebugLabel(
frame_sink_id_));
return attributes;
}
std::pair<gfx::NativeWindow, gfx::Rect>
FrameSinkElement::GetNodeWindowAndBounds() const {
return {};
}
// static
const viz::FrameSinkId& FrameSinkElement::From(const UIElement* element) {
DCHECK_EQ(UIElementType::FRAMESINK, element->type());
return static_cast<const FrameSinkElement*>(element)->frame_sink_id_;
}
} // namespace ui_devtools
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_FRAME_SINK_ELEMENT_H_
#define COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_FRAME_SINK_ELEMENT_H_
#include "base/macros.h"
#include "components/ui_devtools/ui_element.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
namespace viz {
class FrameSinkManagerImpl;
}
namespace ui_devtools {
class FrameSinkElement : public UIElement {
public:
FrameSinkElement(const viz::FrameSinkId& frame_sink_id,
viz::FrameSinkManagerImpl* frame_sink_manager,
UIElementDelegate* ui_element_delegate,
UIElement* parent,
bool is_root,
bool is_registered,
bool is_client_connected);
~FrameSinkElement() override;
// UIElement:
std::vector<std::pair<std::string, std::string>> GetCustomProperties()
const override;
void GetBounds(gfx::Rect* bounds) const override;
void SetBounds(const gfx::Rect& bounds) override;
void GetVisible(bool* visible) const override;
void SetVisible(bool visible) override;
std::unique_ptr<protocol::Array<std::string>> GetAttributes() const override;
std::pair<gfx::NativeWindow, gfx::Rect> GetNodeWindowAndBounds()
const override;
static const viz::FrameSinkId& From(const UIElement* element);
private:
const viz::FrameSinkId frame_sink_id_;
viz::FrameSinkManagerImpl* frame_sink_manager_;
// Properties of the FrameSink. If element is a RootFrameSink then it has
// |is_root_| = true. If element is not a root than it has |is_root_| = false.
// If an element is a sibling of a RootFrameSink but has property |is_root_| =
// false then it is considered detached. If the FrameSink was registered then
// corresponding element's |is_registered_| = true. If a FrameSink was created
// then |is_client_connected_| = true.
bool is_root_;
bool is_registered_;
bool is_client_connected_;
DISALLOW_COPY_AND_ASSIGN(FrameSinkElement);
};
} // namespace ui_devtools
#endif // COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_FRAME_SINK_ELEMENT_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/ui_devtools/viz_views/overlay_agent_viz.h"
namespace ui_devtools {
OverlayAgentViz::OverlayAgentViz(DOMAgentViz* dom_agent)
: OverlayAgent(dom_agent) {}
OverlayAgentViz::~OverlayAgentViz() {}
protocol::Response OverlayAgentViz::setInspectMode(
const String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
return protocol::Response::OK();
}
protocol::Response OverlayAgentViz::highlightNode(
std::unique_ptr<protocol::Overlay::HighlightConfig> highlight_config,
protocol::Maybe<int> node_id) {
return protocol::Response::OK();
}
protocol::Response OverlayAgentViz::hideHighlight() {
return protocol::Response::OK();
}
} // namespace ui_devtools
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_OVERLAY_AGENT_VIZ_H_
#define COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_OVERLAY_AGENT_VIZ_H_
#include "components/ui_devtools/Overlay.h"
#include "components/ui_devtools/overlay_agent.h"
#include "components/ui_devtools/viz_views/dom_agent_viz.h"
namespace ui_devtools {
class OverlayAgentViz : public OverlayAgent {
public:
explicit OverlayAgentViz(DOMAgentViz* dom_agent);
~OverlayAgentViz() override;
// Overlay::Backend:
protocol::Response setInspectMode(
const String& in_mode,
protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
override;
protocol::Response highlightNode(
std::unique_ptr<protocol::Overlay::HighlightConfig> highlight_config,
protocol::Maybe<int> node_id) override;
protocol::Response hideHighlight() override;
private:
DISALLOW_COPY_AND_ASSIGN(OverlayAgentViz);
};
} // namespace ui_devtools
#endif // COMPONENTS_UI_DEVTOOLS_VIZ_VIEWS_OVERLAY_AGENT_VIZ_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment