Commit ea38ede3 authored by Jennifer Apacible's avatar Jennifer Apacible Committed by Commit Bot

[cc::SurfaceLayer] Allow cc::SurfaceLayer to stretch content via ui::Layer.

ui::Layer has a cc::SurfaceLayer and can set its primary surface. This
change allows ui::Layer to also set whether or not cc::SurfaceLayer
should stretch its content to fill the surface bounds, which will either
stretch or shrink to fit the surface.

This change is driven by the intent for Picture-in-Picture to be able
to scale the video (contents) to fit into the PiP window bounds.
Since the PiP surface embedder, or OverlaySurfaceEmbedder, utilizes a
ui::Layer, this change would allow the ability to customize the
cc::SurfaceLayer be exposed. Further work for the PiP sizing will be
done, including maintaining the aspect ratio.

BUG: 819414 726621
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: I3bdbf54635702414a4007912271118a57733ad05
Reviewed-on: https://chromium-review.googlesource.com/952476
Commit-Queue: apacible <apacible@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarFady Samuel <fsamuel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543289}
parent 72b68bc8
......@@ -28,6 +28,9 @@ class CC_EXPORT SurfaceLayer : public Layer {
// When stretch_content_to_fill_bounds is true, the scale of the embedded
// surface is ignored and the content will be stretched to fill the bounds.
void SetStretchContentToFillBounds(bool stretch_content_to_fill_bounds);
bool stretch_content_to_fill_bounds() const {
return stretch_content_to_fill_bounds_;
}
// Layer overrides.
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
......
......@@ -31,5 +31,6 @@ void OverlaySurfaceEmbedder::SetPrimarySurfaceId(
// SurfaceInfo has information about the embedded surface.
surface_layer_->SetShowPrimarySurface(
surface_id, window_->GetBounds().size(), SK_ColorBLACK,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(),
true /* stretch_content_to_fill_bounds */);
}
......@@ -288,7 +288,7 @@ void DelegatedFrameHost::WasResized(
#endif
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
surface_id, current_frame_size_in_dip_, GetGutterColor(),
deadline_policy);
deadline_policy, false /* stretch_content_to_fill_bounds */);
if (compositor_ && !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableResizeLock)) {
compositor_->OnChildResizing();
......@@ -521,7 +521,8 @@ void DelegatedFrameHost::OnFirstSurfaceActivation(
} else {
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
surface_info.id(), frame_size_in_dip, GetGutterColor(),
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
}
client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
......
......@@ -163,7 +163,8 @@ void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
window_->layer()->SetShowPrimarySurface(
surface_info.id(), window_->bounds().size(), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
window_->layer()->SetFallbackSurfaceId(surface_info.id());
}
......
......@@ -37,7 +37,8 @@ void ClientSurfaceEmbedder::SetPrimarySurfaceId(
const viz::SurfaceId& surface_id) {
surface_layer_->SetShowPrimarySurface(
surface_id, window_->bounds().size(), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
}
void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
......
......@@ -665,7 +665,8 @@ void WindowPortMus::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
window_->layer()->SetShowPrimarySurface(
surface_info.id(), window_->bounds().size(), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
window_->layer()->SetFallbackSurfaceId(surface_info.id());
}
......
......@@ -193,7 +193,8 @@ std::unique_ptr<Layer> Layer::Clone() const {
surface_layer_->deadline_in_frames()
? cc::DeadlinePolicy::UseSpecifiedDeadline(
*surface_layer_->deadline_in_frames())
: cc::DeadlinePolicy::UseDefaultDeadline());
: cc::DeadlinePolicy::UseDefaultDeadline(),
surface_layer_->stretch_content_to_fill_bounds());
}
if (surface_layer_->fallback_surface_id().is_valid())
clone->SetFallbackSurfaceId(surface_layer_->fallback_surface_id());
......@@ -706,6 +707,11 @@ void Layer::RemoveTrilinearFilteringRequest() {
cc_layer_->SetTrilinearFiltering(false);
}
bool Layer::StretchContentToFillBounds() const {
DCHECK(surface_layer_);
return surface_layer_->stretch_content_to_fill_bounds();
}
void Layer::SetTransferableResource(
const viz::TransferableResource& resource,
std::unique_ptr<viz::SingleReleaseCallback> release_callback,
......@@ -752,7 +758,8 @@ bool Layer::TextureFlipped() const {
void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id,
const gfx::Size& frame_size_in_dip,
SkColor default_background_color,
const cc::DeadlinePolicy& deadline_policy) {
const cc::DeadlinePolicy& deadline_policy,
bool stretch_content_to_fill_bounds) {
DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
if (!surface_layer_) {
......@@ -763,14 +770,15 @@ void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id,
surface_layer_->SetPrimarySurfaceId(surface_id, deadline_policy);
surface_layer_->SetBackgroundColor(default_background_color);
surface_layer_->SetStretchContentToFillBounds(stretch_content_to_fill_bounds);
frame_size_in_dip_ = frame_size_in_dip;
RecomputeDrawsContentAndUVRect();
for (const auto& mirror : mirrors_) {
mirror->dest()->SetShowPrimarySurface(surface_id, frame_size_in_dip,
default_background_color,
deadline_policy);
mirror->dest()->SetShowPrimarySurface(
surface_id, frame_size_in_dip, default_background_color,
deadline_policy, stretch_content_to_fill_bounds);
}
}
......
......@@ -307,7 +307,8 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate,
void SetShowPrimarySurface(const viz::SurfaceId& surface_id,
const gfx::Size& frame_size_in_dip,
SkColor default_background_color,
const cc::DeadlinePolicy& deadline_policy);
const cc::DeadlinePolicy& deadline_policy,
bool stretch_content_to_fill_bounds);
// In the event that the primary surface is not yet available in the
// display compositor, the fallback surface will be used.
......@@ -438,6 +439,10 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate,
// while attached to the main layer before the main layer is deleted.
const Layer* layer_mask_back_link() const { return layer_mask_back_link_; }
// If |surface_layer_| exists, return whether the contents should stretch to
// fill the bounds of |this|. Defaults to false.
bool StretchContentToFillBounds() const;
private:
friend class LayerOwner;
class LayerMirror;
......
......@@ -33,6 +33,7 @@
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -891,6 +892,36 @@ TEST_F(LayerWithDelegateTest, Mirroring) {
EXPECT_EQ(new_bounds, mirror->bounds());
}
// Tests for SurfaceLayer cloning and mirroring. This tests certain properties
// are preserved.
TEST_F(LayerWithDelegateTest, SurfaceLayerCloneAndMirror) {
const viz::FrameSinkId arbitrary_frame_sink(1, 1);
viz::ParentLocalSurfaceIdAllocator allocator;
std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
viz::LocalSurfaceId local_surface_id = allocator.GenerateId();
viz::SurfaceId surface_id_one(arbitrary_frame_sink, local_surface_id);
layer->SetShowPrimarySurface(surface_id_one, gfx::Size(10, 10), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline(), false);
EXPECT_FALSE(layer->StretchContentToFillBounds());
auto clone = layer->Clone();
EXPECT_FALSE(clone->StretchContentToFillBounds());
auto mirror = layer->Mirror();
EXPECT_FALSE(clone->StretchContentToFillBounds());
local_surface_id = allocator.GenerateId();
viz::SurfaceId surface_id_two(arbitrary_frame_sink, local_surface_id);
layer->SetShowPrimarySurface(surface_id_two, gfx::Size(10, 10), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline(), true);
EXPECT_TRUE(layer->StretchContentToFillBounds());
clone = layer->Clone();
EXPECT_TRUE(clone->StretchContentToFillBounds());
mirror = layer->Mirror();
EXPECT_TRUE(clone->StretchContentToFillBounds());
}
class LayerWithNullDelegateTest : public LayerWithDelegateTest {
public:
LayerWithNullDelegateTest() {}
......@@ -1851,23 +1882,17 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
before = child->cc_layer_for_testing();
child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(), false);
scoped_refptr<cc::Layer> after = child->cc_layer_for_testing();
const auto* surface = static_cast<cc::SurfaceLayer*>(after.get());
EXPECT_TRUE(after.get());
EXPECT_NE(before.get(), after.get());
EXPECT_EQ(base::nullopt, surface->deadline_in_frames());
child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE,
cc::DeadlinePolicy::UseSpecifiedDeadline(4u));
child->SetShowPrimarySurface(
viz::SurfaceId(), gfx::Size(10, 10), SK_ColorWHITE,
cc::DeadlinePolicy::UseSpecifiedDeadline(4u), false);
EXPECT_EQ(4u, surface->deadline_in_frames());
// Changing to painted content should change the underlying cc layer.
before = child->cc_layer_for_testing();
child->SetShowSolidColorContent();
EXPECT_TRUE(child->cc_layer_for_testing());
EXPECT_NE(before.get(), child->cc_layer_for_testing());
}
TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
......@@ -1877,7 +1902,7 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
viz::FrameSinkId(0, 1),
viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
layer->SetShowPrimarySurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(), false);
const auto mirror = layer->Mirror();
auto* const cc_layer = mirror->cc_layer_for_testing();
......@@ -1890,12 +1915,12 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
viz::SurfaceId(viz::FrameSinkId(1, 2),
viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(), false);
// The mirror should continue to use the same cc_layer.
EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing());
layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(), false);
// Surface updates propagate to the mirror.
EXPECT_EQ(surface_id, surface->primary_surface_id());
......@@ -1917,7 +1942,7 @@ TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing();
layer->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline());
cc::DeadlinePolicy::UseDefaultDeadline(), false);
EXPECT_EQ(layer->layer_grayscale(), 0.5f);
EXPECT_TRUE(layer->cc_layer_for_testing());
EXPECT_NE(before.get(), layer->cc_layer_for_testing());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment