15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/debug_utils.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iomanip>
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <ostream>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/interpolated_transform.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point_conversions.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/transform.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF8ToWide;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrintLayerHierarchyImp(const Layer* layer,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            int indent,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gfx::Point mouse_location,
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            std::wostringstream* out) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string indent_str(indent, ' ');
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  layer->transform().TransformPointReverse(&mouse_location);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool mouse_inside_layer_bounds = layer->bounds().Contains(mouse_location);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_location.Offset(-layer->bounds().x(), -layer->bounds().y());
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out << UTF8ToWide(indent_str);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_inside_layer_bounds)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L'*';
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L' ';
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out << UTF8ToWide(layer->name()) << L' ' << layer;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (layer->type()) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::LAYER_NOT_DRAWN:
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *out << L" not_drawn";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::LAYER_TEXTURED:
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *out << L" textured";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (layer->fills_bounds_opaquely())
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        *out << L" opaque";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ui::LAYER_SOLID_COLOR:
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *out << L" solid";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case ui::LAYER_NINE_PATCH:
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *out << L" nine_patch";
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!layer->visible())
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L" !visible";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string property_indent_str(indent+3, ' ');
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out << L'\n' << UTF8ToWide(property_indent_str);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out << L"bounds: " << layer->bounds().x() << L',' << layer->bounds().y();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out << L' ' << layer->bounds().width() << L'x' << layer->bounds().height();
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!layer->subpixel_position_offset().IsZero())
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *out << " " << UTF8ToWide(layer->subpixel_position_offset().ToString());
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const ui::Layer* mask = const_cast<ui::Layer*>(layer)->layer_mask_layer();
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (mask) {
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *out << L'\n' << UTF8ToWide(property_indent_str);
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *out << L"mask layer: " << std::setprecision(2)
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         << UTF8ToWide(mask->bounds().ToString())
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         << UTF8ToWide(mask->subpixel_position_offset().ToString());
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (layer->opacity() != 1.0f) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L'\n' << UTF8ToWide(property_indent_str);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L"opacity: " << std::setprecision(2) << layer->opacity();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::DecomposedTransform decomp;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer->transform().IsIdentity() &&
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::DecomposeTransform(&decomp, layer->transform())) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L'\n' << UTF8ToWide(property_indent_str);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L"translation: " << std::fixed << decomp.translate[0];
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L", " << decomp.translate[1];
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L'\n' << UTF8ToWide(property_indent_str);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L"rotation: ";
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << std::acos(decomp.quaternion[3]) * 360.0 / M_PI;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L'\n' << UTF8ToWide(property_indent_str);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L"scale: " << decomp.scale[0];
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *out << L", " << decomp.scale[1];
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out << L'\n';
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0, count = layer->children().size(); i < count; ++i) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrintLayerHierarchyImp(
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer->children()[i], indent + 3, mouse_location, out);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintLayerHierarchy(const Layer* layer, gfx::Point mouse_location) {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::wostringstream out;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out << L"Layer hierarchy:\n";
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrintLayerHierarchyImp(layer, 0, mouse_location, &out);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Error so logs can be collected from end-users.
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(ERROR) << out.str();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace ui
122