1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// found in the LICENSE file.
4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/host/transformer_helper.h"
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/host/ash_window_tree_host.h"
8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/host/root_window_transformer.h"
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/aura/window.h"
10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/aura/window_tree_host.h"
11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/compositor/dip_util.h"
12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/geometry/insets.h"
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/geometry/rect.h"
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/geometry/rect_f.h"
15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/geometry/size.h"
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/size_conversions.h"
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/transform.h"
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace ash {
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace {
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// A simple RootWindowTransformer without host insets.
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass SimpleRootWindowTransformer : public RootWindowTransformer {
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SimpleRootWindowTransformer(const aura::Window* root_window,
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                              const gfx::Transform& transform)
27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : root_window_(root_window), transform_(transform) {}
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // RootWindowTransformer overrides:
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual gfx::Transform GetTransform() const OVERRIDE { return transform_; }
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual gfx::Transform GetInverseTransform() const OVERRIDE {
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gfx::Transform invert;
34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!transform_.GetInverse(&invert))
35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return transform_;
36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return invert;
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual gfx::Rect GetRootWindowBounds(const gfx::Size& host_size) const
40a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      OVERRIDE {
41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gfx::Rect bounds(host_size);
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gfx::RectF new_bounds(ui::ConvertRectToDIP(root_window_->layer(), bounds));
43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    transform_.TransformRect(&new_bounds);
44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return gfx::Rect(gfx::ToFlooredSize(new_bounds.size()));
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual gfx::Insets GetHostInsets() const OVERRIDE { return gfx::Insets(); }
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual ~SimpleRootWindowTransformer() {}
51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const aura::Window* root_window_;
53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const gfx::Transform transform_;
54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SimpleRootWindowTransformer);
56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}  // namespace
59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
60a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTransformerHelper::TransformerHelper(AshWindowTreeHost* ash_host)
61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : ash_host_(ash_host) {
62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetTransform(gfx::Transform());
63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
65a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTransformerHelper::~TransformerHelper() {}
66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochgfx::Insets TransformerHelper::GetHostInsets() const {
68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return transformer_->GetHostInsets();
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid TransformerHelper::SetTransform(const gfx::Transform& transform) {
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<RootWindowTransformer> transformer(new SimpleRootWindowTransformer(
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ash_host_->AsWindowTreeHost()->window(), transform));
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetRootWindowTransformer(transformer.Pass());
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid TransformerHelper::SetRootWindowTransformer(
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    scoped_ptr<RootWindowTransformer> transformer) {
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  transformer_ = transformer.Pass();
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost();
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  aura::Window* window = host->window();
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  window->SetTransform(transformer_->GetTransform());
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // If the layer is not animating, then we need to update the root window
84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // size immediately.
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!window->layer()->GetAnimator()->is_animating())
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    host->UpdateRootWindowSize(host->GetBounds().size());
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochgfx::Transform TransformerHelper::GetTransform() const {
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  float scale = ui::GetDeviceScaleFactor(
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ash_host_->AsWindowTreeHost()->window()->layer());
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Transform transform;
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  transform.Scale(scale, scale);
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  transform *= transformer_->GetTransform();
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return transform;
96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochgfx::Transform TransformerHelper::GetInverseTransform() const {
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  float scale = ui::GetDeviceScaleFactor(
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ash_host_->AsWindowTreeHost()->window()->layer());
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Transform transform;
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  transform.Scale(1.0f / scale, 1.0f / scale);
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return transformer_->GetInverseTransform() * transform;
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid TransformerHelper::UpdateWindowSize(const gfx::Size& host_size) {
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ash_host_->AsWindowTreeHost()->window()->SetBounds(
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      transformer_->GetRootWindowBounds(host_size));
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}  // namespace ash
112