0

Add gfx::Transform::[Inverse]MapRect(const gfx::Rect&)

This follows blink::TransformationMatrix(const gfx::Rect&), to
prepare for combination of gfx::Transform and
blink::TransformationMatrix.

Code like the following
  gfx::RectF rect_f(rect);
  transform.TransformRect(&rect_f);
  gfx::Rect out_rect = gfx::ToEnclosingRect(rect_f);
is replaced with
  gfx::Rect out_rect = gfx::MapRect(rect);

Code in some unittests using gfx::ToRoundedRect(),
gfx::ToEnclosedRect() or gfx::ToNearestRect() instead of
gfx::ToEnclosingRect() as the last step are also replace with
the new code as long as the tests still pass. Similar code in
production code is kept as-is.

Bug: 1359528
Change-Id: Ic86333d48da459fc571240d80d513ca5efded699
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3935017
Owners-Override: danakj <danakj@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1055517}
This commit is contained in:
Xianzhu Wang
2022-10-05 22:34:54 +00:00
committed by Chromium LUCI CQ
parent 9dac27aa95
commit 901b935e43
32 changed files with 157 additions and 169 deletions

@@ -98,9 +98,12 @@ class FullscreenMagnifierControllerTest : public AshTestBase {
} }
gfx::Rect GetViewport() const { gfx::Rect GetViewport() const {
gfx::RectF bounds(0, 0, kRootWidth, kRootHeight); gfx::Rect bounds(0, 0, kRootWidth, kRootHeight);
GetRootWindow()->layer()->transform().TransformRectReverse(&bounds); return GetRootWindow()
return gfx::ToEnclosingRect(bounds); ->layer()
->transform()
.InverseMapRect(bounds)
.value_or(bounds);
} }
std::string CurrentPointOfInterest() const { std::string CurrentPointOfInterest() const {

@@ -28,17 +28,15 @@ class AppDragIconProxyTest : public AshTestBase {
~AppDragIconProxyTest() override = default; ~AppDragIconProxyTest() override = default;
gfx::Rect GetTargetAppDragIconImageBounds(AppDragIconProxy* drag_icon_proxy) { gfx::Rect GetTargetAppDragIconImageBounds(AppDragIconProxy* drag_icon_proxy) {
gfx::RectF layer_target_position( gfx::Rect layer_target_position =
drag_icon_proxy->GetImageLayerForTesting()->GetTargetBounds()); drag_icon_proxy->GetImageLayerForTesting()
drag_icon_proxy->GetImageLayerForTesting() ->GetTargetTransform()
->GetTargetTransform() .MapRect(
.TransformRect(&layer_target_position); drag_icon_proxy->GetImageLayerForTesting()->GetTargetBounds());
gfx::Rect widget_target_bounds = gfx::Rect widget_target_bounds =
drag_icon_proxy->GetWidgetForTesting()->GetLayer()->GetTargetBounds(); drag_icon_proxy->GetWidgetForTesting()->GetLayer()->GetTargetBounds();
layer_target_position.set_origin( layer_target_position.Offset(widget_target_bounds.OffsetFromOrigin());
gfx::PointF(layer_target_position.x() + widget_target_bounds.x(), return layer_target_position;
layer_target_position.y() + widget_target_bounds.y()));
return gfx::ToNearestRect(layer_target_position);
} }
}; };

@@ -90,9 +90,8 @@ void AshWindowTreeHostPlatform::ConfineCursorToBoundsInRoot(
if (!allow_confine_cursor()) if (!allow_confine_cursor())
return; return;
gfx::RectF bounds_f(bounds_in_root); last_cursor_confine_bounds_in_pixels_ =
GetRootTransform().TransformRect(&bounds_f); GetRootTransform().MapRect(bounds_in_root);
last_cursor_confine_bounds_in_pixels_ = gfx::ToEnclosingRect(bounds_f);
platform_window()->ConfineCursorToBounds( platform_window()->ConfineCursorToBounds(
last_cursor_confine_bounds_in_pixels_); last_cursor_confine_bounds_in_pixels_);
} }

@@ -108,14 +108,11 @@ gfx::Rect GetDisplayBoundsWithShelf(aura::Window* window) {
->display_configuration_controller() ->display_configuration_controller()
->GetPrimaryMirroringDisplayForUnifiedDesktop(); ->GetPrimaryMirroringDisplayForUnifiedDesktop();
DCHECK_NE(shelf_display.id(), display::kInvalidDisplayId); DCHECK_NE(shelf_display.id(), display::kInvalidDisplayId);
gfx::RectF shelf_display_screen_bounds(shelf_display.bounds());
// Transform the bounds back to the unified host's coordinates. // Transform the bounds back to the unified host's coordinates.
auto inverse_unified_transform = auto inverse_unified_transform =
window->GetRootWindow()->GetHost()->GetInverseRootTransform(); window->GetRootWindow()->GetHost()->GetInverseRootTransform();
inverse_unified_transform.TransformRect(&shelf_display_screen_bounds); return inverse_unified_transform.MapRect(shelf_display.bounds());
return gfx::ToEnclosingRect(shelf_display_screen_bounds);
} }
gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds, gfx::Rect SnapBoundsToDisplayEdge(const gfx::Rect& bounds,

@@ -130,16 +130,14 @@ class HomeToOverviewNudgeControllerTest : public AshTestBase {
ASSERT_TRUE(nudge_widget); ASSERT_TRUE(nudge_widget);
EXPECT_TRUE(nudge_widget->IsVisible()); EXPECT_TRUE(nudge_widget->IsVisible());
gfx::RectF nudge_bounds_f( const gfx::Rect nudge_bounds =
nudge_widget->GetNativeWindow()->GetTargetBounds()); nudge_widget->GetLayer()->transform().MapRect(
nudge_widget->GetLayer()->transform().TransformRect(&nudge_bounds_f); nudge_widget->GetNativeWindow()->GetTargetBounds());
const gfx::Rect nudge_bounds = gfx::ToEnclosingRect(nudge_bounds_f);
HotseatWidget* const hotseat = GetHotseatWidget(); HotseatWidget* const hotseat = GetHotseatWidget();
gfx::RectF hotseat_bounds_f(hotseat->GetNativeWindow()->GetTargetBounds()); const gfx::Rect hotseat_bounds =
hotseat->GetLayerForNudgeAnimation()->transform().TransformRect( hotseat->GetLayerForNudgeAnimation()->transform().MapRect(
&hotseat_bounds_f); hotseat->GetNativeWindow()->GetTargetBounds());
const gfx::Rect hotseat_bounds = gfx::ToEnclosingRect(hotseat_bounds_f);
// Nudge and hotseat should have the same transform. // Nudge and hotseat should have the same transform.
EXPECT_EQ(hotseat->GetLayerForNudgeAnimation()->transform(), EXPECT_EQ(hotseat->GetLayerForNudgeAnimation()->transform(),

@@ -1180,9 +1180,8 @@ void HotseatWidget::LayoutHotseatByAnimation(double target_opacity,
// between hidden and extended state use transform to animate. Clear any // between hidden and extended state use transform to animate. Clear any
// transform that may have been set by the previous animation, and update // transform that may have been set by the previous animation, and update
// current bounds to match it. // current bounds to match it.
gfx::RectF current_bounds_f(GetNativeView()->GetBoundsInScreen()); gfx::Rect current_bounds =
hotseat_layer->transform().TransformRect(&current_bounds_f); hotseat_layer->transform().MapRect(GetNativeView()->GetBoundsInScreen());
gfx::Rect current_bounds = gfx::ToEnclosingRect(current_bounds_f);
// If the bounds size has not changed, set the target bounds immediately, and // If the bounds size has not changed, set the target bounds immediately, and
// animate using transform. // animate using transform.

@@ -1024,9 +1024,8 @@ void ShelfWidget::UpdateLayout(bool animate) {
// When the |shelf_widget_| needs to reverse the direction of the current // When the |shelf_widget_| needs to reverse the direction of the current
// animation, we must take into account the transform when calculating the // animation, we must take into account the transform when calculating the
// current shelf widget bounds. // current shelf widget bounds.
gfx::RectF transformed_bounds(current_shelf_bounds); current_shelf_bounds =
GetLayer()->transform().TransformRect(&transformed_bounds); GetLayer()->transform().MapRect(current_shelf_bounds);
current_shelf_bounds = gfx::ToEnclosedRect(transformed_bounds);
} }
gfx::Transform shelf_widget_target_transform; gfx::Transform shelf_widget_target_transform;

@@ -3256,9 +3256,9 @@ TEST_F(DesksTest, AutohiddenShelfAnimatesAfterDeskSwitch) {
// Since the layer transform animation is just starting, the transformed // Since the layer transform animation is just starting, the transformed
// bounds should still be hidden. If this fails, the change was not animated. // bounds should still be hidden. If this fails, the change was not animated.
gfx::RectF transformed_bounds(shelf_widget->GetWindowBoundsInScreen()); gfx::Rect transformed_bounds = shelf_widget->GetLayer()->transform().MapRect(
shelf_widget->GetLayer()->transform().TransformRect(&transformed_bounds); shelf_widget->GetWindowBoundsInScreen());
EXPECT_EQ(gfx::ToEnclosedRect(transformed_bounds), hidden_shelf_bounds); EXPECT_EQ(transformed_bounds, hidden_shelf_bounds);
EXPECT_EQ(shelf_widget->GetWindowBoundsInScreen(), shown_shelf_bounds); EXPECT_EQ(shelf_widget->GetWindowBoundsInScreen(), shown_shelf_bounds);
// Let's wait until the shelf animates to a fully shown state. // Let's wait until the shelf animates to a fully shown state.

@@ -53,9 +53,7 @@ gfx::Rect GetVisibleBounds(ui::Layer* child_layer,
use_target_transform ? animating_layer->GetTargetTransform() use_target_transform ? animating_layer->GetTargetTransform()
: animating_layer->transform(); : animating_layer->transform();
DCHECK(animating_layer_transform.IsIdentityOr2DTranslation()); DCHECK(animating_layer_transform.IsIdentityOr2DTranslation());
gfx::RectF bounds(child_layer->bounds()); return animating_layer_transform.MapRect(child_layer->bounds());
animating_layer_transform.TransformRect(&bounds);
return gfx::ToRoundedRect(bounds);
} }
gfx::Rect GetTargetVisibleBounds(ui::Layer* child_layer, gfx::Rect GetTargetVisibleBounds(ui::Layer* child_layer,

@@ -4797,9 +4797,8 @@ TEST_F(SplitViewOverviewSessionTest, Clipping) {
EXPECT_FALSE(preview_layer->clip_rect().IsEmpty()); EXPECT_FALSE(preview_layer->clip_rect().IsEmpty());
EXPECT_FALSE(preview_layer->transform().IsIdentity()); EXPECT_FALSE(preview_layer->transform().IsIdentity());
// The clip rect is affected by |preview_layer|'s transform so apply it. // The clip rect is affected by |preview_layer|'s transform so apply it.
gfx::RectF clip_rect3_f(preview_layer->clip_rect()); const gfx::Rect clip_rects3 =
preview_layer->transform().TransformRect(&clip_rect3_f); preview_layer->transform().MapRect(preview_layer->clip_rect());
const gfx::Rect clip_rects3 = gfx::ToEnclosedRect(clip_rect3_f);
EXPECT_TRUE(aspect_ratio_near(clip_rects3, split_view_bounds_right)); EXPECT_TRUE(aspect_ratio_near(clip_rects3, split_view_bounds_right));
EXPECT_TRUE(aspect_ratio_near( EXPECT_TRUE(aspect_ratio_near(
gfx::ToEnclosedRect(item3->GetWindowTargetBoundsWithInsets()), gfx::ToEnclosedRect(item3->GetWindowTargetBoundsWithInsets()),

@@ -99,7 +99,6 @@ gfx::Rect OverviewTestBase::GetTransformedTargetBounds(aura::Window* window) {
gfx::Rect OverviewTestBase::GetTransformedBoundsInRootWindow( gfx::Rect OverviewTestBase::GetTransformedBoundsInRootWindow(
aura::Window* window) { aura::Window* window) {
gfx::RectF bounds = gfx::RectF(gfx::SizeF(window->bounds().size()));
aura::Window* root = window->GetRootWindow(); aura::Window* root = window->GetRootWindow();
CHECK(window->layer()); CHECK(window->layer());
CHECK(root->layer()); CHECK(root->layer());
@@ -108,8 +107,7 @@ gfx::Rect OverviewTestBase::GetTransformedBoundsInRootWindow(
&transform)) { &transform)) {
return gfx::Rect(); return gfx::Rect();
} }
transform.TransformRect(&bounds); return transform.MapRect(gfx::Rect(window->bounds().size()));
return gfx::ToEnclosingRect(bounds);
} }
OverviewItem* OverviewTestBase::GetDropTarget(int grid_index) { OverviewItem* OverviewTestBase::GetDropTarget(int grid_index) {

@@ -1244,7 +1244,7 @@ TEST_P(SurfaceTest, ScaledSurfaceQuad) {
->quad_list.back() ->quad_list.back()
->shared_quad_state->clip_rect); ->shared_quad_state->clip_rect);
auto testing_rect = gfx::RectF(gfx::PointF(0, 0), gfx::SizeF(256, 256)); gfx::Rect testing_rect(256, 256);
// To get 32,32 -> 160,160 into the correct position it must be translated // To get 32,32 -> 160,160 into the correct position it must be translated
// backwards and scaled 0.5x in Y, then everything is scaled by the scale // backwards and scaled 0.5x in Y, then everything is scaled by the scale
// factor. // factor.
@@ -1258,8 +1258,7 @@ TEST_P(SurfaceTest, ScaledSurfaceQuad) {
if (gfx::Transform() == frame.render_pass_list.back() if (gfx::Transform() == frame.render_pass_list.back()
->quad_list.back() ->quad_list.back()
->shared_quad_state->quad_to_target_transform) { ->shared_quad_state->quad_to_target_transform) {
expected_transform.TransformRect(&testing_rect); auto expected_rect = expected_transform.MapRect(testing_rect);
auto expected_rect = gfx::ToNearestRect(testing_rect);
EXPECT_EQ(expected_rect, EXPECT_EQ(expected_rect,
frame.render_pass_list.back()->quad_list.back()->rect); frame.render_pass_list.back()->quad_list.back()->rect);
} else { } else {
@@ -1267,7 +1266,7 @@ TEST_P(SurfaceTest, ScaledSurfaceQuad) {
frame.render_pass_list.back() frame.render_pass_list.back()
->quad_list.back() ->quad_list.back()
->shared_quad_state->quad_to_target_transform); ->shared_quad_state->quad_to_target_transform);
EXPECT_EQ(gfx::ToNearestRect(testing_rect), EXPECT_EQ(testing_rect,
frame.render_pass_list.back()->quad_list.back()->rect); frame.render_pass_list.back()->quad_list.back()->rect);
} }
} }

@@ -152,9 +152,8 @@ void FromYUVQuad(const YUVVideoDrawQuad* quad,
if (quad->shared_quad_state->clip_rect) { if (quad->shared_quad_state->clip_rect) {
// Clip rect is in quad target space, and must be transformed to root target // Clip rect is in quad target space, and must be transformed to root target
// space. // space.
gfx::RectF clip_rect = gfx::RectF(*quad->shared_quad_state->clip_rect); dc_layer->clip_rect =
transform_to_root_target.TransformRect(&clip_rect); transform_to_root_target.MapRect(*quad->shared_quad_state->clip_rect);
dc_layer->clip_rect = gfx::ToEnclosingRect(clip_rect);
} }
dc_layer->color_space = quad->video_color_space; dc_layer->color_space = quad->video_color_space;
dc_layer->protected_video_type = quad->protected_video_type; dc_layer->protected_video_type = quad->protected_video_type;
@@ -214,10 +213,8 @@ void FromTextureQuad(const TextureDrawQuad* quad,
if (quad->shared_quad_state->clip_rect) { if (quad->shared_quad_state->clip_rect) {
// Clip rect is in quad target space, and must be transformed to root target // Clip rect is in quad target space, and must be transformed to root target
// space. // space.
gfx::RectF clip_rect = dc_layer->clip_rect = transform_to_root_target.MapRect(
gfx::RectF(quad->shared_quad_state->clip_rect.value_or(gfx::Rect())); quad->shared_quad_state->clip_rect.value_or(gfx::Rect()));
transform_to_root_target.TransformRect(&clip_rect);
dc_layer->clip_rect = gfx::ToEnclosingRect(clip_rect);
} }
dc_layer->color_space = gfx::ColorSpace::CreateSRGB(); dc_layer->color_space = gfx::ColorSpace::CreateSRGB();
@@ -627,10 +624,9 @@ void DCLayerOverlayProcessor::InsertDebugBorderDrawQuad(
// Add debug borders for overlays/underlays // Add debug borders for overlays/underlays
for (const auto& dc_layer : *dc_layer_overlays) { for (const auto& dc_layer : *dc_layer_overlays) {
gfx::RectF overlay_rect(dc_layer.quad_rect); gfx::Rect overlay_rect = dc_layer.transform.MapRect(dc_layer.quad_rect);
dc_layer.transform.TransformRect(&overlay_rect);
if (dc_layer.clip_rect) if (dc_layer.clip_rect)
overlay_rect.Intersect(gfx::RectF(*dc_layer.clip_rect)); overlay_rect.Intersect(*dc_layer.clip_rect);
// Overlay:red, Underlay:blue. // Overlay:red, Underlay:blue.
SkColor4f border_color = SkColor4f border_color =
@@ -640,10 +636,9 @@ void DCLayerOverlayProcessor::InsertDebugBorderDrawQuad(
quad_list.begin(), 1u); quad_list.begin(), 1u);
auto* debug_quad = static_cast<DebugBorderDrawQuad*>(*it); auto* debug_quad = static_cast<DebugBorderDrawQuad*>(*it);
gfx::Rect rect = gfx::ToEnclosingRect(overlay_rect); overlay_rect.Inset(kDCLayerDebugBorderInsets);
rect.Inset(kDCLayerDebugBorderInsets); debug_quad->SetNew(shared_quad_state, overlay_rect, overlay_rect,
debug_quad->SetNew(shared_quad_state, rect, rect, border_color, border_color, kDCLayerDebugBorderWidth);
kDCLayerDebugBorderWidth);
} }
// Mark the entire output as damaged because the border quads might not be // Mark the entire output as damaged because the border quads might not be

@@ -145,9 +145,7 @@ gfx::Rect OverlayProcessorSurfaceControl::GetOverlayDamageRectForOutputSurface(
viewport_size_.width()); viewport_size_.width());
auto transform = gfx::OverlayTransformToTransform( auto transform = gfx::OverlayTransformToTransform(
display_transform_, gfx::SizeF(viewport_size_pre_display_transform)); display_transform_, gfx::SizeF(viewport_size_pre_display_transform));
gfx::RectF transformed_rect(candidate.display_rect); return transform.MapRect(gfx::ToEnclosingRect(candidate.display_rect));
transform.TransformRect(&transformed_rect);
return gfx::ToEnclosedRect(transformed_rect);
} }
void OverlayProcessorSurfaceControl::SetDisplayTransformHint( void OverlayProcessorSurfaceControl::SetDisplayTransformHint(

@@ -66,8 +66,7 @@ bool OverlayStrategyUnderlayCast::Attempt(
continue; continue;
const auto& transform = quad->shared_quad_state->quad_to_target_transform; const auto& transform = quad->shared_quad_state->quad_to_target_transform;
gfx::RectF quad_rect = gfx::RectF(quad->rect); gfx::Rect quad_rect = transform.MapRect(quad->rect);
transform.TransformRect(&quad_rect);
bool is_underlay = false; bool is_underlay = false;
if (!found_underlay) { if (!found_underlay) {
@@ -93,9 +92,9 @@ bool OverlayStrategyUnderlayCast::Attempt(
} }
if (is_underlay) { if (is_underlay) {
content_rect.Subtract(gfx::ToEnclosedRect(quad_rect)); content_rect.Subtract(quad_rect);
} else { } else {
content_rect.Union(gfx::ToEnclosingRect(quad_rect)); content_rect.Union(quad_rect);
} }
} }
@@ -197,8 +196,7 @@ bool OverlayStrategyUnderlayCast::AttemptPrioritized(
continue; continue;
const auto& transform = quad->shared_quad_state->quad_to_target_transform; const auto& transform = quad->shared_quad_state->quad_to_target_transform;
gfx::RectF quad_rect = gfx::RectF(quad->rect); gfx::Rect quad_rect = transform.MapRect(quad->rect);
transform.TransformRect(&quad_rect);
bool is_underlay = false; bool is_underlay = false;
if (!found_underlay) { if (!found_underlay) {
@@ -224,9 +222,9 @@ bool OverlayStrategyUnderlayCast::AttemptPrioritized(
} }
if (is_underlay) { if (is_underlay) {
content_rect.Subtract(gfx::ToEnclosedRect(quad_rect)); content_rect.Subtract(quad_rect);
} else { } else {
content_rect.Union(gfx::ToEnclosingRect(quad_rect)); content_rect.Union(quad_rect);
} }
} }

@@ -2406,7 +2406,7 @@ void SurfaceAggregator::CreateDeJellyRenderPassQuads(
// Compute the required renderpass rect in target space. // Compute the required renderpass rect in target space.
// First, find the un-transformed visible rect. // First, find the un-transformed visible rect.
gfx::RectF render_pass_visible_rect_f(state->visible_quad_layer_rect); gfx::Rect render_pass_visible_rect = state->visible_quad_layer_rect;
// Next, if this is a RenderPass quad, find any filters and expand the // Next, if this is a RenderPass quad, find any filters and expand the
// visible rect. // visible rect.
if (quad->material == DrawQuad::Material::kCompositorRenderPass) { if (quad->material == DrawQuad::Material::kCompositorRenderPass) {
@@ -2414,16 +2414,15 @@ void SurfaceAggregator::CreateDeJellyRenderPassQuads(
CompositorRenderPassDrawQuad::MaterialCast(quad)->render_pass_id}); CompositorRenderPassDrawQuad::MaterialCast(quad)->render_pass_id});
for (auto& rp : *dest_pass_list_) { for (auto& rp : *dest_pass_list_) {
if (rp->id == target_id) { if (rp->id == target_id) {
render_pass_visible_rect_f = gfx::RectF( render_pass_visible_rect =
rp->filters.MapRect(state->visible_quad_layer_rect, SkMatrix())); rp->filters.MapRect(state->visible_quad_layer_rect, SkMatrix());
break; break;
} }
} }
} }
// Next, find the enclosing Rect for the transformed target space RectF. // Next, find the enclosing Rect for the transformed target space RectF.
state->quad_to_target_transform.TransformRect(&render_pass_visible_rect_f); render_pass_visible_rect =
gfx::Rect render_pass_visible_rect = state->quad_to_target_transform.MapRect(render_pass_visible_rect);
gfx::ToEnclosingRect(render_pass_visible_rect_f);
// Finally, expand by our un_clip amounts. // Finally, expand by our un_clip amounts.
render_pass_visible_rect.Inset( render_pass_visible_rect.Inset(
gfx::Insets::TLBR(-un_clip_top, 0, -un_clip_bottom, 0)); gfx::Insets::TLBR(-un_clip_top, 0, -un_clip_bottom, 0));

@@ -3763,11 +3763,8 @@ bool TransformPointAndRectToRootView(RenderWidgetHostViewBase* view,
if (transformed_point) if (transformed_point)
*transformed_point = transform_to_main_frame.MapPoint(*transformed_point); *transformed_point = transform_to_main_frame.MapPoint(*transformed_point);
if (transformed_rect) { if (transformed_rect)
gfx::RectF transformed_rect_f(*transformed_rect); *transformed_rect = transform_to_main_frame.MapRect(*transformed_rect);
transform_to_main_frame.TransformRect(&transformed_rect_f);
*transformed_rect = gfx::ToEnclosingRect(transformed_rect_f);
}
return true; return true;
} }

@@ -6938,9 +6938,7 @@ class SitePerProcessHitTestDataGenerationBrowserTest
gfx::Rect AxisAlignedLayoutRectFromHitTest( gfx::Rect AxisAlignedLayoutRectFromHitTest(
const viz::AggregatedHitTestRegion& hit_test_region) { const viz::AggregatedHitTestRegion& hit_test_region) {
DCHECK(hit_test_region.transform.Preserves2dAxisAlignment()); DCHECK(hit_test_region.transform.Preserves2dAxisAlignment());
gfx::RectF rect(hit_test_region.rect); return hit_test_region.transform.MapRect(hit_test_region.rect);
hit_test_region.transform.TransformRect(&rect);
return gfx::ToEnclosingRect(rect);
} }
public: public:

@@ -2104,13 +2104,8 @@ void LocalFrame::SetViewportIntersectionFromParent(
intersection_state.main_frame_intersection || intersection_state.main_frame_intersection ||
intersection_state_.main_frame_transform != intersection_state_.main_frame_transform !=
intersection_state.main_frame_transform) { intersection_state.main_frame_transform) {
gfx::RectF transform_rect = gfx::Rect rect = intersection_state.main_frame_transform.MapRect(
gfx::RectF(gfx::Rect(intersection_state.main_frame_intersection)); intersection_state.main_frame_intersection);
intersection_state.main_frame_transform.TransformRect(&transform_rect);
gfx::Rect rect = ToEnclosingRect(
gfx::RectF(transform_rect.x(), transform_rect.y(),
transform_rect.width(), transform_rect.height()));
// Return <0, 0, 0, 0> if there is no area. // Return <0, 0, 0, 0> if there is no area.
if (rect.IsEmpty()) if (rect.IsEmpty())

@@ -100,10 +100,8 @@ SkIRect ComputeClippedAndTransformedBounds(
const gfx::Transform& transform_relative_to_root, const gfx::Transform& transform_relative_to_root,
const SkIRect* clipped_bounds) { const SkIRect* clipped_bounds) {
DCHECK(transform_relative_to_root.Preserves2dAxisAlignment()); DCHECK(transform_relative_to_root.Preserves2dAxisAlignment());
gfx::RectF transformed_bounds(bounds); gfx::Rect transformed_bounds = transform_relative_to_root.MapRect(bounds);
transform_relative_to_root.TransformRect(&transformed_bounds); SkIRect skirect_bounds = gfx::RectToSkIRect(transformed_bounds);
SkIRect skirect_bounds =
gfx::RectToSkIRect(gfx::ToEnclosedRect(transformed_bounds));
// If necessary, clip the bounds. // If necessary, clip the bounds.
if (clipped_bounds && !skirect_bounds.intersect(*clipped_bounds)) if (clipped_bounds && !skirect_bounds.intersect(*clipped_bounds))
return SkIRect::MakeEmpty(); return SkIRect::MakeEmpty();

@@ -736,9 +736,7 @@ void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display,
gfx::Rect WindowTreeHost::GetTransformedRootWindowBoundsFromPixelSize( gfx::Rect WindowTreeHost::GetTransformedRootWindowBoundsFromPixelSize(
const gfx::Size& size_in_pixels) const { const gfx::Size& size_in_pixels) const {
gfx::RectF new_bounds = gfx::RectF(gfx::Rect(size_in_pixels)); return GetInverseRootTransform().MapRect(gfx::Rect(size_in_pixels));
GetInverseRootTransform().TransformRect(&new_bounds);
return gfx::ToEnclosingRect(new_bounds);
} }
void WindowTreeHost::SetNativeWindowOcclusionEnabled(bool enable) { void WindowTreeHost::SetNativeWindowOcclusionEnabled(bool enable) {

@@ -3752,9 +3752,7 @@ class WindowActualScreenBoundsTest
void OnTranslationAnimationProgressed(const gfx::Rect& child_initial_bounds, void OnTranslationAnimationProgressed(const gfx::Rect& child_initial_bounds,
const gfx::Transform& transform) const { const gfx::Transform& transform) const {
gfx::RectF current_screen_bounds(child_initial_bounds); EXPECT_EQ(transform.MapRect(child_initial_bounds),
transform.TransformRect(&current_screen_bounds);
EXPECT_EQ(gfx::ToEnclosedRect(current_screen_bounds),
child_->GetActualBoundsInScreen()); child_->GetActualBoundsInScreen());
} }

@@ -13,6 +13,7 @@
#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/quaternion.h" #include "ui/gfx/geometry/quaternion.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rrect_f.h" #include "ui/gfx/geometry/rrect_f.h"
#include "ui/gfx/geometry/skia_conversions.h" #include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gfx/geometry/transform_util.h" #include "ui/gfx/geometry/transform_util.h"
@@ -496,6 +497,15 @@ void Transform::TransformRect(RectF* rect) const {
*rect = SkRectToRectF(src); *rect = SkRectToRectF(src);
} }
Rect Transform::MapRect(const Rect& rect) const {
if (IsIdentity())
return rect;
RectF rect_f(rect);
TransformRect(&rect_f);
return ToEnclosingRect(rect_f);
}
bool Transform::TransformRectReverse(RectF* rect) const { bool Transform::TransformRectReverse(RectF* rect) const {
if (IsIdentity()) if (IsIdentity())
return true; return true;
@@ -510,6 +520,16 @@ bool Transform::TransformRectReverse(RectF* rect) const {
return true; return true;
} }
absl::optional<Rect> Transform::InverseMapRect(const Rect& rect) const {
if (IsIdentity())
return rect;
RectF rect_f(rect);
if (TransformRectReverse(&rect_f))
return ToEnclosingRect(rect_f);
return absl::nullopt;
}
bool Transform::TransformRRectF(RRectF* rrect) const { bool Transform::TransformRRectF(RRectF* rrect) const {
// We want this to fail only in cases where our // We want this to fail only in cases where our
// Transform::Preserves2dAxisAlignment returns false. However, // Transform::Preserves2dAxisAlignment returns false. However,

@@ -18,6 +18,7 @@ namespace gfx {
class AxisTransform2d; class AxisTransform2d;
class BoxF; class BoxF;
class Rect;
class RectF; class RectF;
class RRectF; class RRectF;
class Point; class Point;
@@ -334,12 +335,14 @@ class GEOMETRY_SKIA_EXPORT Transform {
// |rect| will be the smallest axis aligned bounding rect containing the // |rect| will be the smallest axis aligned bounding rect containing the
// transformed rect. // transformed rect.
void TransformRect(RectF* rect) const; void TransformRect(RectF* rect) const;
[[nodiscard]] Rect MapRect(const Rect& rect) const;
// Applies the reverse transformation on the given rect. After the function // Applies the reverse transformation on the given rect. After the function
// completes, |rect| will be the smallest axis aligned bounding rect // completes, |rect| will be the smallest axis aligned bounding rect
// containing the transformed rect. Returns false if the matrix cannot be // containing the transformed rect. Returns false if the matrix cannot be
// inverted. // inverted.
bool TransformRectReverse(RectF* rect) const; bool TransformRectReverse(RectF* rect) const;
[[nodiscard]] absl::optional<Rect> InverseMapRect(const Rect& rect) const;
// Applies transformation on the given |rrect|. Returns false if the transform // Applies transformation on the given |rrect|. Returns false if the transform
// matrix cannot be applied to rrect. // matrix cannot be applied to rrect.

@@ -2752,27 +2752,56 @@ TEST(XFormTest, To2dTranslation) {
} }
TEST(XFormTest, TransformRect) { TEST(XFormTest, TransformRect) {
Transform translation; auto translation = Transform::MakeTranslation(3.25f, 7.75f);
translation.Translate(3.f, 7.f); RectF rect(1.25f, 2.5f, 3.75f, 4.f);
RectF rect(1.f, 2.f, 3.f, 4.f); RectF expected(4.5f, 10.25f, 3.75f, 4.f);
RectF expected(4.f, 9.f, 3.f, 4.f);
translation.TransformRect(&rect); translation.TransformRect(&rect);
EXPECT_EQ(expected.ToString(), rect.ToString()); EXPECT_EQ(expected, rect);
expected = rect;
Transform().TransformRect(&rect);
EXPECT_EQ(expected, rect);
auto singular = Transform::MakeScale(0.f);
singular.TransformRect(&rect);
EXPECT_EQ(RectF(0, 0, 0, 0), rect);
}
TEST(XFormTest, MapIntRect) {
auto translation = Transform::MakeTranslation(3.25f, 7.75f);
EXPECT_EQ(Rect(4, 9, 4, 5), translation.MapRect(Rect(1, 2, 3, 4)));
EXPECT_EQ(Rect(1, 2, 3, 4), Transform().MapRect(Rect(1, 2, 3, 4)));
auto singular = Transform::MakeScale(0.f);
EXPECT_EQ(Rect(0, 0, 0, 0), singular.MapRect(Rect(1, 2, 3, 4)));
} }
TEST(XFormTest, TransformRectReverse) { TEST(XFormTest, TransformRectReverse) {
Transform translation; auto translation = Transform::MakeTranslation(3.25f, 7.75f);
translation.Translate(3.f, 7.f); RectF rect(1.25f, 2.5f, 3.75f, 4.f);
RectF rect(1.f, 2.f, 3.f, 4.f); RectF expected(-2.f, -5.25f, 3.75f, 4.f);
RectF expected(-2.f, -5.f, 3.f, 4.f);
EXPECT_TRUE(translation.TransformRectReverse(&rect)); EXPECT_TRUE(translation.TransformRectReverse(&rect));
EXPECT_EQ(expected.ToString(), rect.ToString()); EXPECT_EQ(expected.ToString(), rect.ToString());
Transform singular; expected = rect;
singular.Scale3d(0.f, 0.f, 0.f); EXPECT_TRUE(Transform().TransformRectReverse(&rect));
EXPECT_EQ(expected, rect);
auto singular = Transform::MakeScale(0.f);
EXPECT_FALSE(singular.TransformRectReverse(&rect)); EXPECT_FALSE(singular.TransformRectReverse(&rect));
} }
TEST(XFormTest, InverseMapIntRect) {
auto translation = Transform::MakeTranslation(3.25f, 7.75f);
EXPECT_EQ(Rect(-3, -6, 4, 5), translation.InverseMapRect(Rect(1, 2, 3, 4)));
EXPECT_EQ(Rect(1, 2, 3, 4), Transform().InverseMapRect(Rect(1, 2, 3, 4)));
auto singular = Transform::MakeScale(0.f);
EXPECT_FALSE(singular.InverseMapRect(Rect(1, 2, 3, 4)));
}
TEST(XFormTest, TransformRRectF) { TEST(XFormTest, TransformRRectF) {
Transform translation; Transform translation;
translation.Translate(-3.f, -7.f); translation.Translate(-3.f, -7.f);

@@ -1232,9 +1232,7 @@ TEST_F(DirectCompositionPixelTest, ResizeVideoLayer) {
// chain to |new_on_screen_rect| which fits the monitor. // chain to |new_on_screen_rect| which fits the monitor.
surface_->GetSwapChainVisualInfoForTesting(0, &transform, &offset, surface_->GetSwapChainVisualInfoForTesting(0, &transform, &offset,
&clip_rect); &clip_rect);
gfx::RectF new_on_screen_rect = gfx::RectF(100, 100); EXPECT_EQ(gfx::Rect(monitor_size), transform.MapRect(gfx::Rect(100, 100)));
transform.TransformRect(&new_on_screen_rect);
EXPECT_EQ(gfx::Rect(monitor_size), gfx::ToEnclosingRect(new_on_screen_rect));
} }
TEST_F(DirectCompositionPixelTest, SwapChainImage) { TEST_F(DirectCompositionPixelTest, SwapChainImage) {

@@ -568,15 +568,11 @@ bool SwapChainPresenter::AdjustSwapChainToFullScreenSizeIfNeeded(
visual_transform->PostTranslate(-new_origin.OffsetFromOrigin()); visual_transform->PostTranslate(-new_origin.OffsetFromOrigin());
} }
#if DCHECK_IS_ON()
// The new transform matrix should transform the swap chain to the monitor // The new transform matrix should transform the swap chain to the monitor
// rect. // rect.
gfx::Rect new_swap_chain_rect = gfx::Rect(*swap_chain_size); DCHECK_EQ(visual_transform->MapRect(
new_swap_chain_rect.set_origin(params.quad_rect.origin()); gfx::Rect(params.quad_rect.origin(), *swap_chain_size)),
gfx::RectF new_onscreen_rect(new_swap_chain_rect); gfx::Rect(monitor_size));
visual_transform->TransformRect(&new_onscreen_rect);
DCHECK_EQ(gfx::ToEnclosingRect(new_onscreen_rect), gfx::Rect(monitor_size));
#endif
return true; return true;
} }
@@ -655,11 +651,8 @@ void SwapChainPresenter::AdjustSwapChainForFullScreenLetterboxing(
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
// The new transform matrix should transform the swap chain correctly // The new transform matrix should transform the swap chain correctly
gfx::Rect new_swap_chain_rect = gfx::Rect(*swap_chain_size); gfx::Rect new_swap_chain_rect(params.quad_rect.origin(), *swap_chain_size);
new_swap_chain_rect.set_origin(params.quad_rect.origin()); gfx::Rect result_rect = visual_transform->MapRect(new_swap_chain_rect);
gfx::RectF new_onscreen_rect(new_swap_chain_rect);
visual_transform->TransformRect(&new_onscreen_rect);
gfx::Rect result_rect = gfx::ToEnclosingRect(new_onscreen_rect);
if (IsWithinMargin(clipped_onscreen_rect.x(), 0)) { if (IsWithinMargin(clipped_onscreen_rect.x(), 0)) {
DCHECK_EQ(result_rect.x(), 0); DCHECK_EQ(result_rect.x(), 0);
DCHECK_EQ(result_rect.width(), monitor_size.width()); DCHECK_EQ(result_rect.width(), monitor_size.width());
@@ -683,11 +676,9 @@ gfx::Size SwapChainPresenter::CalculateSwapChainSize(
gfx::Size swap_chain_size = params.content_rect.size(); gfx::Size swap_chain_size = params.content_rect.size();
if (swap_chain_size.IsEmpty()) if (swap_chain_size.IsEmpty())
return gfx::Size(); return gfx::Size();
gfx::RectF bounds(params.quad_rect); if (params.quad_rect.IsEmpty())
if (bounds.IsEmpty())
return gfx::Size(); return gfx::Size();
params.transform.TransformRect(&bounds); gfx::Rect overlay_onscreen_rect = params.transform.MapRect(params.quad_rect);
gfx::Rect overlay_onscreen_rect = gfx::ToEnclosingRect(bounds);
// If transform isn't a scale or translation then swap chain can't be promoted // If transform isn't a scale or translation then swap chain can't be promoted
// to an overlay so avoid blitting to a large surface unnecessarily. Also, // to an overlay so avoid blitting to a large surface unnecessarily. Also,
@@ -1266,9 +1257,7 @@ bool SwapChainPresenter::PresentDCOMPSurface(
dcomp_surface_proxy->SetParentWindow(layer_tree_->window()); dcomp_surface_proxy->SetParentWindow(layer_tree_->window());
// Apply transform to video and notify DCOMPTexture. // Apply transform to video and notify DCOMPTexture.
gfx::RectF on_screen_bounds(params.quad_rect); dcomp_surface_proxy->SetRect(params.transform.MapRect(params.quad_rect));
params.transform.TransformRect(&on_screen_bounds);
dcomp_surface_proxy->SetRect(gfx::ToEnclosingRect(on_screen_bounds));
// If |dcomp_surface_proxy| size is {1, 1}, the texture was initialized // If |dcomp_surface_proxy| size is {1, 1}, the texture was initialized
// without knowledge of output size; reset |content_| so it's not added to the // without knowledge of output size; reset |content_| so it's not added to the

@@ -2123,9 +2123,7 @@ TEST_P(WaylandWindowTest, WaylandPopupInitialBufferScale) {
const int32_t effective_scale = entered_output.output->GetScale(); const int32_t effective_scale = entered_output.output->GetScale();
gfx::Transform transform; gfx::Transform transform;
transform.Scale(effective_scale, effective_scale); transform.Scale(effective_scale, effective_scale);
gfx::RectF rect_in_pixels = gfx::RectF(bounds_dip); gfx::Rect wayland_popup_bounds = transform.MapRect(bounds_dip);
transform.TransformRect(&rect_in_pixels);
gfx::Rect wayland_popup_bounds = gfx::ToEnclosingRect(rect_in_pixels);
std::unique_ptr<WaylandWindow> wayland_popup = std::unique_ptr<WaylandWindow> wayland_popup =
CreateWaylandWindowWithParams(PlatformWindowType::kMenu, CreateWaylandWindowWithParams(PlatformWindowType::kMenu,

@@ -106,13 +106,10 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle,
DCHECK(host); DCHECK(host);
HWND hwnd = host->GetAcceleratedWidget(); HWND hwnd = host->GetAcceleratedWidget();
gfx::RectF window_bounds_in_pixels(window_bounds); gfx::Rect snapshot_bounds_in_pixels =
host->GetRootTransform().TransformRect(&window_bounds_in_pixels); host->GetRootTransform().MapRect(snapshot_bounds);
gfx::RectF snapshot_bounds_in_pixels(snapshot_bounds);
host->GetRootTransform().TransformRect(&snapshot_bounds_in_pixels);
gfx::Rect expanded_window_bounds_in_pixels = gfx::Rect expanded_window_bounds_in_pixels =
gfx::ToEnclosingRect(window_bounds_in_pixels); host->GetRootTransform().MapRect(window_bounds);
RECT client_area; RECT client_area;
::GetClientRect(hwnd, &client_area); ::GetClientRect(hwnd, &client_area);
gfx::Rect client_area_rect(client_area); gfx::Rect client_area_rect(client_area);
@@ -120,9 +117,8 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle,
expanded_window_bounds_in_pixels.Intersect(client_area_rect); expanded_window_bounds_in_pixels.Intersect(client_area_rect);
return internal::GrabHwndSnapshot( return internal::GrabHwndSnapshot(hwnd, snapshot_bounds_in_pixels,
hwnd, gfx::ToEnclosingRect(snapshot_bounds_in_pixels), expanded_window_bounds_in_pixels, image);
expanded_window_bounds_in_pixels, image);
} }
void GrabWindowSnapshotAsync(gfx::NativeWindow window, void GrabWindowSnapshotAsync(gfx::NativeWindow window,

@@ -514,11 +514,10 @@ gfx::Rect View::GetVisibleBounds() const {
} }
if (vis_bounds.IsEmpty()) if (vis_bounds.IsEmpty())
return vis_bounds; return vis_bounds;
// Convert back to this views coordinate system. // Convert back to this views coordinate system. This mapping returns the
gfx::RectF views_vis_bounds(vis_bounds); // enclosing rect, which is good because partially visible pixels should
transform.TransformRectReverse(&views_vis_bounds); // be considered visible.
// Partially visible pixels should be considered visible. return transform.InverseMapRect(vis_bounds).value_or(vis_bounds);
return gfx::ToEnclosingRect(views_vis_bounds);
} }
gfx::Rect View::GetBoundsInScreen() const { gfx::Rect View::GetBoundsInScreen() const {
@@ -1114,11 +1113,11 @@ void View::ConvertRectToScreen(const View* src, gfx::Rect* rect) {
} }
gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const { gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
gfx::RectF x_rect = gfx::RectF(rect); // This mapping returns the enclosing rect, which is good because pixels that
GetTransform().TransformRect(&x_rect); // partially occupy in the parent should be included.
gfx::Rect x_rect = GetTransform().MapRect(rect);
x_rect.Offset(GetMirroredPosition().OffsetFromOrigin()); x_rect.Offset(GetMirroredPosition().OffsetFromOrigin());
// Pixels we partially occupy in the parent should be included. return x_rect;
return gfx::ToEnclosingRect(x_rect);
} }
gfx::Rect View::ConvertRectToWidget(const gfx::Rect& rect) const { gfx::Rect View::ConvertRectToWidget(const gfx::Rect& rect) const {

@@ -952,16 +952,14 @@ void DesktopWindowTreeHostPlatform::OnWorkspaceChanged() {
gfx::Rect DesktopWindowTreeHostPlatform::ToDIPRect( gfx::Rect DesktopWindowTreeHostPlatform::ToDIPRect(
const gfx::Rect& rect_in_pixels) const { const gfx::Rect& rect_in_pixels) const {
gfx::RectF rect_in_dip = gfx::RectF(rect_in_pixels); return GetRootTransform()
GetRootTransform().TransformRectReverse(&rect_in_dip); .InverseMapRect(rect_in_pixels)
return gfx::ToEnclosingRect(rect_in_dip); .value_or(rect_in_pixels);
} }
gfx::Rect DesktopWindowTreeHostPlatform::ToPixelRect( gfx::Rect DesktopWindowTreeHostPlatform::ToPixelRect(
const gfx::Rect& rect_in_dip) const { const gfx::Rect& rect_in_dip) const {
gfx::RectF rect_in_pixels = gfx::RectF(rect_in_dip); return GetRootTransform().MapRect(rect_in_dip);
GetRootTransform().TransformRect(&rect_in_pixels);
return gfx::ToEnclosingRect(rect_in_pixels);
} }
Widget* DesktopWindowTreeHostPlatform::GetWidget() { Widget* DesktopWindowTreeHostPlatform::GetWidget() {

@@ -248,10 +248,7 @@ gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer,
gfx::Transform in_world = transform; gfx::Transform in_world = transform;
GetTransformRelativeToRoot(layer, &in_world); GetTransformRelativeToRoot(layer, &in_world);
gfx::RectF transformed = gfx::RectF(layer->bounds()); return in_world.MapRect(layer->bounds());
in_world.TransformRect(&transformed);
return gfx::ToEnclosingRect(transformed);
} }
// Augment the host window so that the enclosing bounds of the full // Augment the host window so that the enclosing bounds of the full