Skip to content

Commit

Permalink
Support fractional coordinates in DCLayerOverlayParams content_rect
Browse files Browse the repository at this point in the history
We already support fractional scaling and offsets for the visual content
in a DComp subtree. This CL makes it so callers of DCLayerTree can
specify non-integral content rects.

This is a case that can happen for delegated compositing when cc submits
a frame with a tile quad that is both scaled and occluded in such a way
that the part of its image that is visible does not fall on exact pixel
boundaries.

Bug: 1132392
Change-Id: I5a10953e1fc98f9adb9f6940399915de5023b8e0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4646982
Commit-Queue: Michael Tang <tangm@microsoft.com>
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1187487}
  • Loading branch information
tangm-msft authored and Chromium LUCI CQ committed Aug 23, 2023
1 parent 47a0c79 commit ac2ea7e
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 226 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ void SkiaOutputDeviceDComp::ScheduleOverlays(
// SwapChainPresenter uses the size of the overlay's resource in pixels to
// calculate its swap chain size. `uv_rect` maps the portion of
// `resource_size_in_pixels` that will be displayed.
params->content_rect = gfx::ToNearestRect(gfx::ScaleRect(
params->content_rect = gfx::ScaleRect(
dc_layer.uv_rect, dc_layer.resource_size_in_pixels.width(),
dc_layer.resource_size_in_pixels.height()));
dc_layer.resource_size_in_pixels.height());

params->quad_rect = gfx::ToEnclosingRect(dc_layer.display_rect);
DCHECK(absl::holds_alternative<gfx::Transform>(dc_layer.transform));
Expand Down
5 changes: 3 additions & 2 deletions ui/gl/dc_layer_overlay_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ struct GL_EXPORT DCLayerOverlayParams {
int z_order = 1;

// What part of |overlay_image| to display in pixels. Ignored, if this overlay
// represents a solid color.
gfx::Rect content_rect;
// represents a solid color. Usually integral, but can be non-integral in the
// case of combining occlusion with scaling.
gfx::RectF content_rect;

// Bounds of the overlay in pre-transform space.
gfx::Rect quad_rect;
Expand Down
22 changes: 12 additions & 10 deletions ui/gl/dc_layer_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ bool DCLayerTree::VisualTree::VisualSubtree::Update(
Microsoft::WRL::ComPtr<IUnknown> dcomp_visual_content,
uint64_t dcomp_surface_serial,
const gfx::Size& image_size,
const gfx::Rect& content_rect,
const gfx::RectF& content_rect,
Microsoft::WRL::ComPtr<IDCompositionSurface> solid_white_surface,
const SkColor4f& background_color,
const gfx::Rect& quad_rect,
Expand Down Expand Up @@ -483,7 +483,7 @@ bool DCLayerTree::VisualTree::VisualSubtree::Update(
}

if (image_size_changed || content_rect_changed || quad_rect_changed) {
if (content_rect_.Contains(gfx::Rect(image_size_))) {
if (content_rect_.Contains(gfx::RectF(image_size_))) {
// No need to set clip to content if the whole image is inside the content
// rect region.
hr = content_visual_->SetClip(nullptr);
Expand All @@ -500,13 +500,14 @@ bool DCLayerTree::VisualTree::VisualSubtree::Update(
// Transform the (clipped) content so that it fills |quad_rect_|'s bounds.
// |quad_rect_|'s offset is handled below, so we exclude it from the matrix.
const bool needs_offset = !content_rect_.OffsetFromOrigin().IsZero();
const bool needs_scale = quad_rect_.width() != content_rect_.width() ||
quad_rect_.height() != content_rect_.height();
const bool needs_scale =
static_cast<float>(quad_rect_.width()) != content_rect_.width() ||
static_cast<float>(quad_rect_.height()) != content_rect_.height();
if (needs_offset || needs_scale) {
const float scale_x = static_cast<float>(quad_rect_.width()) /
static_cast<float>(content_rect_.width());
const float scale_y = static_cast<float>(quad_rect_.height()) /
static_cast<float>(content_rect_.height());
const float scale_x =
static_cast<float>(quad_rect_.width()) / content_rect_.width();
const float scale_y =
static_cast<float>(quad_rect_.height()) / content_rect_.height();
const D2D_MATRIX_3X2_F matrix =
D2D1::Matrix3x2F::Translation(-content_rect_.x(),
-content_rect_.y()) *
Expand Down Expand Up @@ -1116,7 +1117,8 @@ bool DCLayerTree::CommitAndClearPendingOverlays(
root_params->overlay_image = DCLayerOverlayImage(
root_surface->GetSize(), std::move(root_visual_content),
root_surface->dcomp_surface_serial());
root_params->content_rect = gfx::Rect(root_params->overlay_image->size());
root_params->content_rect =
gfx::RectF(root_params->overlay_image->size());
root_params->quad_rect = gfx::Rect(root_params->overlay_image->size());
ScheduleDCLayer(std::move(root_params));
} else {
Expand Down Expand Up @@ -1202,13 +1204,13 @@ bool DCLayerTree::CommitAndClearPendingOverlays(
// rect, e.g. to present to a swap chain exactly the size of the display
// rect when the source video is larger.
overlay->transform = transform;
overlay->content_rect = gfx::Rect(video_swap_chain->content_size());
overlay->quad_rect.set_size(video_swap_chain->content_size());
if (overlay->clip_rect.has_value()) {
overlay->clip_rect = clip_rect;
}
overlay->overlay_image = DCLayerOverlayImage(
video_swap_chain->content_size(), video_swap_chain->content());
overlay->content_rect = gfx::RectF(video_swap_chain->content_size());
}
}

Expand Down
4 changes: 2 additions & 2 deletions ui/gl/dc_layer_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class GL_EXPORT DCLayerTree {
Microsoft::WRL::ComPtr<IUnknown> dcomp_visual_content,
uint64_t dcomp_surface_serial,
const gfx::Size& image_size,
const gfx::Rect& content_rect,
const gfx::RectF& content_rect,
Microsoft::WRL::ComPtr<IDCompositionSurface> solid_white_surface,
const SkColor4f& background_color,
const gfx::Rect& quad_rect,
Expand Down Expand Up @@ -298,7 +298,7 @@ class GL_EXPORT DCLayerTree {

// The portion of |dcomp_visual_content_| to display. This area will be
// mapped to |quad_rect_|'s bounds.
gfx::Rect content_rect_;
gfx::RectF content_rect_;

// The surface containing solid white for the background color fill to be
// placed at a leaf of the visual subtree. Will be tinted by
Expand Down

0 comments on commit ac2ea7e

Please sign in to comment.