0
Files
src/ash/debug.cc
Eliot Courtney f1505cec49 Include exo child surface layers in layer debug listing
When exo aura windows of child surfaces were disconnected from the
window tree for perf reasons, their layers also disappeared from the
debug listing. It's confusing, so add them back in as a special case.

Bug: 1497343
Test: manual + cq
Change-Id: Ib228432d40f9fbb6368e8e1e688022558379034a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4996491
Commit-Queue: Eliot Courtney <edcourtney@chromium.org>
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1220764}
2023-11-07 07:34:58 +00:00

200 lines
7.1 KiB
C++

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/debug.h"
#include <memory>
#include <string>
#include "ash/public/cpp/debug_utils.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "cc/debug/layer_tree_debug_state.h"
#include "ui/accessibility/aura/aura_window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/debug_utils.h"
#include "ui/compositor/layer.h"
#include "ui/views/debug_utils.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace debug {
namespace {
std::unique_ptr<DebugWindowHierarchyDelegate> instance = nullptr;
} // namespace
void SetDebugWindowHierarchyDelegate(
std::unique_ptr<DebugWindowHierarchyDelegate> delegate) {
instance = std::move(delegate);
}
void PrintLayerHierarchy(std::ostringstream* out) {
ui::DebugLayerChildCallback child_cb =
instance ? base::BindRepeating(
&DebugWindowHierarchyDelegate::GetAdjustedLayerChildren,
base::Unretained(instance.get()))
: ui::DebugLayerChildCallback();
for (aura::Window* root : Shell::Get()->GetAllRootWindows()) {
ui::Layer* layer = root->layer();
if (layer) {
ui::PrintLayerHierarchy(
layer,
RootWindowController::ForWindow(root)->GetLastMouseLocationInRoot(),
out, child_cb);
}
}
}
void PrintViewHierarchy(std::ostringstream* out) {
aura::Window* active_window = window_util::GetActiveWindow();
if (!active_window)
return;
views::Widget* widget = views::Widget::GetWidgetForNativeView(active_window);
if (!widget)
return;
*out << "Host widget:\n";
views::PrintWidgetInformation(*widget, /*detailed*/ true, out);
views::PrintViewHierarchy(widget->GetRootView(), out);
}
void PrintWindowHierarchy(const aura::Window* active_window,
const aura::Window* focused_window,
const aura::Window* capture_window,
aura::Window* window,
int indent,
bool scrub_data,
std::vector<std::string>* out_window_titles,
std::ostringstream* out) {
std::string indent_str(indent, ' ');
std::string name(window->GetName());
if (name.empty())
name = "\"\"";
const gfx::Vector2dF& subpixel_position_offset =
window->layer()->GetSubpixelOffset();
*out << indent_str;
*out << " [window]";
*out << " " << name << " (" << window << ")"
<< " type=" << window->GetType();
int window_id = window->GetId();
if (window_id != aura::Window::kInitialId)
*out << " id=" << window_id;
if (window->GetProperty(kWindowStateKey))
*out << " " << WindowState::Get(window)->GetStateType();
*out << ((window == active_window) ? " [active]" : "")
<< ((window == focused_window) ? " [focused]" : "")
<< ((window == capture_window) ? " [capture]" : "")
<< (window->GetTransparent() ? " [transparent]" : "")
<< (window->IsVisible() ? " [visible]" : "") << " "
<< (window->GetOcclusionState() != aura::Window::OcclusionState::UNKNOWN
? base::UTF16ToUTF8(aura::Window::OcclusionStateToString(
window->GetOcclusionState()))
.c_str()
: "")
<< " " << window->bounds().ToString()
<< " scale=" + window->transform().To2dScale().ToString();
if (!subpixel_position_offset.IsZero())
*out << " subpixel offset=" + subpixel_position_offset.ToString();
std::string* tree_id = window->GetProperty(ui::kChildAXTreeID);
if (tree_id)
*out << " ax_tree_id=" << *tree_id;
std::u16string title(window->GetTitle());
if (!title.empty()) {
out_window_titles->push_back(base::UTF16ToUTF8(title));
if (!scrub_data) {
*out << " title=" << title;
}
}
int app_type = window->GetProperty(aura::client::kAppType);
*out << " app_type=" << app_type;
std::string* pkg_name = window->GetProperty(ash::kArcPackageNameKey);
if (pkg_name)
*out << " pkg_name=" << *pkg_name;
*out << '\n';
views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
if (widget) {
*out << std::string(indent + 3, ' ');
*out << " [widget]";
views::PrintWidgetInformation(*widget, /*detailed*/ false, out);
}
std::vector<aura::Window*> children =
instance ? instance->GetAdjustedWindowChildren(window)
: window->children();
for (aura::Window* child : children) {
PrintWindowHierarchy(active_window, focused_window, capture_window, child,
indent + 3, scrub_data, out_window_titles, out);
}
}
std::vector<std::string> PrintWindowHierarchy(std::ostringstream* out,
bool scrub_data) {
aura::Window* active_window = window_util::GetActiveWindow();
aura::Window* focused_window = window_util::GetFocusedWindow();
aura::Window* capture_window = window_util::GetCaptureWindow();
aura::Window::Windows roots = Shell::Get()->GetAllRootWindows();
std::vector<std::string> window_titles;
for (size_t i = 0; i < roots.size(); ++i) {
*out << "RootWindow " << i << ":\n";
PrintWindowHierarchy(active_window, focused_window, capture_window,
roots[i], 0, scrub_data, &window_titles, out);
}
return window_titles;
}
void ToggleShowDebugBorders() {
aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
std::unique_ptr<cc::DebugBorderTypes> value;
for (auto* window : root_windows) {
ui::Compositor* compositor = window->GetHost()->compositor();
cc::LayerTreeDebugState state = compositor->GetLayerTreeDebugState();
if (!value.get())
value = std::make_unique<cc::DebugBorderTypes>(
state.show_debug_borders.flip());
state.show_debug_borders = *value.get();
compositor->SetLayerTreeDebugState(state);
}
}
void ToggleShowFpsCounter() {
aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
std::unique_ptr<bool> value;
for (auto* window : root_windows) {
ui::Compositor* compositor = window->GetHost()->compositor();
cc::LayerTreeDebugState state = compositor->GetLayerTreeDebugState();
if (!value.get())
value = std::make_unique<bool>(!state.show_fps_counter);
state.show_fps_counter = *value.get();
compositor->SetLayerTreeDebugState(state);
}
}
void ToggleShowPaintRects() {
aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
std::unique_ptr<bool> value;
for (auto* window : root_windows) {
ui::Compositor* compositor = window->GetHost()->compositor();
cc::LayerTreeDebugState state = compositor->GetLayerTreeDebugState();
if (!value.get())
value = std::make_unique<bool>(!state.show_paint_rects);
state.show_paint_rects = *value.get();
compositor->SetLayerTreeDebugState(state);
}
}
} // namespace debug
} // namespace ash