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 { ...@@ -28,6 +28,9 @@ class CC_EXPORT SurfaceLayer : public Layer {
// When stretch_content_to_fill_bounds is true, the scale of the embedded // 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. // surface is ignored and the content will be stretched to fill the bounds.
void SetStretchContentToFillBounds(bool stretch_content_to_fill_bounds); void SetStretchContentToFillBounds(bool stretch_content_to_fill_bounds);
bool stretch_content_to_fill_bounds() const {
return stretch_content_to_fill_bounds_;
}
// Layer overrides. // Layer overrides.
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
......
...@@ -31,5 +31,6 @@ void OverlaySurfaceEmbedder::SetPrimarySurfaceId( ...@@ -31,5 +31,6 @@ void OverlaySurfaceEmbedder::SetPrimarySurfaceId(
// SurfaceInfo has information about the embedded surface. // SurfaceInfo has information about the embedded surface.
surface_layer_->SetShowPrimarySurface( surface_layer_->SetShowPrimarySurface(
surface_id, window_->GetBounds().size(), SK_ColorBLACK, 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( ...@@ -288,7 +288,7 @@ void DelegatedFrameHost::WasResized(
#endif #endif
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface( client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
surface_id, current_frame_size_in_dip_, GetGutterColor(), surface_id, current_frame_size_in_dip_, GetGutterColor(),
deadline_policy); deadline_policy, false /* stretch_content_to_fill_bounds */);
if (compositor_ && !base::CommandLine::ForCurrentProcess()->HasSwitch( if (compositor_ && !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableResizeLock)) { switches::kDisableResizeLock)) {
compositor_->OnChildResizing(); compositor_->OnChildResizing();
...@@ -521,7 +521,8 @@ void DelegatedFrameHost::OnFirstSurfaceActivation( ...@@ -521,7 +521,8 @@ void DelegatedFrameHost::OnFirstSurfaceActivation(
} else { } else {
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface( client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
surface_info.id(), frame_size_in_dip, GetGutterColor(), surface_info.id(), frame_size_in_dip, GetGutterColor(),
cc::DeadlinePolicy::UseDefaultDeadline()); cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
} }
client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId( client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
......
...@@ -163,7 +163,8 @@ void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) { ...@@ -163,7 +163,8 @@ void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_); DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
window_->layer()->SetShowPrimarySurface( window_->layer()->SetShowPrimarySurface(
surface_info.id(), window_->bounds().size(), SK_ColorWHITE, 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()); window_->layer()->SetFallbackSurfaceId(surface_info.id());
} }
......
...@@ -37,7 +37,8 @@ void ClientSurfaceEmbedder::SetPrimarySurfaceId( ...@@ -37,7 +37,8 @@ void ClientSurfaceEmbedder::SetPrimarySurfaceId(
const viz::SurfaceId& surface_id) { const viz::SurfaceId& surface_id) {
surface_layer_->SetShowPrimarySurface( surface_layer_->SetShowPrimarySurface(
surface_id, window_->bounds().size(), SK_ColorWHITE, surface_id, window_->bounds().size(), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline()); cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
} }
void ClientSurfaceEmbedder::SetFallbackSurfaceInfo( void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
......
...@@ -665,7 +665,8 @@ void WindowPortMus::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) { ...@@ -665,7 +665,8 @@ void WindowPortMus::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_); DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
window_->layer()->SetShowPrimarySurface( window_->layer()->SetShowPrimarySurface(
surface_info.id(), window_->bounds().size(), SK_ColorWHITE, 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()); window_->layer()->SetFallbackSurfaceId(surface_info.id());
} }
......
...@@ -193,7 +193,8 @@ std::unique_ptr<Layer> Layer::Clone() const { ...@@ -193,7 +193,8 @@ std::unique_ptr<Layer> Layer::Clone() const {
surface_layer_->deadline_in_frames() surface_layer_->deadline_in_frames()
? cc::DeadlinePolicy::UseSpecifiedDeadline( ? cc::DeadlinePolicy::UseSpecifiedDeadline(
*surface_layer_->deadline_in_frames()) *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()) if (surface_layer_->fallback_surface_id().is_valid())
clone->SetFallbackSurfaceId(surface_layer_->fallback_surface_id()); clone->SetFallbackSurfaceId(surface_layer_->fallback_surface_id());
...@@ -706,6 +707,11 @@ void Layer::RemoveTrilinearFilteringRequest() { ...@@ -706,6 +707,11 @@ void Layer::RemoveTrilinearFilteringRequest() {
cc_layer_->SetTrilinearFiltering(false); cc_layer_->SetTrilinearFiltering(false);
} }
bool Layer::StretchContentToFillBounds() const {
DCHECK(surface_layer_);
return surface_layer_->stretch_content_to_fill_bounds();
}
void Layer::SetTransferableResource( void Layer::SetTransferableResource(
const viz::TransferableResource& resource, const viz::TransferableResource& resource,
std::unique_ptr<viz::SingleReleaseCallback> release_callback, std::unique_ptr<viz::SingleReleaseCallback> release_callback,
...@@ -752,7 +758,8 @@ bool Layer::TextureFlipped() const { ...@@ -752,7 +758,8 @@ bool Layer::TextureFlipped() const {
void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id, void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id,
const gfx::Size& frame_size_in_dip, const gfx::Size& frame_size_in_dip,
SkColor default_background_color, 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); DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
if (!surface_layer_) { if (!surface_layer_) {
...@@ -763,14 +770,15 @@ void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id, ...@@ -763,14 +770,15 @@ void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id,
surface_layer_->SetPrimarySurfaceId(surface_id, deadline_policy); surface_layer_->SetPrimarySurfaceId(surface_id, deadline_policy);
surface_layer_->SetBackgroundColor(default_background_color); surface_layer_->SetBackgroundColor(default_background_color);
surface_layer_->SetStretchContentToFillBounds(stretch_content_to_fill_bounds);
frame_size_in_dip_ = frame_size_in_dip; frame_size_in_dip_ = frame_size_in_dip;
RecomputeDrawsContentAndUVRect(); RecomputeDrawsContentAndUVRect();
for (const auto& mirror : mirrors_) { for (const auto& mirror : mirrors_) {
mirror->dest()->SetShowPrimarySurface(surface_id, frame_size_in_dip, mirror->dest()->SetShowPrimarySurface(
default_background_color, surface_id, frame_size_in_dip, default_background_color,
deadline_policy); deadline_policy, stretch_content_to_fill_bounds);
} }
} }
......
...@@ -307,7 +307,8 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate, ...@@ -307,7 +307,8 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate,
void SetShowPrimarySurface(const viz::SurfaceId& surface_id, void SetShowPrimarySurface(const viz::SurfaceId& surface_id,
const gfx::Size& frame_size_in_dip, const gfx::Size& frame_size_in_dip,
SkColor default_background_color, 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 // In the event that the primary surface is not yet available in the
// display compositor, the fallback surface will be used. // display compositor, the fallback surface will be used.
...@@ -438,6 +439,10 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate, ...@@ -438,6 +439,10 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate,
// while attached to the main layer before the main layer is deleted. // while attached to the main layer before the main layer is deleted.
const Layer* layer_mask_back_link() const { return layer_mask_back_link_; } 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: private:
friend class LayerOwner; friend class LayerOwner;
class LayerMirror; class LayerMirror;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/resources/transferable_resource.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 "components/viz/common/surfaces/surface_id.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -891,6 +892,36 @@ TEST_F(LayerWithDelegateTest, Mirroring) { ...@@ -891,6 +892,36 @@ TEST_F(LayerWithDelegateTest, Mirroring) {
EXPECT_EQ(new_bounds, mirror->bounds()); 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 { class LayerWithNullDelegateTest : public LayerWithDelegateTest {
public: public:
LayerWithNullDelegateTest() {} LayerWithNullDelegateTest() {}
...@@ -1851,23 +1882,17 @@ TEST_F(LayerWithDelegateTest, ExternalContent) { ...@@ -1851,23 +1882,17 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
before = child->cc_layer_for_testing(); before = child->cc_layer_for_testing();
child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10), child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE, SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline()); cc::DeadlinePolicy::UseDefaultDeadline(), false);
scoped_refptr<cc::Layer> after = child->cc_layer_for_testing(); scoped_refptr<cc::Layer> after = child->cc_layer_for_testing();
const auto* surface = static_cast<cc::SurfaceLayer*>(after.get()); const auto* surface = static_cast<cc::SurfaceLayer*>(after.get());
EXPECT_TRUE(after.get()); EXPECT_TRUE(after.get());
EXPECT_NE(before.get(), after.get()); EXPECT_NE(before.get(), after.get());
EXPECT_EQ(base::nullopt, surface->deadline_in_frames()); EXPECT_EQ(base::nullopt, surface->deadline_in_frames());
child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10), child->SetShowPrimarySurface(
SK_ColorWHITE, viz::SurfaceId(), gfx::Size(10, 10), SK_ColorWHITE,
cc::DeadlinePolicy::UseSpecifiedDeadline(4u)); cc::DeadlinePolicy::UseSpecifiedDeadline(4u), false);
EXPECT_EQ(4u, surface->deadline_in_frames()); 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) { TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
...@@ -1877,7 +1902,7 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) { ...@@ -1877,7 +1902,7 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
viz::FrameSinkId(0, 1), viz::FrameSinkId(0, 1),
viz::LocalSurfaceId(2, base::UnguessableToken::Create())); viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
layer->SetShowPrimarySurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE, layer->SetShowPrimarySurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline()); cc::DeadlinePolicy::UseDefaultDeadline(), false);
const auto mirror = layer->Mirror(); const auto mirror = layer->Mirror();
auto* const cc_layer = mirror->cc_layer_for_testing(); auto* const cc_layer = mirror->cc_layer_for_testing();
...@@ -1890,12 +1915,12 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) { ...@@ -1890,12 +1915,12 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
viz::SurfaceId(viz::FrameSinkId(1, 2), viz::SurfaceId(viz::FrameSinkId(1, 2),
viz::LocalSurfaceId(3, base::UnguessableToken::Create())); viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE, 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. // The mirror should continue to use the same cc_layer.
EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing()); EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing());
layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE, layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline()); cc::DeadlinePolicy::UseDefaultDeadline(), false);
// Surface updates propagate to the mirror. // Surface updates propagate to the mirror.
EXPECT_EQ(surface_id, surface->primary_surface_id()); EXPECT_EQ(surface_id, surface->primary_surface_id());
...@@ -1917,7 +1942,7 @@ TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) { ...@@ -1917,7 +1942,7 @@ TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing(); scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing();
layer->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10), layer->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE, SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline()); cc::DeadlinePolicy::UseDefaultDeadline(), false);
EXPECT_EQ(layer->layer_grayscale(), 0.5f); EXPECT_EQ(layer->layer_grayscale(), 0.5f);
EXPECT_TRUE(layer->cc_layer_for_testing()); EXPECT_TRUE(layer->cc_layer_for_testing());
EXPECT_NE(before.get(), 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