Chromium Code Reviews| Index: ash/display/root_window_transformers.cc |
| diff --git a/ash/ash_root_window_transformer.cc b/ash/display/root_window_transformers.cc |
| similarity index 38% |
| rename from ash/ash_root_window_transformer.cc |
| rename to ash/display/root_window_transformers.cc |
| index fa8a8a3c546bd3f3164907d014bd7fe168a4deea..7773187a4648c08eef7f7b520b7dade3a56835ff 100644 |
| --- a/ash/ash_root_window_transformer.cc |
| +++ b/ash/display/root_window_transformers.cc |
| @@ -2,7 +2,7 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "ash/ash_root_window_transformer.h" |
| +#include "ash/display/root_window_transformers.h" |
| #include <cmath> |
| @@ -10,17 +10,23 @@ |
| #include "ash/display/display_manager.h" |
| #include "ash/magnifier/magnification_controller.h" |
| #include "ash/shell.h" |
| +#include "base/basictypes.h" |
| +#include "base/memory/scoped_ptr.h" |
| #include "third_party/skia/include/utils/SkMatrix44.h" |
| #include "ui/aura/root_window.h" |
| +#include "ui/aura/root_window_transformer.h" |
| #include "ui/aura/window_property.h" |
| #include "ui/compositor/dip_util.h" |
| #include "ui/gfx/display.h" |
| +#include "ui/gfx/insets.h" |
| #include "ui/gfx/size_conversions.h" |
| #include "ui/gfx/transform.h" |
| +#include "ui/gfx/transform.h" |
| DECLARE_WINDOW_PROPERTY_TYPE(gfx::Display::Rotation); |
| namespace ash { |
| +namespace internal { |
| namespace { |
| DEFINE_WINDOW_PROPERTY_KEY(gfx::Display::Rotation, kRotationPropertyKey, |
| @@ -40,7 +46,7 @@ void RoundNearZero(gfx::Transform* transform) { |
| gfx::Transform CreateRotationTransform(aura::RootWindow* root_window, |
| const gfx::Display& display) { |
| - internal::DisplayInfo info = |
| + DisplayInfo info = |
| Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id()); |
| // TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade) |
| @@ -97,80 +103,175 @@ gfx::Transform CreateMagnifierTransform(aura::RootWindow* root_window) { |
| return transform; |
| } |
| -gfx::Transform CreateOverscanAndUIScaleTransform(aura::RootWindow* root_window, |
| - const gfx::Display& display) { |
| - internal::DisplayInfo info = |
| - Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id()); |
| - gfx::Insets insets = info.GetOverscanInsetsInPixel(); |
| - float scale = info.ui_scale(); |
| - |
| +gfx::Transform CreateInsetsAndScaleTransform(const gfx::Insets& insets, |
| + float device_scale_factor, |
| + float ui_scale) { |
| gfx::Transform transform; |
| if (insets.top() != 0 || insets.left() != 0) { |
| - float device_scale_factor = ui::GetDeviceScaleFactor(root_window->layer()); |
| float x_offset = insets.left() / device_scale_factor; |
| float y_offset = insets.top() / device_scale_factor; |
| transform.Translate(x_offset, y_offset); |
| } |
| - float inverted_scale = 1.0f / scale; |
| + float inverted_scale = 1.0f / ui_scale; |
| transform.Scale(inverted_scale, inverted_scale); |
| return transform; |
| } |
| -} // namespace |
| +gfx::Transform CreateOverscanAndUIScaleTransform(aura::RootWindow* root_window, |
| + const gfx::Display& display) { |
| + DisplayInfo info = |
| + Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id()); |
| + return CreateInsetsAndScaleTransform( |
| + info.GetOverscanInsetsInPixel(), |
| + ui::GetDeviceScaleFactor(root_window->layer()), |
| + info.ui_scale()); |
| +} |
| -AshRootWindowTransformer::AshRootWindowTransformer(aura::RootWindow* root, |
| - const gfx::Display& display) |
| - : root_window_(root) { |
| - root_window_bounds_transform_ = |
| - CreateOverscanAndUIScaleTransform(root, display) * |
| - CreateRotationTransform(root, display); |
| - transform_ = root_window_bounds_transform_ * CreateMagnifierTransform(root); |
| - CHECK(transform_.GetInverse(&invert_transform_)); |
| - |
| - internal::DisplayInfo info = Shell::GetInstance()-> |
| - display_manager()->GetDisplayInfo(display.id()); |
| - root_window_ui_scale_ = info.ui_scale(); |
| - host_insets_ = info.GetOverscanInsetsInPixel(); |
| - MagnificationController* magnifier = |
| - Shell::GetInstance()->magnification_controller(); |
| +// RootWindowTransformer for ash environment. |
| +class ASH_EXPORT AshRootWindowTransformer : public aura::RootWindowTransformer { |
|
James Cook
2013/05/29 12:22:43
Dumb question: If these are internal classes in a
oshima
2013/05/29 15:39:49
good point. I just copied from header and apparent
|
| + public: |
| + AshRootWindowTransformer(aura::RootWindow* root, |
| + const gfx::Display& display) |
| + : root_window_(root) { |
| + root_window_bounds_transform_ = |
| + CreateOverscanAndUIScaleTransform(root, display) * |
| + CreateRotationTransform(root, display); |
| + transform_ = root_window_bounds_transform_ * CreateMagnifierTransform(root); |
| + CHECK(transform_.GetInverse(&invert_transform_)); |
| - bool scaled = (root_window_ui_scale_ != 1.f) || |
| - (magnifier && magnifier->GetScale() != 1.f); |
| - root_window_->layer()->SetForceRenderSurface(scaled); |
| -} |
| + DisplayInfo info = Shell::GetInstance()->display_manager()-> |
| + GetDisplayInfo(display.id()); |
| + root_window_ui_scale_ = info.ui_scale(); |
| + host_insets_ = info.GetOverscanInsetsInPixel(); |
| + MagnificationController* magnifier = |
| + Shell::GetInstance()->magnification_controller(); |
| -AshRootWindowTransformer::~AshRootWindowTransformer() {} |
| + bool scaled = (root_window_ui_scale_ != 1.f) || |
| + (magnifier && magnifier->GetScale() != 1.f); |
| + root_window_->layer()->SetForceRenderSurface(scaled); |
| + } |
| -gfx::Transform AshRootWindowTransformer::GetTransform() const { |
| - return transform_; |
| -} |
| + // aura::RootWindowTransformer overrides: |
| + virtual gfx::Transform GetTransform() const OVERRIDE { |
| + return transform_; |
| + } |
| + virtual gfx::Transform GetInverseTransform() const OVERRIDE { |
| + return invert_transform_; |
| + } |
| + virtual gfx::Rect GetRootWindowBounds( |
| + const gfx::Size& host_size) const OVERRIDE { |
| + gfx::Rect bounds(host_size); |
| + bounds.Inset(host_insets_); |
| + bounds = ui::ConvertRectToDIP(root_window_->layer(), bounds); |
| + gfx::RectF new_bounds(bounds); |
| + root_window_bounds_transform_.TransformRect(&new_bounds); |
| + // Apply |root_window_scale_| twice as the downscaling |
| + // is already applied once in |SetTransformInternal()|. |
| + // TODO(oshima): This is a bit ugly. Consider specifying |
| + // the pseudo host resolution instead. |
| + new_bounds.Scale(root_window_ui_scale_ * root_window_ui_scale_); |
| + // Ignore the origin because RootWindow's insets are handled by |
| + // the transform. |
| + // Floor the size because the bounds is no longer aligned to |
| + // backing pixel when |root_window_scale_| is specified |
| + // (850 height at 1.25 scale becomes 1062.5 for example.) |
| + return gfx::Rect(gfx::ToFlooredSize(new_bounds.size())); |
| + } |
| -gfx::Transform AshRootWindowTransformer::GetInverseTransform() const { |
| - return invert_transform_; |
| -} |
| + virtual gfx::Insets GetHostInsets() const OVERRIDE { |
| + return host_insets_; |
| + } |
| + |
| + private: |
| + virtual ~AshRootWindowTransformer() {} |
| + |
| + aura::RootWindow* root_window_; |
| + gfx::Transform transform_; |
| + |
| + // The accurate representation of the inverse of the |transform_|. |
| + // This is used to avoid computation error caused by |
| + // |gfx::Transform::GetInverse|. |
| + gfx::Transform invert_transform_; |
| + |
| + // The transform of the root window bounds. This is used to calculate |
| + // the size of root window. |
| + gfx::Transform root_window_bounds_transform_; |
| + |
| + // The scale of the root window. This is used to expand the |
| + // area of the root window (useful in HighDPI display). |
| + // Note that this should not be confused with the device scale |
| + // factor, which specfies the pixel density of the display. |
| + float root_window_ui_scale_; |
| + |
| + gfx::Insets host_insets_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AshRootWindowTransformer); |
| +}; |
| + |
| +// RootWindowTransformer for mirror root window. We simply copy the |
| +// texture (bitmap) of the source display into the mirror window, so |
| +// kthe root window bounds is the same as the source display's |
|
James Cook
2013/05/29 12:22:43
kthe -> the
oshima
2013/05/29 15:39:49
Done.
|
| +// pixel size (excluding overscan insets). |
| +class ASH_EXPORT MirrorRootWindowTransformer |
| + : public aura::RootWindowTransformer { |
| + public: |
| + MirrorRootWindowTransformer(const DisplayInfo& source_display_info, |
| + const DisplayInfo& mirror_display_info) { |
| + root_bounds_ = gfx::Rect(source_display_info.bounds_in_pixel().size()); |
| + gfx::Rect mirror_display_rect = |
| + gfx::Rect(mirror_display_info.bounds_in_pixel().size()); |
| + |
| + // TODO(oshima): Insets & scale has to be adjusted so that |
| + // 1) it does letterbox/pillarbox to adjust aspect ration |
|
James Cook
2013/05/29 12:22:43
ration -> ratio
oshima
2013/05/29 15:39:49
Done.
|
| + // 2) visible area excluding insets are corretly mapped |
|
James Cook
2013/05/29 12:22:43
corretly -> correctly
I'm like a human spelling-c
oshima
2013/05/29 15:39:49
Done.
|
| + // to the other display's visible area. |
| + float mirror_scale_ratio = |
| + (static_cast<float>(root_bounds_.width()) / |
| + static_cast<float>(mirror_display_rect.width())); |
| + float inverted_scale = 1.0f / mirror_scale_ratio; |
| + transform_.Scale(inverted_scale, inverted_scale); |
| + } |
| + |
| + // aura::RootWindowTransformer overrides: |
| + virtual gfx::Transform GetTransform() const OVERRIDE { |
| + return transform_; |
| + } |
| + virtual gfx::Transform GetInverseTransform() const OVERRIDE { |
| + gfx::Transform invert; |
| + CHECK(transform_.GetInverse(&invert)); |
| + return invert; |
| + } |
| + virtual gfx::Rect GetRootWindowBounds( |
| + const gfx::Size& host_size) const OVERRIDE { |
| + return root_bounds_; |
| + } |
| + virtual gfx::Insets GetHostInsets() const OVERRIDE { |
| + return gfx::Insets(); |
| + } |
| + |
| + private: |
| + virtual ~MirrorRootWindowTransformer() {} |
| + |
| + gfx::Transform transform_; |
| + gfx::Rect root_bounds_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MirrorRootWindowTransformer); |
| +}; |
| + |
| +} // namespace |
| -gfx::Rect AshRootWindowTransformer::GetRootWindowBounds( |
| - const gfx::Size& host_size) const { |
| - gfx::Rect bounds(host_size); |
| - bounds.Inset(host_insets_); |
| - bounds = ui::ConvertRectToDIP(root_window_->layer(), bounds); |
| - gfx::RectF new_bounds(bounds); |
| - root_window_bounds_transform_.TransformRect(&new_bounds); |
| - // Apply |root_window_scale_| twice as the downscaling |
| - // is already applied once in |SetTransformInternal()|. |
| - // TODO(oshima): This is a bit ugly. Consider specifying |
| - // the pseudo host resolution instead. |
| - new_bounds.Scale(root_window_ui_scale_ * root_window_ui_scale_); |
| - // Ignore the origin because RootWindow's insets are handled by |
| - // the transform. |
| - // Floor the size because the bounds is no longer aligned to |
| - // backing pixel when |root_window_scale_| is specified |
| - // (850 height at 1.25 scale becomes 1062.5 for example.) |
| - return gfx::Rect(gfx::ToFlooredSize(new_bounds.size())); |
| +aura::RootWindowTransformer* CreateRootWindowTransformerForDisplay( |
| + aura::RootWindow* root, |
| + const gfx::Display& display) { |
| + return new AshRootWindowTransformer(root, display); |
| } |
| -gfx::Insets AshRootWindowTransformer::GetHostInsets() const { |
| - return host_insets_; |
| +aura::RootWindowTransformer* CreateRootWindowTransformerForMirroredDisplay( |
| + const DisplayInfo& source_display_info, |
| + const DisplayInfo& mirror_display_info) { |
| + return new MirrorRootWindowTransformer(source_display_info, |
| + mirror_display_info); |
| } |
| +} // namespace internal |
| } // namespace ash |