summaryrefslogtreecommitdiff
path: root/chromium/cc/trees
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/trees')
-rw-r--r--chromium/cc/trees/draw_property_utils.cc20
-rw-r--r--chromium/cc/trees/draw_property_utils.h2
-rw-r--r--chromium/cc/trees/latency_info_swap_promise.cc3
-rw-r--r--chromium/cc/trees/latency_info_swap_promise_monitor.cc23
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.cc4
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h35
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h8
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_unittest.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host.cc125
-rw-r--r--chromium/cc/trees/layer_tree_host.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_common_perftest.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc491
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc404
-rw-r--r--chromium/cc/trees/layer_tree_host_perftest.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc39
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc73
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc686
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc61
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc57
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_masks.cc666
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_picture.cc18
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc4
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc30
-rw-r--r--chromium/cc/trees/layer_tree_impl.h17
-rw-r--r--chromium/cc/trees/layer_tree_settings.cc3
-rw-r--r--chromium/cc/trees/layer_tree_settings.h6
-rw-r--r--chromium/cc/trees/mutator_host.h1
-rw-r--r--chromium/cc/trees/proxy_impl.cc4
-rw-r--r--chromium/cc/trees/proxy_impl.h1
-rw-r--r--chromium/cc/trees/proxy_main.cc2
-rw-r--r--chromium/cc/trees/render_frame_metadata.cc24
-rw-r--r--chromium/cc/trees/render_frame_metadata.h32
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc12
-rw-r--r--chromium/cc/trees/single_thread_proxy.h1
38 files changed, 1950 insertions, 986 deletions
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index d3c1958a13c..b888d085203 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -506,11 +506,12 @@ static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees,
float page_scale_factor,
float device_scale_factor,
gfx::Transform device_transform) {
- if (property_trees->transform_tree.page_scale_factor() == page_scale_factor)
+ if (property_trees->transform_tree.page_scale_factor() == page_scale_factor ||
+ !page_scale_layer) {
return;
+ }
property_trees->transform_tree.set_page_scale_factor(page_scale_factor);
- DCHECK(page_scale_layer);
DCHECK_GE(page_scale_layer->transform_tree_index(),
TransformTree::kRootNodeId);
TransformNode* node = property_trees->transform_tree.Node(
@@ -648,7 +649,7 @@ static void SetSurfaceDrawTransform(const PropertyTrees* property_trees,
const EffectNode* effect_node =
effect_tree.Node(render_surface->EffectTreeIndex());
// The draw transform of root render surface is identity tranform.
- if (transform_node->id == TransformTree::kRootNodeId) {
+ if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) {
render_surface->SetDrawTransform(gfx::Transform());
return;
}
@@ -1004,7 +1005,7 @@ void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
}
void ComputeMaskDrawProperties(LayerImpl* mask_layer,
- const PropertyTrees* property_trees) {
+ PropertyTrees* property_trees) {
// Mask draw properties are used only for rastering, so most of the draw
// properties computed for other layers are not needed.
// Draw transform of a mask layer has to be a 2d scale.
@@ -1016,8 +1017,17 @@ void ComputeMaskDrawProperties(LayerImpl* mask_layer,
mask_layer->draw_properties().screen_space_transform =
ScreenSpaceTransformInternal(mask_layer,
property_trees->transform_tree);
+
+ ConditionalClip clip = LayerClipRect(property_trees, mask_layer);
+ // is_clipped should be set before visible rect computation as it is used
+ // there.
+ mask_layer->draw_properties().is_clipped = clip.is_clipped;
+ mask_layer->draw_properties().clip_rect =
+ gfx::ToEnclosingRect(clip.clip_rect);
+ // Calculate actual visible layer rect for mask layers, since we could have
+ // tiled mask layers and the tile manager would need this info for rastering.
mask_layer->draw_properties().visible_layer_rect =
- gfx::Rect(mask_layer->bounds());
+ LayerVisibleRect(property_trees, mask_layer);
mask_layer->draw_properties().opacity = 1;
}
diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h
index 45ed01f6e88..6c843521df6 100644
--- a/chromium/cc/trees/draw_property_utils.h
+++ b/chromium/cc/trees/draw_property_utils.h
@@ -59,7 +59,7 @@ ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
PropertyTrees* property_trees);
void CC_EXPORT ComputeMaskDrawProperties(LayerImpl* mask_layer,
- const PropertyTrees* property_trees);
+ PropertyTrees* property_trees);
void CC_EXPORT ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
RenderSurfaceImpl* render_surface);
diff --git a/chromium/cc/trees/latency_info_swap_promise.cc b/chromium/cc/trees/latency_info_swap_promise.cc
index 6ebf5352014..9b376030ed5 100644
--- a/chromium/cc/trees/latency_info_swap_promise.cc
+++ b/chromium/cc/trees/latency_info_swap_promise.cc
@@ -44,8 +44,7 @@ void LatencyInfoSwapPromise::DidSwap() {}
SwapPromise::DidNotSwapAction LatencyInfoSwapPromise::DidNotSwap(
DidNotSwapReason reason) {
- latency_.AddLatencyNumber(DidNotSwapReasonToLatencyComponentType(reason), 0,
- 0);
+ latency_.AddLatencyNumber(DidNotSwapReasonToLatencyComponentType(reason), 0);
// TODO(miletus): Turn this back on once per-event LatencyInfo tracking
// is enabled in GPU side.
// DCHECK(latency_.terminated);
diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.cc b/chromium/cc/trees/latency_info_swap_promise_monitor.cc
index 7bca0d6ebf0..99ec2c686a4 100644
--- a/chromium/cc/trees/latency_info_swap_promise_monitor.cc
+++ b/chromium/cc/trees/latency_info_swap_promise_monitor.cc
@@ -21,7 +21,7 @@ bool AddRenderingScheduledComponent(ui::LatencyInfo* latency_info,
: ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT;
if (latency_info->FindLatency(type, 0, nullptr))
return false;
- latency_info->AddLatencyNumber(type, 0, 0);
+ latency_info->AddLatencyNumber(type, 0);
return true;
}
@@ -31,8 +31,7 @@ bool AddForwardingScrollUpdateToMainComponent(ui::LatencyInfo* latency_info) {
nullptr))
return false;
latency_info->AddLatencyNumber(
- ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT, 0,
- latency_info->trace_id());
+ ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT, 0);
return true;
}
@@ -70,29 +69,13 @@ void LatencyInfoSwapPromiseMonitor::OnSetNeedsRedrawOnImpl() {
void LatencyInfoSwapPromiseMonitor::OnForwardScrollUpdateToMainThreadOnImpl() {
if (AddForwardingScrollUpdateToMainComponent(latency_)) {
- int64_t new_sequence_number = 0;
- for (ui::LatencyInfo::LatencyMap::const_iterator it =
- latency_->latency_components().begin();
- it != latency_->latency_components().end(); ++it) {
- if (it->first.first == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT) {
- new_sequence_number =
- ((static_cast<int64_t>(base::PlatformThread::CurrentId()) << 32) ^
- (reinterpret_cast<uint64_t>(this) << 32)) |
- (it->second.sequence_number & 0xffffffff);
- if (new_sequence_number == it->second.sequence_number)
- return;
- break;
- }
- }
- if (!new_sequence_number)
- return;
ui::LatencyInfo new_latency;
new_latency.CopyLatencyFrom(
*latency_,
ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT);
new_latency.AddLatencyNumberWithTraceName(
ui::LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT, 0,
- new_sequence_number, "ScrollUpdate");
+ "ScrollUpdate");
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(new_latency));
host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(
diff --git a/chromium/cc/trees/layer_tree_frame_sink.cc b/chromium/cc/trees/layer_tree_frame_sink.cc
index 5a1fb748c7b..e1a1b803b72 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink.cc
@@ -43,13 +43,11 @@ LayerTreeFrameSink::LayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- viz::SharedBitmapManager* shared_bitmap_manager)
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager)
: context_provider_(std::move(context_provider)),
worker_context_provider_(std::move(worker_context_provider)),
compositor_task_runner_(std::move(compositor_task_runner)),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
- shared_bitmap_manager_(shared_bitmap_manager),
weak_ptr_factory_(this) {
DETACH_FROM_THREAD(thread_checker_);
}
diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h
index f61c7a6c019..7f550dc9fe8 100644
--- a/chromium/cc/trees/layer_tree_frame_sink.h
+++ b/chromium/cc/trees/layer_tree_frame_sink.h
@@ -11,15 +11,15 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "cc/cc_export.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
-#include "components/viz/common/quads/shared_bitmap.h"
#include "components/viz/common/resources/returned_resource.h"
+#include "components/viz/common/resources/shared_bitmap_reporter.h"
#include "gpu/command_buffer/common/texture_in_use_response.h"
-#include "mojo/public/cpp/system/buffer.h"
#include "ui/gfx/color_space.h"
namespace gpu {
@@ -29,21 +29,20 @@ class GpuMemoryBufferManager;
namespace viz {
class CompositorFrame;
class LocalSurfaceId;
-class SharedBitmapManager;
struct BeginFrameAck;
} // namespace viz
namespace cc {
class LayerTreeFrameSinkClient;
-class LayerTreeHostImpl;
// An interface for submitting CompositorFrames to a display compositor
// which will compose frames from multiple clients to show on screen to the
// user.
// If a context_provider() is present, frames should be submitted with
// OpenGL resources (created with the context_provider()). If not, then
-// SharedBitmap resources should be used.
-class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
+// SharedMemory resources should be used.
+class CC_EXPORT LayerTreeFrameSink : public viz::SharedBitmapReporter,
+ public viz::ContextLostObserver {
public:
struct Capabilities {
Capabilities() = default;
@@ -74,8 +73,7 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
scoped_refptr<viz::ContextProvider> context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- viz::SharedBitmapManager* shared_bitmap_manager);
+ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
~LayerTreeFrameSink() override;
@@ -101,7 +99,7 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
const Capabilities& capabilities() const { return capabilities_; }
// The viz::ContextProviders may be null if frames should be submitted with
- // software SharedBitmap resources.
+ // software SharedMemory resources.
viz::ContextProvider* context_provider() const {
return context_provider_.get();
}
@@ -111,13 +109,6 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const {
return gpu_memory_buffer_manager_;
}
- viz::SharedBitmapManager* shared_bitmap_manager() const {
- return shared_bitmap_manager_;
- }
-
- // Generate hit test region list based on LayerTreeHostImpl, the data will be
- // submitted with compositor frame.
- virtual void UpdateHitTestData(const LayerTreeHostImpl* host_impl) {}
// If supported, this sets the viz::LocalSurfaceId the LayerTreeFrameSink will
// use to submit a CompositorFrame.
@@ -137,13 +128,10 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
// the client did not lead to a CompositorFrame submission.
virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack) = 0;
- // Associates a SharedBitmapId with a shared buffer handle.
- virtual void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
- const viz::SharedBitmapId& id) = 0;
-
- // Disassociates a SharedBitmapId previously passed to
- // DidAllocateSharedBitmap.
- virtual void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) = 0;
+ // viz::SharedBitmapReporter implementation.
+ void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
+ const viz::SharedBitmapId& id) override = 0;
+ void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override = 0;
protected:
class ContextLostForwarder;
@@ -158,7 +146,6 @@ class CC_EXPORT LayerTreeFrameSink : public viz::ContextLostObserver {
scoped_refptr<viz::RasterContextProvider> worker_context_provider_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
- viz::SharedBitmapManager* shared_bitmap_manager_;
std::unique_ptr<ContextLostForwarder> worker_context_lost_forwarder_;
diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h
index a463b770007..d774db56e35 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_client.h
+++ b/chromium/cc/trees/layer_tree_frame_sink_client.h
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "components/viz/common/resources/returned_resource.h"
@@ -19,6 +20,7 @@ class Transform;
namespace viz {
class BeginFrameSource;
+struct HitTestRegionList;
}
namespace cc {
@@ -32,6 +34,12 @@ class CC_EXPORT LayerTreeFrameSinkClient {
// binding to the client and then call again with a null while detaching.
virtual void SetBeginFrameSource(viz::BeginFrameSource* source) = 0;
+ // Builds and returns a HitTestRegionList from the active LayerTreeImpl. To be
+ // called during SubmitCompositorFrame().
+ // TODO(danakj): Just pass it into SubmitCompositorFrame(), with a
+ // LayerTreeSetting to enable it or not.
+ virtual base::Optional<viz::HitTestRegionList> BuildHitTestData() = 0;
+
// Returns resources sent to SubmitCompositorFrame to be reused or freed.
virtual void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) = 0;
diff --git a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
index 8ac72b45da5..781effb7740 100644
--- a/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
+++ b/chromium/cc/trees/layer_tree_frame_sink_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/trees/layer_tree_frame_sink.h"
+#include "base/single_thread_task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "cc/test/fake_layer_tree_frame_sink_client.h"
#include "components/viz/common/quads/compositor_frame.h"
@@ -25,7 +26,6 @@ class StubLayerTreeFrameSink : public LayerTreeFrameSink {
: LayerTreeFrameSink(std::move(context_provider),
std::move(worker_context_provider),
std::move(compositor_task_runner),
- nullptr,
nullptr) {}
void SubmitCompositorFrame(viz::CompositorFrame frame) override {
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index d8bf091317a..b47182219c0 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -159,7 +159,7 @@ void LayerTreeHost::SetUIResourceManagerForTesting(
}
void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) {
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::InitializeForReal");
+ TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal");
DCHECK(task_runner_provider_);
proxy_ = std::move(proxy);
@@ -174,7 +174,7 @@ LayerTreeHost::~LayerTreeHost() {
// Track when we're inside a main frame to see if compositor is being
// destroyed midway which causes a crash. crbug.com/654672
DCHECK(!inside_main_frame_);
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::~LayerTreeHostInProcess");
+ TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
// Clear any references into the LayerTreeHost.
mutator_host_->SetMutatorHostClient(nullptr);
@@ -280,25 +280,12 @@ void LayerTreeHost::RequestMainFrameUpdate(VisualStateUpdate requested_update) {
// This function commits the LayerTreeHost to an impl tree. When modifying
// this function, keep in mind that the function *runs* on the impl thread! Any
// code that is logically a main thread operation, e.g. deletion of a Layer,
-// should be delayed until the LayerTreeHostInProcess::CommitComplete, which
-// will run after the commit, but on the main thread.
+// should be delayed until the LayerTreeHost::CommitComplete, which will run
+// after the commit, but on the main thread.
void LayerTreeHost::FinishCommitOnImplThread(
LayerTreeHostImpl* host_impl) {
DCHECK(task_runner_provider_->IsImplThread());
- bool is_new_trace;
- TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
- if (is_new_trace &&
- frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() &&
- root_layer()) {
- // We'll be dumping layer trees as part of trace, so make sure
- // PushPropertiesTo() propagates layer debug info to the impl side --
- // otherwise this won't happen for the layers that remain unchanged since
- // tracing started.
- LayerTreeHostCommon::CallFunctionForEveryLayer(
- this, [](Layer* layer) { layer->SetNeedsPushProperties(); });
- }
-
LayerTreeImpl* sync_tree = host_impl->sync_tree();
sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync);
@@ -341,7 +328,7 @@ void LayerTreeHost::FinishCommitOnImplThread(
}
{
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::PushProperties");
+ TRACE_EVENT0("cc", "LayerTreeHost::PushProperties");
PushPropertyTreesTo(sync_tree);
sync_tree->lifecycle().AdvanceTo(LayerTreeLifecycle::kSyncedPropertyTrees);
@@ -377,7 +364,7 @@ void LayerTreeHost::FinishCommitOnImplThread(
// TODO(pdr): Enforce this comment with DCHECKS and a lifecycle state.
sync_tree->UpdatePropertyTreeAnimationFromMainThread();
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties");
+ TRACE_EVENT0("cc", "LayerTreeHost::AnimationHost::PushProperties");
DCHECK(host_impl->mutator_host());
mutator_host_->PushPropertiesTo(host_impl->mutator_host());
@@ -427,13 +414,29 @@ void LayerTreeHost::PushPropertyTreesTo(LayerTreeImpl* tree_impl) {
void LayerTreeHost::WillCommit() {
swap_promise_manager_.WillCommit();
client_->WillCommit();
+
+ if (frame_viewer_instrumentation::IsTracingLayerTreeSnapshots()) {
+ bool is_new_trace;
+ TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
+ if (is_new_trace) {
+ // We'll be dumping layer trees as part of trace, so make sure
+ // PushPropertiesTo() propagates layer debug info to the impl side --
+ // otherwise this won't happen for the layers that remain unchanged since
+ // tracing started.
+ LayerTreeHostCommon::CallFunctionForEveryLayer(
+ this, [](Layer* layer) { layer->SetNeedsPushProperties(); });
+ }
+
+ for (Layer* layer : LayersThatShouldPushProperties())
+ layer->UpdateDebugInfo();
+ }
}
void LayerTreeHost::UpdateDeferCommitsInternal() {
proxy_->SetDeferCommits(defer_commits_ ||
(settings_.enable_surface_synchronization &&
- !local_surface_id_.is_valid()));
+ !local_surface_id_from_parent_.is_valid()));
}
bool LayerTreeHost::IsUsingLayerLists() const {
@@ -451,7 +454,7 @@ void LayerTreeHost::CommitComplete() {
void LayerTreeHost::SetLayerTreeFrameSink(
std::unique_ptr<LayerTreeFrameSink> surface) {
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::SetLayerTreeFrameSink");
+ TRACE_EVENT0("cc", "LayerTreeHost::SetLayerTreeFrameSink");
DCHECK(surface);
DCHECK(!new_layer_tree_frame_sink_);
@@ -514,7 +517,7 @@ LayerTreeHost::CreateLayerTreeHostImpl(
}
void LayerTreeHost::DidLoseLayerTreeFrameSink() {
- TRACE_EVENT0("cc", "LayerTreeHostInProcess::DidLoseLayerTreeFrameSink");
+ TRACE_EVENT0("cc", "LayerTreeHost::DidLoseLayerTreeFrameSink");
DCHECK(task_runner_provider_->IsMainThread());
SetNeedsCommit();
}
@@ -598,9 +601,9 @@ void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) {
return;
has_gpu_rasterization_trigger_ = has_trigger;
- TRACE_EVENT_INSTANT1(
- "cc", "LayerTreeHostInProcess::SetHasGpuRasterizationTrigger",
- TRACE_EVENT_SCOPE_THREAD, "has_trigger", has_gpu_rasterization_trigger_);
+ TRACE_EVENT_INSTANT1("cc", "LayerTreeHost::SetHasGpuRasterizationTrigger",
+ TRACE_EVENT_SCOPE_THREAD, "has_trigger",
+ has_gpu_rasterization_trigger_);
}
void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(
@@ -745,8 +748,8 @@ void LayerTreeHost::RecordGpuRasterizationHistogram(
}
bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
- TRACE_EVENT1("cc", "LayerTreeHostInProcess::DoUpdateLayers",
- "source_frame_number", SourceFrameNumber());
+ TRACE_EVENT1("cc", "LayerTreeHost::DoUpdateLayers", "source_frame_number",
+ SourceFrameNumber());
UpdateHudLayer(debug_state_.ShowHudInfo());
@@ -777,11 +780,9 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
{
base::AutoReset<bool> update_property_trees(&in_update_property_trees_,
true);
- TRACE_EVENT0("cc",
- "LayerTreeHostInProcess::UpdateLayers::BuildPropertyTrees");
- TRACE_EVENT0(
- TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
- "LayerTreeHostInProcessCommon::ComputeVisibleRectsWithPropertyTrees");
+ TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
+ "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
PropertyTrees* property_trees = &property_trees_;
if (!IsUsingLayerLists()) {
// In SPv2 the property trees should have been built by the
@@ -791,15 +792,15 @@ bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) {
outer_viewport_scroll_layer(), overscroll_elasticity_layer(),
elastic_overscroll_, page_scale_factor_, device_scale_factor_,
gfx::Rect(device_viewport_size_), identity_transform, property_trees);
- TRACE_EVENT_INSTANT1(
- "cc", "LayerTreeHostInProcess::UpdateLayers_BuiltPropertyTrees",
- TRACE_EVENT_SCOPE_THREAD, "property_trees",
- property_trees->AsTracedValue());
+ TRACE_EVENT_INSTANT1("cc",
+ "LayerTreeHost::UpdateLayers_BuiltPropertyTrees",
+ TRACE_EVENT_SCOPE_THREAD, "property_trees",
+ property_trees->AsTracedValue());
} else {
- TRACE_EVENT_INSTANT1(
- "cc", "LayerTreeHostInProcess::UpdateLayers_ReceivedPropertyTrees",
- TRACE_EVENT_SCOPE_THREAD, "property_trees",
- property_trees->AsTracedValue());
+ TRACE_EVENT_INSTANT1("cc",
+ "LayerTreeHost::UpdateLayers_ReceivedPropertyTrees",
+ TRACE_EVENT_SCOPE_THREAD, "property_trees",
+ property_trees->AsTracedValue());
}
draw_property_utils::UpdatePropertyTrees(this, property_trees);
@@ -1054,9 +1055,8 @@ void LayerTreeHost::SetEventListenerProperties(
void LayerTreeHost::SetViewportSizeAndScale(
const gfx::Size& device_viewport_size,
float device_scale_factor,
- const viz::LocalSurfaceId& local_surface_id) {
- if (settings_.enable_surface_synchronization)
- SetLocalSurfaceId(local_surface_id);
+ const viz::LocalSurfaceId& local_surface_id_from_parent) {
+ SetLocalSurfaceIdFromParent(local_surface_id_from_parent);
bool changed = false;
if (device_viewport_size_ != device_viewport_size) {
@@ -1083,7 +1083,9 @@ void LayerTreeHost::SetViewportSizeAndScale(
#if defined(OS_MACOSX)
// TODO(ccameron): This check is not valid on Aura or Mus yet, but should
// be.
- CHECK(!has_pushed_local_surface_id_ || !local_surface_id_.is_valid());
+ CHECK(!has_pushed_local_surface_id_from_parent_ ||
+ new_local_surface_id_request_ ||
+ !local_surface_id_from_parent_.is_valid());
#endif
}
}
@@ -1180,16 +1182,34 @@ void LayerTreeHost::SetContentSourceId(uint32_t id) {
SetNeedsCommit();
}
-void LayerTreeHost::SetLocalSurfaceId(
- const viz::LocalSurfaceId& local_surface_id) {
- if (local_surface_id_ == local_surface_id)
+void LayerTreeHost::SetLocalSurfaceIdFromParent(
+ const viz::LocalSurfaceId& local_surface_id_from_parent) {
+ if (local_surface_id_from_parent_ == local_surface_id_from_parent)
return;
- local_surface_id_ = local_surface_id;
- has_pushed_local_surface_id_ = false;
+ local_surface_id_from_parent_ = local_surface_id_from_parent;
+ has_pushed_local_surface_id_from_parent_ = false;
UpdateDeferCommitsInternal();
SetNeedsCommit();
}
+void LayerTreeHost::RequestNewLocalSurfaceId() {
+ // If surface synchronization is enabled, then we can still request a new
+ // viz::LocalSurfaceId but that request will be deferred until we have a valid
+ // viz::LocalSurfaceId from the parent.
+ DCHECK(settings_.enable_surface_synchronization ||
+ local_surface_id_from_parent_.is_valid());
+ if (new_local_surface_id_request_)
+ return;
+ new_local_surface_id_request_ = true;
+ SetNeedsCommit();
+}
+
+bool LayerTreeHost::TakeNewLocalSurfaceIdRequest() {
+ bool new_local_surface_id_request = new_local_surface_id_request_;
+ new_local_surface_id_request_ = false;
+ return new_local_surface_id_request;
+}
+
void LayerTreeHost::RegisterLayer(Layer* layer) {
DCHECK(!LayerById(layer->id()));
DCHECK(!in_paint_layer_contents_);
@@ -1375,8 +1395,11 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->set_content_source_id(content_source_id_);
- tree_impl->set_local_surface_id(local_surface_id_);
- has_pushed_local_surface_id_ = true;
+ if (TakeNewLocalSurfaceIdRequest())
+ tree_impl->RequestNewLocalSurfaceId();
+
+ tree_impl->SetLocalSurfaceIdFromParent(local_surface_id_from_parent_);
+ has_pushed_local_surface_id_from_parent_ = true;
if (pending_page_scale_animation_) {
tree_impl->SetPendingPageScaleAnimation(
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index 9aecadafd1e..2fbf3e6c021 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -292,9 +292,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
return event_listener_properties_[static_cast<size_t>(event_class)];
}
- void SetViewportSizeAndScale(const gfx::Size& device_viewport_size,
- float device_scale_factor,
- const viz::LocalSurfaceId& local_surface_id);
+ void SetViewportSizeAndScale(
+ const gfx::Size& device_viewport_size,
+ float device_scale_factor,
+ const viz::LocalSurfaceId& local_surface_id_from_parent);
void SetViewportVisibleRect(const gfx::Rect& visible_rect);
@@ -337,9 +338,20 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// If this LayerTreeHost needs a valid viz::LocalSurfaceId then commits will
// be deferred until a valid viz::LocalSurfaceId is provided.
- void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id);
- const viz::LocalSurfaceId& local_surface_id() const {
- return local_surface_id_;
+ void SetLocalSurfaceIdFromParent(
+ const viz::LocalSurfaceId& local_surface_id_from_parent);
+ const viz::LocalSurfaceId& local_surface_id_from_parent() const {
+ return local_surface_id_from_parent_;
+ }
+
+ // Requests the allocation of a new LocalSurfaceId on the compositor thread.
+ void RequestNewLocalSurfaceId();
+
+ // Returns the current state of the new LocalSurfaceId request and resets
+ // the state.
+ bool TakeNewLocalSurfaceIdRequest();
+ bool new_local_surface_id_request_for_testing() const {
+ return new_local_surface_id_request_;
}
void SetRasterColorSpace(const gfx::ColorSpace& raster_color_space);
@@ -418,7 +430,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
LayerListReverseIterator<Layer> rbegin();
LayerListReverseIterator<Layer> rend();
- // LayerTreeHostInProcess interface to Proxy.
+ // LayerTreeHost interface to Proxy.
void WillBeginMainFrame();
void DidBeginMainFrame();
void BeginMainFrame(const viz::BeginFrameArgs& args);
@@ -636,9 +648,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
- viz::LocalSurfaceId local_surface_id_;
+ viz::LocalSurfaceId local_surface_id_from_parent_;
// Used to detect surface invariant violations.
- bool has_pushed_local_surface_id_ = false;
+ bool has_pushed_local_surface_id_from_parent_ = false;
+ bool new_local_surface_id_request_ = false;
bool defer_commits_ = false;
SkColor background_color_ = SK_ColorWHITE;
diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc
index f411b4efca1..e599a6b4c1d 100644
--- a/chromium/cc/trees/layer_tree_host_common_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc
@@ -40,7 +40,8 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest {
void ReadTestFile(const std::string& name) {
base::FilePath test_data_dir;
- ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
+ ASSERT_TRUE(
+ base::PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
}
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index 910862ce9a8..df0758ace5d 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -16,6 +16,8 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/containers/adapters.h"
#include "base/containers/flat_map.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
@@ -23,6 +25,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
+#include "base/sys_info.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/base/histograms.h"
@@ -82,6 +85,7 @@
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gpu/texture_allocation.h"
+#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "components/viz/common/quads/frame_deadline.h"
@@ -90,6 +94,7 @@
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
+#include "components/viz/common/resources/platform_color.h"
#include "components/viz/common/traced_value.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
@@ -107,6 +112,53 @@
namespace cc {
namespace {
+// Used to accommodate finite precision when comparing scaled viewport and
+// content widths. While this value may seem large, width=device-width on an N7
+// V1 saw errors of ~0.065 between computed window and content widths.
+const float kMobileViewportWidthEpsilon = 0.15f;
+
+bool HasFixedPageScale(LayerTreeImpl* active_tree) {
+ return active_tree->min_page_scale_factor() ==
+ active_tree->max_page_scale_factor();
+}
+
+bool HasMobileViewport(LayerTreeImpl* active_tree) {
+ float window_width_dip = active_tree->current_page_scale_factor() *
+ active_tree->ScrollableViewportSize().width();
+ float content_width_css = active_tree->ScrollableSize().width();
+ return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
+}
+
+bool IsMobileOptimized(LayerTreeImpl* active_tree) {
+ bool has_mobile_viewport = HasMobileViewport(active_tree);
+ bool has_fixed_page_scale = HasFixedPageScale(active_tree);
+ return has_fixed_page_scale || has_mobile_viewport;
+}
+
+viz::ResourceFormat TileRasterBufferFormat(
+ const LayerTreeSettings& settings,
+ viz::ContextProvider* context_provider,
+ bool use_gpu_rasterization) {
+ // Software compositing always uses the native skia RGBA N32 format, but we
+ // just call it RGBA_8888 everywhere even though it can be BGRA ordering,
+ // because we don't need to communicate the actual ordering as the code all
+ // assumes the native skia format.
+ if (!context_provider)
+ return viz::RGBA_8888;
+
+ // RGBA4444 overrides the defaults if specified, but only for gpu compositing.
+ // It is always supported on platforms where it is specified.
+ if (settings.use_rgba_4444)
+ return viz::RGBA_4444;
+ // Otherwise we use BGRA textures if we can but it depends on the context
+ // capabilities, and we have different preferences when rastering to textures
+ // vs uploading textures.
+ const gpu::Capabilities& caps = context_provider->ContextCapabilities();
+ if (use_gpu_rasterization)
+ return viz::PlatformColor::BestSupportedRenderBufferFormat(caps);
+ return viz::PlatformColor::BestSupportedTextureFormat(caps);
+}
+
// Small helper class that saves the current viewport location as the user sees
// it and resets to the same location.
class ViewportAnchor {
@@ -212,7 +264,6 @@ LayerTreeHostImpl::LayerTreeHostImpl(
: client_(client),
task_runner_provider_(task_runner_provider),
current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
- layer_tree_frame_sink_(nullptr),
need_update_gpu_rasterization_status_(false),
content_has_slow_paths_(false),
content_has_non_aa_paint_(false),
@@ -294,7 +345,9 @@ LayerTreeHostImpl::LayerTreeHostImpl(
this, settings.top_controls_show_threshold,
settings.top_controls_hide_threshold);
- tile_manager_.SetDecodedImageTracker(&decoded_image_tracker_);
+ memory_pressure_listener_.reset(
+ new base::MemoryPressureListener(base::BindRepeating(
+ &LayerTreeHostImpl::OnMemoryPressure, base::Unretained(this))));
}
LayerTreeHostImpl::~LayerTreeHostImpl() {
@@ -882,8 +935,8 @@ bool LayerTreeHostImpl::HasDamage() const {
// If we have a new LocalSurfaceId, we must always submit a CompositorFrame
// because the parent is blocking on us.
bool local_surface_id_changed =
- settings_.enable_surface_synchronization &&
- (last_draw_local_surface_id_ != active_tree->local_surface_id());
+ last_draw_local_surface_id_ !=
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
return root_surface_has_visible_damage ||
active_tree_->property_trees()->effect_tree.HasCopyRequests() ||
@@ -1448,6 +1501,7 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
void LayerTreeHostImpl::DidModifyTilePriorities() {
// Mark priorities as dirty and schedule a PrepareTiles().
tile_priorities_dirty_ = true;
+ tile_manager_.DidModifyTilePriorities();
client_->SetNeedsPrepareTilesOnImplThread();
}
@@ -1730,8 +1784,10 @@ void LayerTreeHostImpl::ReclaimResources(
// If we're not visible, we likely released resources, so we want to
// aggressively flush here to make sure those DeleteTextures make it to the
// GPU process to free up the memory.
- if (!visible_)
- resource_provider_->FlushPendingDeletions();
+ if (!visible_ && layer_tree_frame_sink_->context_provider()) {
+ auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
+ gl->ShallowFlushCHROMIUM();
+ }
}
void LayerTreeHostImpl::OnDraw(const gfx::Transform& transform,
@@ -1844,8 +1900,39 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata() {
gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
metadata.root_background_color = active_tree_->background_color();
metadata.is_scroll_offset_at_top = active_tree_->TotalScrollOffset().y() == 0;
+ metadata.device_scale_factor = active_tree_->painted_device_scale_factor() *
+ active_tree_->device_scale_factor();
+ metadata.viewport_size_in_pixels = device_viewport_size();
+ metadata.top_controls_height =
+ browser_controls_offset_manager_->TopControlsHeight();
+ metadata.top_controls_shown_ratio =
+ browser_controls_offset_manager_->TopControlsShownRatio();
+ metadata.bottom_controls_height =
+ browser_controls_offset_manager_->BottomControlsHeight();
+ metadata.bottom_controls_shown_ratio =
+ browser_controls_offset_manager_->BottomControlsShownRatio();
+
+ bool allocate_new_local_surface_id =
+ last_draw_render_frame_metadata_ &&
+ (last_draw_render_frame_metadata_->top_controls_height !=
+ metadata.top_controls_height ||
+ last_draw_render_frame_metadata_->top_controls_shown_ratio !=
+ metadata.top_controls_shown_ratio ||
+ last_draw_render_frame_metadata_->bottom_controls_height !=
+ metadata.bottom_controls_height ||
+ last_draw_render_frame_metadata_->bottom_controls_shown_ratio !=
+ metadata.bottom_controls_shown_ratio);
+
+ viz::LocalSurfaceId local_surface_id =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
+ if (local_surface_id.is_valid()) {
+ if (allocate_new_local_surface_id)
+ local_surface_id = child_local_surface_id_allocator_.GenerateId();
+ metadata.local_surface_id = local_surface_id;
+ }
active_tree_->GetViewportSelection(&metadata.selection);
+ metadata.is_mobile_optimized = IsMobileOptimized(active_tree_.get());
return metadata;
}
@@ -1923,32 +2010,32 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
active_tree()->FinishSwapPromises(&metadata, &frame_token_allocator_);
if (render_frame_metadata_observer_) {
- RenderFrameMetadata render_frame_metadata = MakeRenderFrameMetadata();
+ last_draw_render_frame_metadata_ = MakeRenderFrameMetadata();
render_frame_metadata_observer_->OnRenderFrameSubmission(
- std::move(render_frame_metadata));
+ *last_draw_render_frame_metadata_);
}
metadata.latency_info.emplace_back(ui::SourceEventType::FRAME);
ui::LatencyInfo& new_latency_info = metadata.latency_info.back();
if (CommitToActiveTree()) {
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, 0, 0, frame_time, 1);
+ ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, 0, frame_time, 1);
} else {
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, 0, 0, frame_time,
+ ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, 0, frame_time,
1);
base::TimeTicks draw_time = base::TimeTicks::Now();
for (auto& latency : metadata.latency_info) {
latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, 0, draw_time, 1);
+ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, draw_time, 1);
}
}
ui::LatencyInfo::TraceIntermediateFlowEvents(metadata.latency_info,
"SwapBuffers");
// Collect all resource ids in the render passes into a single array.
- ResourceProvider::ResourceIdArray resources;
+ std::vector<viz::ResourceId> resources;
for (const auto& render_pass : frame->render_passes) {
for (auto* quad : render_pass->quad_list) {
for (viz::ResourceId resource_id : quad->resources)
@@ -1962,8 +2049,9 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
viz::CompositorFrame compositor_frame;
compositor_frame.metadata = std::move(metadata);
- resource_provider_->PrepareSendToParent(resources,
- &compositor_frame.resource_list);
+ resource_provider_->PrepareSendToParent(
+ resources, &compositor_frame.resource_list,
+ layer_tree_frame_sink_->context_provider());
compositor_frame.render_pass_list = std::move(frame->render_passes);
// TODO(fsamuel): Once all clients get their viz::LocalSurfaceId from their
// parent, the viz::LocalSurfaceId should hang off CompositorFrameMetadata.
@@ -1974,11 +2062,12 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
// LocalSurfaceId might slip through, but single-thread-without-scheduler
// mode is only used in tests so it doesn't matter.
CHECK(!settings_.single_thread_proxy_scheduler ||
- active_tree()->local_surface_id().is_valid());
+ active_tree()->local_surface_id_from_parent().is_valid());
layer_tree_frame_sink_->SetLocalSurfaceId(
- active_tree()->local_surface_id());
- last_draw_local_surface_id_ = active_tree()->local_surface_id();
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
}
+ last_draw_local_surface_id_ =
+ child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
if (const char* client_name = GetClientNameForMetrics()) {
size_t total_quad_count = 0;
for (const auto& pass : compositor_frame.render_pass_list)
@@ -2102,9 +2191,13 @@ void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
*supports_disable_msaa = caps.multisample_compatibility;
if (!caps.msaa_is_slow && !caps.avoid_stencil_buffers) {
// Skia may blacklist MSAA independently of Chrome. Query Skia for its max
- // supported sample count.
- SkColorType color_type =
- ResourceFormatToClosestSkColorType(settings_.preferred_tile_format);
+ // supported sample count. Assume gpu compositing + gpu raster for this, as
+ // that is what we are hoping to use.
+ viz::ResourceFormat tile_format = TileRasterBufferFormat(
+ settings_, layer_tree_frame_sink_->context_provider(),
+ /*use_gpu_rasterization=*/true);
+ SkColorType color_type = ResourceFormatToClosestSkColorType(
+ /*gpu_compositing=*/true, tile_format);
*max_msaa_samples =
gr_context->maxSurfaceSampleCountForColorType(color_type);
}
@@ -2244,7 +2337,7 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
void LayerTreeHostImpl::DidFinishImplFrame() {
impl_thread_phase_ = ImplThreadPhase::IDLE;
current_begin_frame_tracker_.Finish();
- decoded_image_tracker_.NotifyFrameFinished();
+ tile_manager_.decoded_image_tracker().NotifyFrameFinished();
}
void LayerTreeHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
@@ -2302,6 +2395,100 @@ void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() {
single_thread_synchronous_task_graph_runner_->RunUntilIdle();
}
+static uint32_t GetFlagsForSurfaceLayer(const SurfaceLayerImpl* layer) {
+ uint32_t flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch;
+ const auto& surface_id = layer->primary_surface_id();
+ if (layer->is_clipped()) {
+ flags |= viz::HitTestRegionFlags::kHitTestAsk;
+ }
+ if (surface_id.local_surface_id().is_valid()) {
+ flags |= viz::HitTestRegionFlags::kHitTestChildSurface;
+ } else {
+ flags |= viz::HitTestRegionFlags::kHitTestMine;
+ }
+ return flags;
+}
+
+static void PopulateHitTestRegion(viz::HitTestRegion* hit_test_region,
+ const LayerImpl* layer,
+ uint32_t flags,
+ const gfx::Rect& rect,
+ const viz::SurfaceId& surface_id,
+ float device_scale_factor) {
+ hit_test_region->frame_sink_id = surface_id.frame_sink_id();
+ hit_test_region->flags = flags;
+
+ hit_test_region->rect = rect;
+ // The transform of hit test region maps a point from parent hit test region
+ // to the local space. This is the inverse of screen space transform. Because
+ // hit test query wants the point in target to be in Pixel space, we
+ // counterscale the transform here. Note that the rect is scaled by dsf, so
+ // the point and the rect are still in the same space.
+ gfx::Transform surface_to_root_transform = layer->ScreenSpaceTransform();
+ surface_to_root_transform.Scale(SK_MScalar1 / device_scale_factor,
+ SK_MScalar1 / device_scale_factor);
+ // TODO(sunxd): Avoid losing precision by not using inverse if possible.
+ bool ok = surface_to_root_transform.GetInverse(&hit_test_region->transform);
+ // Note: If |ok| is false, the |transform| is set to the identity before
+ // returning, which is what we want.
+ ALLOW_UNUSED_LOCAL(ok);
+}
+
+base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
+ if (!settings_.build_hit_test_data)
+ return {};
+
+ base::Optional<viz::HitTestRegionList> hit_test_region_list(base::in_place);
+ hit_test_region_list->flags = viz::HitTestRegionFlags::kHitTestMine |
+ viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch;
+ hit_test_region_list->bounds = DeviceViewport();
+ hit_test_region_list->transform = DrawTransform();
+
+ float device_scale_factor = active_tree()->device_scale_factor();
+
+ Region overlapping_region;
+ for (const auto* layer : base::Reversed(*active_tree())) {
+ if (!layer->should_hit_test())
+ continue;
+
+ if (layer->is_surface_layer()) {
+ const auto* surface_layer = static_cast<const SurfaceLayerImpl*>(layer);
+
+ if (!surface_layer->surface_hit_testable()) {
+ overlapping_region.Union(MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), gfx::Rect(surface_layer->bounds())));
+ continue;
+ }
+
+ gfx::Rect content_rect(
+ gfx::ScaleToEnclosingRect(gfx::Rect(surface_layer->bounds()),
+ device_scale_factor, device_scale_factor));
+
+ gfx::Rect layer_screen_space_rect = MathUtil::MapEnclosingClippedRect(
+ surface_layer->ScreenSpaceTransform(),
+ gfx::Rect(surface_layer->bounds()));
+ if (overlapping_region.Contains(layer_screen_space_rect))
+ continue;
+
+ auto flag = GetFlagsForSurfaceLayer(surface_layer);
+ if (overlapping_region.Intersects(layer_screen_space_rect))
+ flag |= viz::HitTestRegionFlags::kHitTestAsk;
+ auto surface_id = surface_layer->primary_surface_id();
+ hit_test_region_list->regions.emplace_back();
+ PopulateHitTestRegion(&hit_test_region_list->regions.back(), layer, flag,
+ content_rect, surface_id, device_scale_factor);
+ continue;
+ }
+ // TODO(sunxd): Submit all overlapping layer bounds as hit test regions.
+ overlapping_region.Union(MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), gfx::Rect(layer->bounds())));
+ }
+
+ return hit_test_region_list;
+}
+
void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() {
// Check that we haven't already detected context loss because we get it via
// two paths: compositor context loss on the compositor thread and worker
@@ -2310,8 +2497,6 @@ void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() {
if (!has_valid_layer_tree_frame_sink_)
return;
has_valid_layer_tree_frame_sink_ = false;
- if (resource_provider_)
- resource_provider_->DidLoseContextProvider();
client_->DidLoseLayerTreeFrameSinkOnImplThread();
}
@@ -2502,6 +2687,14 @@ void LayerTreeHostImpl::ActivateSyncTree() {
// Activation can change the root scroll offset, so inform the synchronous
// input handler.
UpdateRootLayerStateForSynchronousInputHandler();
+
+ // Update the child's LocalSurfaceId.
+ if (active_tree()->local_surface_id_from_parent().is_valid()) {
+ child_local_surface_id_allocator_.UpdateFromParent(
+ active_tree()->local_surface_id_from_parent());
+ if (active_tree()->TakeNewLocalSurfaceIdRequest())
+ child_local_surface_id_allocator_.GenerateId();
+ }
}
void LayerTreeHostImpl::ActivateStateForImages() {
@@ -2509,6 +2702,30 @@ void LayerTreeHostImpl::ActivateStateForImages() {
tile_manager_.DidActivateSyncTree();
}
+void LayerTreeHostImpl::OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ // Only work for low-end devices for now.
+ if (!base::SysInfo::IsLowEndDevice())
+ return;
+
+ switch (level) {
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+ break;
+ case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+ ReleaseTileResources();
+ ReleaseTreeResources();
+ ClearUIResources();
+ if (image_decode_cache_) {
+ image_decode_cache_->SetShouldAggressivelyFreeResources(true);
+ image_decode_cache_->SetShouldAggressivelyFreeResources(false);
+ }
+ if (resource_pool_)
+ resource_pool_->OnPurgeMemory();
+ break;
+ }
+}
+
void LayerTreeHostImpl::SetVisible(bool visible) {
DCHECK(task_runner_provider_->IsImplThread());
@@ -2599,20 +2816,21 @@ void LayerTreeHostImpl::RecreateTileResources() {
void LayerTreeHostImpl::CreateTileManagerResources() {
raster_buffer_provider_ = CreateRasterBufferProvider();
+ viz::ResourceFormat tile_format = TileRasterBufferFormat(
+ settings_, layer_tree_frame_sink_->context_provider(),
+ use_gpu_rasterization_);
+
if (use_gpu_rasterization_) {
- int max_texture_size = layer_tree_frame_sink_->context_provider()
- ->ContextCapabilities()
- .max_texture_size;
image_decode_cache_ = std::make_unique<GpuImageDecodeCache>(
layer_tree_frame_sink_->worker_context_provider(),
use_oop_rasterization_,
- viz::ResourceFormatToClosestSkColorType(
- settings_.preferred_tile_format),
- settings_.decoded_image_working_set_budget_bytes, max_texture_size);
+ viz::ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true,
+ tile_format),
+ settings_.decoded_image_working_set_budget_bytes, max_texture_size_);
} else {
+ bool gpu_compositing = !!layer_tree_frame_sink_->context_provider();
image_decode_cache_ = std::make_unique<SoftwareImageDecodeCache>(
- viz::ResourceFormatToClosestSkColorType(
- settings_.preferred_tile_format),
+ viz::ResourceFormatToClosestSkColorType(gpu_compositing, tile_format),
settings_.decoded_image_working_set_budget_bytes);
}
@@ -2643,18 +2861,22 @@ LayerTreeHostImpl::CreateRasterBufferProvider() {
if (!compositor_context_provider)
return std::make_unique<BitmapRasterBufferProvider>(layer_tree_frame_sink_);
+ const gpu::Capabilities& caps =
+ compositor_context_provider->ContextCapabilities();
viz::RasterContextProvider* worker_context_provider =
layer_tree_frame_sink_->worker_context_provider();
+
+ viz::ResourceFormat tile_format = TileRasterBufferFormat(
+ settings_, compositor_context_provider, use_gpu_rasterization_);
+
if (use_gpu_rasterization_) {
DCHECK(worker_context_provider);
int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0;
return std::make_unique<GpuRasterBufferProvider>(
compositor_context_provider, worker_context_provider,
- resource_provider_.get(),
settings_.resource_settings.use_gpu_memory_buffer_resources,
- msaa_sample_count, settings_.preferred_tile_format,
- settings_.max_gpu_raster_tile_size,
+ msaa_sample_count, tile_format, settings_.max_gpu_raster_tile_size,
settings_.unpremultiply_and_dither_low_bit_depth_tiles,
use_oop_rasterization_);
}
@@ -2670,21 +2892,18 @@ LayerTreeHostImpl::CreateRasterBufferProvider() {
if (use_zero_copy) {
return std::make_unique<ZeroCopyRasterBufferProvider>(
- resource_provider_.get(),
layer_tree_frame_sink_->gpu_memory_buffer_manager(),
- compositor_context_provider, settings_.preferred_tile_format);
+ compositor_context_provider, tile_format);
}
const int max_copy_texture_chromium_size =
- compositor_context_provider->ContextCapabilities()
- .max_copy_texture_chromium_size;
+ caps.max_copy_texture_chromium_size;
return std::make_unique<OneCopyRasterBufferProvider>(
GetTaskRunner(), compositor_context_provider, worker_context_provider,
- resource_provider_.get(), max_copy_texture_chromium_size,
- settings_.use_partial_raster,
+ layer_tree_frame_sink_->gpu_memory_buffer_manager(),
+ max_copy_texture_chromium_size, settings_.use_partial_raster,
settings_.resource_settings.use_gpu_memory_buffer_resources,
- settings_.max_staging_buffer_usage_in_bytes,
- settings_.preferred_tile_format);
+ settings_.max_staging_buffer_usage_in_bytes, tile_format);
}
void LayerTreeHostImpl::SetLayerTreeMutator(
@@ -2711,7 +2930,7 @@ void LayerTreeHostImpl::QueueImageDecode(int request_id,
image.GetKeyForFrame(image.frame_index()).ToString());
// Optimistically specify the current raster color space, since we assume that
// it won't change.
- decoded_image_tracker_.QueueImageDecode(
+ tile_manager_.decoded_image_tracker().QueueImageDecode(
image, GetRasterColorSpace().color_space,
base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
base::Unretained(this), request_id));
@@ -2795,6 +3014,11 @@ void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() {
ClearUIResources();
resource_provider_ = nullptr;
+ if (layer_tree_frame_sink_->context_provider()) {
+ auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
+ gl->Finish();
+ }
+
// Release any context visibility before we destroy the LayerTreeFrameSink.
SetContextVisibility(false);
@@ -2824,27 +3048,23 @@ bool LayerTreeHostImpl::InitializeRenderer(
layer_tree_frame_sink_ = layer_tree_frame_sink;
has_valid_layer_tree_frame_sink_ = true;
- resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
- layer_tree_frame_sink_->context_provider(),
- layer_tree_frame_sink_->shared_bitmap_manager(),
- layer_tree_frame_sink_->gpu_memory_buffer_manager(),
- layer_tree_frame_sink_->capabilities().delegated_sync_points_required,
- settings_.resource_settings);
- if (!layer_tree_frame_sink_->context_provider()) {
- // This ResourcePool will vend software resources.
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), GetTaskRunner(),
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kSoftware,
- settings_.disallow_non_exact_resource_reuse);
+
+ auto* context_provider = layer_tree_frame_sink_->context_provider();
+ if (context_provider) {
+ max_texture_size_ =
+ context_provider->ContextCapabilities().max_texture_size;
} else {
- // The ResourcePool will vend gpu resources.
- resource_pool_ = std::make_unique<ResourcePool>(
- resource_provider_.get(), GetTaskRunner(),
- ResourcePool::kDefaultExpirationDelay, ResourcePool::Mode::kGpu,
- settings_.disallow_non_exact_resource_reuse);
+ // Pick an arbitrary limit here similar to what hardware might.
+ max_texture_size_ = 16 * 1024;
}
- if (features::IsVizHitTestingSurfaceLayerEnabled())
- layer_tree_frame_sink_->UpdateHitTestData(this);
+
+ resource_provider_ = std::make_unique<LayerTreeResourceProvider>(
+ layer_tree_frame_sink_->context_provider(),
+ layer_tree_frame_sink_->capabilities().delegated_sync_points_required);
+ resource_pool_ = std::make_unique<ResourcePool>(
+ resource_provider_.get(), layer_tree_frame_sink_->context_provider(),
+ GetTaskRunner(), ResourcePool::kDefaultExpirationDelay,
+ settings_.disallow_non_exact_resource_reuse);
// TODO(piman): Make oop raster always supported: http://crbug.com/786591
use_oop_rasterization_ = settings_.enable_oop_rasterization;
@@ -3128,9 +3348,15 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
if (!scrolling_node) {
- scroll_status.thread = SCROLL_IGNORED;
- if (settings_.is_layer_tree_for_subframe)
+ if (settings_.is_layer_tree_for_subframe) {
+ TRACE_EVENT_INSTANT0("cc", "Ignored - No ScrollNode (OOPIF)",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_UNKNOWN;
+ } else {
+ TRACE_EVENT_INSTANT0("cc", "Ignroed - No ScrollNode",
+ TRACE_EVENT_SCOPE_THREAD);
+ scroll_status.thread = SCROLL_IGNORED;
+ }
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNoScrollingLayer;
return scroll_status;
@@ -3140,6 +3366,9 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
browser_controls_offset_manager_->ScrollBegin();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ScrollBeginImpl",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ scrolling_node ? false : true);
active_tree_->SetCurrentlyScrollingNode(scrolling_node);
// TODO(majidvp): get rid of wheel_scrolling_ and set is_direct_manipulation
// in input_handler_proxy instead.
@@ -3152,6 +3381,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
// If the CurrentlyScrollingNode doesn't exist after distributing scroll
// delta, no scroller can scroll in the given delta hint direction(s).
if (!active_tree_->CurrentlyScrollingNode()) {
+ TRACE_EVENT_INSTANT0("cc", "Ignored - Didnt Scroll",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = InputHandler::SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
@@ -3211,6 +3442,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
if (layer_impl) {
if (!IsInitialScrollHitTestReliable(layer_impl, device_viewport_point)) {
+ TRACE_EVENT_INSTANT0("cc", "Failed Hit Test", TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_UNKNOWN;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kFailedHitTest;
@@ -3277,6 +3509,7 @@ bool LayerTreeHostImpl::IsInitialScrollHitTestReliable(
InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
ScrollState* scroll_state) {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollAnimatedBegin");
InputHandler::ScrollStatus scroll_status;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
@@ -3288,6 +3521,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
if (ScrollAnimationUpdateTarget(scroll_node, delta, base::TimeDelta())) {
scroll_status.thread = SCROLL_ON_IMPL_THREAD;
} else {
+ TRACE_EVENT_INSTANT0("cc", "Failed to create animation",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollable;
@@ -3377,6 +3612,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta,
base::TimeDelta delayed_by) {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollAnimated");
InputHandler::ScrollStatus scroll_status;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
@@ -3403,6 +3639,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
if (ScrollAnimationUpdateTarget(scroll_node, delta, delayed_by)) {
scroll_status.thread = SCROLL_ON_IMPL_THREAD;
} else {
+ TRACE_EVENT_INSTANT0("cc", "Failed to update animation",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollable;
@@ -3479,10 +3717,13 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
}
scroll_state.set_is_ending(true);
ScrollEndImpl(&scroll_state);
- if (settings_.is_layer_tree_for_subframe &&
- scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
- // If we get to here, we shouldn't return SCROLL_ON_IMPL_THREAD as otherwise
- // we'll mark the scroll as handled and the scroll won't bubble.
+ if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
+ // Update scroll_status.thread to SCROLL_IGNORED when there is no ongoing
+ // scroll animation, we can scroll on impl thread and yet, we couldn't
+ // create a new scroll animation. This happens when the scroller has hit its
+ // extent.
+ TRACE_EVENT_INSTANT0("cc", "Ignored - Scroller at extent",
+ TRACE_EVENT_SCOPE_THREAD);
scroll_status.thread = SCROLL_IGNORED;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollable;
@@ -3746,8 +3987,13 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) {
}
}
}
- active_tree_->SetCurrentlyScrollingNode(
- current_scroll_chain.empty() ? nullptr : current_scroll_chain.back());
+
+ scroll_node =
+ current_scroll_chain.empty() ? nullptr : current_scroll_chain.back();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode DistributeScrollDelta",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ scroll_node ? false : true);
+ active_tree_->SetCurrentlyScrollingNode(scroll_node);
scroll_state->set_scroll_chain_and_layer_tree(current_scroll_chain,
active_tree());
scroll_state->DistributeToScrollChainDescendant();
@@ -3803,8 +4049,27 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
DCHECK(scroll_state);
TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
- ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
+ auto& scroll_tree = active_tree_->property_trees()->scroll_tree;
+
+ ElementId provided_element =
+ scroll_state->data()->current_native_scrolling_element();
+ const auto* provided_scroll_node =
+ scroll_tree.FindNodeFromElementId(provided_element);
+
+ // If the currently scrolling node is not set, set it with
+ // |provided_scroll_node|.
ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+ if (scroll_node) {
+ // If |provided_scroll_node| is not null, make sure it matches
+ // |scroll_node|.
+ DCHECK(!provided_scroll_node || scroll_node == provided_scroll_node);
+ } else {
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ScrollBy",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ provided_scroll_node ? false : true);
+ active_tree_->SetCurrentlyScrollingNode(provided_scroll_node);
+ scroll_node = scroll_tree.CurrentlyScrollingNode();
+ }
if (!scroll_node)
return InputHandlerScrollResult();
@@ -3825,13 +4090,15 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
scroll_state->set_delta_consumed_for_scroll_sequence(
did_lock_scrolling_layer_);
scroll_state->set_is_direct_manipulation(!wheel_scrolling_);
- scroll_state->set_current_native_scrolling_node(
- active_tree()->property_trees()->scroll_tree.CurrentlyScrollingNode());
+ scroll_state->set_current_native_scrolling_node(scroll_node);
DistributeScrollDelta(scroll_state);
ScrollNode* current_scrolling_node =
scroll_state->current_native_scrolling_node();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ApplyDelta",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ current_scrolling_node ? false : true);
active_tree_->SetCurrentlyScrollingNode(current_scrolling_node);
did_lock_scrolling_layer_ =
scroll_state->delta_consumed_for_scroll_sequence();
@@ -3898,10 +4165,10 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
UpdateRootLayerStateForSynchronousInputHandler();
}
- scroll_result.current_offset = ScrollOffsetToVector2dF(
- scroll_tree.current_scroll_offset(scroll_node->element_id));
+ scroll_result.current_visual_offset =
+ ScrollOffsetToVector2dF(GetVisualScrollOffset(*scroll_node));
float scale_factor = active_tree()->current_page_scale_factor();
- scroll_result.current_offset.Scale(scale_factor);
+ scroll_result.current_visual_offset.Scale(scale_factor);
// Run animations which need to respond to updated scroll offset.
mutator_host_->TickScrollAnimations(
@@ -3917,6 +4184,9 @@ void LayerTreeHostImpl::RequestUpdateForSynchronousInputHandler() {
void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset(
const gfx::ScrollOffset& root_offset) {
+ TRACE_EVENT2("cc",
+ "LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset",
+ "offset_x", root_offset.x(), "offset_y", root_offset.y());
bool changed = active_tree_->DistributeRootScrollOffset(root_offset);
if (!changed)
return;
@@ -3936,9 +4206,7 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
return false;
const SnapContainerData& data = scroll_node->snap_container_data.value();
- ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree;
- gfx::ScrollOffset current_position =
- scroll_tree.current_scroll_offset(scroll_node->element_id);
+ gfx::ScrollOffset current_position = GetVisualScrollOffset(*scroll_node);
gfx::ScrollOffset snap_position;
if (!data.FindSnapPosition(current_position, did_scroll_x_for_scroll_gesture_,
@@ -3947,12 +4215,43 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
return false;
}
- ScrollAnimationCreate(
- scroll_node, ScrollOffsetToVector2dF(snap_position - current_position),
- base::TimeDelta());
+ gfx::Vector2dF delta =
+ ScrollOffsetToVector2dF(snap_position - current_position);
+ bool scrolls_main_viewport_scroll_layer =
+ scroll_node == ViewportMainScrollNode();
+ if (scrolls_main_viewport_scroll_layer) {
+ // Flash the overlay scrollbar even if the scroll dalta is 0.
+ if (settings_.scrollbar_flash_after_any_scroll_update) {
+ FlashAllScrollbars(false);
+ } else {
+ ScrollbarAnimationController* animation_controller =
+ ScrollbarAnimationControllerForElementId(scroll_node->element_id);
+ if (animation_controller)
+ animation_controller->WillUpdateScroll();
+ }
+ gfx::Vector2dF scaled_delta(delta);
+ scaled_delta.Scale(active_tree()->current_page_scale_factor());
+ viewport()->ScrollAnimated(scaled_delta, base::TimeDelta());
+ } else {
+ ScrollAnimationCreate(scroll_node, delta, base::TimeDelta());
+ }
return true;
}
+gfx::ScrollOffset LayerTreeHostImpl::GetVisualScrollOffset(
+ const ScrollNode& scroll_node) const {
+ const ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree;
+
+ bool scrolls_main_viewport_scroll_layer =
+ viewport()->MainScrollLayer() &&
+ viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node.id;
+
+ if (scrolls_main_viewport_scroll_layer)
+ return viewport()->TotalScrollOffset();
+ else
+ return scroll_tree.current_scroll_offset(scroll_node.element_id);
+}
+
bool LayerTreeHostImpl::GetSnapFlingInfo(
const gfx::Vector2dF& natural_displacement_in_viewport,
gfx::Vector2dF* initial_offset,
@@ -3966,9 +4265,8 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
gfx::Vector2dF natural_displacement_in_content =
gfx::ScaleVector2d(natural_displacement_in_viewport, 1.f / scale_factor);
- const ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree;
- *initial_offset = ScrollOffsetToVector2dF(
- scroll_tree.current_scroll_offset(scroll_node->element_id));
+ *initial_offset =
+ ScrollOffsetToVector2dF(GetVisualScrollOffset(*scroll_node));
bool did_scroll_x = did_scroll_x_for_scroll_gesture_ ||
natural_displacement_in_content.x() != 0;
@@ -3989,6 +4287,7 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
}
void LayerTreeHostImpl::ClearCurrentlyScrollingNode() {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ClearCurrentlyScrollingNode");
active_tree_->ClearCurrentlyScrollingNode();
did_lock_scrolling_layer_ = false;
scroll_affects_scroll_handler_ = false;
@@ -4118,6 +4417,9 @@ void LayerTreeHostImpl::PinchGestureBegin() {
client_->RenewTreePriority();
pinch_gesture_end_should_clear_scrolling_node_ = !CurrentlyScrollingNode();
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode PinchGestureBegin",
+ TRACE_EVENT_SCOPE_THREAD, "isNull",
+ OuterViewportScrollNode() ? false : true);
active_tree_->SetCurrentlyScrollingNode(OuterViewportScrollNode());
browser_controls_offset_manager_->PinchBegin();
}
@@ -4530,9 +4832,16 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
return;
}
- viz::ResourceFormat format = resource_provider_->best_texture_format();
+ viz::ResourceFormat format;
switch (bitmap.GetFormat()) {
case UIResourceBitmap::RGBA8:
+ if (layer_tree_frame_sink_->context_provider()) {
+ const gpu::Capabilities& caps =
+ layer_tree_frame_sink_->context_provider()->ContextCapabilities();
+ format = viz::PlatformColor::BestSupportedTextureFormat(caps);
+ } else {
+ format = viz::RGBA_8888;
+ }
break;
case UIResourceBitmap::ALPHA_8:
format = viz::ALPHA_8;
@@ -4548,13 +4857,12 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
// UIResources are assumed to be rastered in SRGB.
const gfx::ColorSpace& color_space = gfx::ColorSpace::CreateSRGB();
- int max_texture_size = resource_provider_->max_texture_size();
- if (source_size.width() > max_texture_size ||
- source_size.height() > max_texture_size) {
+ if (source_size.width() > max_texture_size_ ||
+ source_size.height() > max_texture_size_) {
// Must resize the bitmap to fit within the max texture size.
scaled = true;
int edge = std::max(source_size.width(), source_size.height());
- float scale = static_cast<float>(max_texture_size - 1) / edge;
+ float scale = static_cast<float>(max_texture_size_ - 1) / edge;
DCHECK_LT(scale, 1.f);
upload_size = gfx::ScaleToCeiledSize(source_size, scale, scale);
}
@@ -4680,7 +4988,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
shared_memory.get(), upload_size, format);
layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(memory_handle),
shared_bitmap_id);
- transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id, 0,
+ transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id,
upload_size, format);
}
transferable.color_space = color_space;
@@ -4976,6 +5284,7 @@ void LayerTreeHostImpl::ElementIsAnimatingChanged(
}
void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollOffsetAnimationFinished");
// TODO(majidvp): We should pass in the original starting scroll position here
ScrollStateData scroll_state_data;
ScrollState scroll_state(scroll_state_data);
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 82d50cc888b..3f93eb51e60 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -17,6 +17,7 @@
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/sequenced_task_runner.h"
#include "base/time/time.h"
#include "cc/base/synced_property.h"
@@ -41,11 +42,13 @@
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/managed_memory_policy.h"
#include "cc/trees/mutator_host_client.h"
+#include "cc/trees/render_frame_metadata.h"
#include "cc/trees/task_runner_provider.h"
#include "cc/trees/ukm_manager.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/gpu/context_cache_controller.h"
#include "components/viz/common/quads/render_pass.h"
+#include "components/viz/common/surfaces/child_local_surface_id_allocator.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "ui/gfx/geometry/rect.h"
@@ -75,7 +78,6 @@ class PendingTreeDurationHistogramTimer;
class PendingTreeRasterDurationHistogramTimer;
class RasterTilePriorityQueue;
class RasterBufferProvider;
-class RenderFrameMetadata;
class RenderFrameMetadataObserver;
class RenderingStatsInstrumentation;
class ResourcePool;
@@ -425,6 +427,7 @@ class CC_EXPORT LayerTreeHostImpl
void SetExternalTilePriorityConstraints(
const gfx::Rect& viewport_rect,
const gfx::Transform& transform) override;
+ base::Optional<viz::HitTestRegionList> BuildHitTestData() override;
void DidLoseLayerTreeFrameSink() override;
void DidReceiveCompositorFrameAck() override;
void DidPresentCompositorFrame(uint32_t presentation_token,
@@ -449,6 +452,7 @@ class CC_EXPORT LayerTreeHostImpl
LayerTreeFrameSink* layer_tree_frame_sink() const {
return layer_tree_frame_sink_;
}
+ int max_texture_size() const { return max_texture_size_; }
void ReleaseLayerTreeFrameSink();
std::string LayerListAsJson() const;
@@ -531,7 +535,9 @@ class CC_EXPORT LayerTreeHostImpl
ManagedMemoryPolicy ActualManagedMemoryPolicy() const;
void SetViewportSize(const gfx::Size& device_viewport_size);
- gfx::Size device_viewport_size() const { return device_viewport_size_; }
+ const gfx::Size& device_viewport_size() const {
+ return device_viewport_size_;
+ }
void SetViewportVisibleRect(const gfx::Rect& visible_rect);
gfx::Rect viewport_visible_rect() const { return viewport_visible_rect_; }
@@ -596,6 +602,10 @@ class CC_EXPORT LayerTreeHostImpl
virtual bool IsUIResourceOpaque(UIResourceId uid) const;
+ // This method gets the scroll offset for a regular scroller, or the combined
+ // visual and layout offsets of the viewport.
+ gfx::ScrollOffset GetVisualScrollOffset(const ScrollNode& scroll_node) const;
+
bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement_in_viewport,
gfx::Vector2dF* initial_offset,
gfx::Vector2dF* target_offset) const override;
@@ -851,6 +861,9 @@ class CC_EXPORT LayerTreeHostImpl
// active tree.
void ActivateStateForImages();
+ void OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel level);
+
std::unordered_map<UIResourceId, UIResourceData> ui_resource_map_;
// UIResources are held here once requested to be deleted until they are
// released from the display compositor, then the backing can be deleted.
@@ -861,7 +874,14 @@ class CC_EXPORT LayerTreeHostImpl
// associated with them anymore, as that is freed at the time of eviction.
std::set<UIResourceId> evicted_ui_resources_;
- LayerTreeFrameSink* layer_tree_frame_sink_;
+ // These are valid when has_valid_layer_tree_frame_sink_ is true.
+ //
+ // A pointer used for communicating with and submitting output to the display
+ // compositor.
+ LayerTreeFrameSink* layer_tree_frame_sink_ = nullptr;
+ // The maximum size (either width or height) that any texture can be. Also
+ // holds a reasonable value for software compositing bitmaps.
+ int max_texture_size_ = 0;
// The following scoped variables must not outlive the
// |layer_tree_frame_sink_|.
@@ -921,7 +941,6 @@ class CC_EXPORT LayerTreeHostImpl
const bool is_synchronous_single_threaded_;
TileManager tile_manager_;
- DecodedImageTracker decoded_image_tracker_;
gfx::Vector2dF accumulated_root_overscroll_;
@@ -1053,10 +1072,14 @@ class CC_EXPORT LayerTreeHostImpl
uint32_t last_presentation_token_ = 0u;
viz::LocalSurfaceId last_draw_local_surface_id_;
+ base::Optional<RenderFrameMetadata> last_draw_render_frame_metadata_;
+ viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
const int default_color_space_id_;
const gfx::ColorSpace default_color_space_;
+ std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 4c4570ee4d7..b7fdefd87dc 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -10,14 +10,17 @@
#include <cmath>
#include <utility>
+#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/transform_operations.h"
@@ -69,11 +72,13 @@
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/service/display/gl_renderer.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
+#include "gpu/GLES2/gl2extchromium.h"
#include "media/base/media.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -180,7 +185,7 @@ class LayerTreeHostImplTest : public testing::Test,
}
void DidActivateSyncTree() override {
// Make sure the active tree always has a valid LocalSurfaceId.
- host_impl_->active_tree()->set_local_surface_id(
+ host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
}
void WillPrepareTiles() override {}
@@ -242,7 +247,7 @@ class LayerTreeHostImplTest : public testing::Test,
bool init = host_impl_->InitializeRenderer(layer_tree_frame_sink_.get());
host_impl_->SetViewportSize(gfx::Size(10, 10));
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
- host_impl_->active_tree()->set_local_surface_id(
+ host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
// Set the viz::BeginFrameArgs so that methods which use it are able to.
host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
@@ -1063,15 +1068,23 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
status.main_thread_scrolling_reasons);
}
+class LostGLES2Interface : public viz::TestGLES2Interface {
+ public:
+ LostGLES2Interface() = default;
+
+ void InitializeTestContext() override {
+ LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB);
+ }
+};
+
TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
- std::unique_ptr<TestWebGraphicsContext3D> context_owned =
- TestWebGraphicsContext3D::Create();
- context_owned->set_context_lost(true);
+ auto gl_owned = std::make_unique<LostGLES2Interface>();
// Initialization will fail.
- EXPECT_FALSE(CreateHostImpl(
- DefaultSettings(),
- FakeLayerTreeFrameSink::Create3d(std::move(context_owned))));
+ EXPECT_FALSE(
+ CreateHostImpl(DefaultSettings(),
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned))));
SetupScrollAndContentsLayers(gfx::Size(100, 100));
@@ -1643,7 +1656,7 @@ TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) {
InputHandlerScrollResult result =
host_impl_->ScrollBy(UpdateState(scroll_position, delta).get());
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), overflow->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(4, 4), result.current_offset);
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(4, 4), result.current_visual_offset);
gfx::Vector2dF initial_offset, target_offset;
EXPECT_TRUE(host_impl_->GetSnapFlingInfo(gfx::Vector2dF(10, 10),
@@ -2589,8 +2602,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
ui::LatencyInfo latency_info;
latency_info.set_trace_id(5);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
- 1234);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0);
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(latency_info));
@@ -3532,7 +3544,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->active_tree()->BuildPropertyTreesForTesting();
host_impl_->active_tree()->DidBecomeActive();
host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain();
- host_impl_->active_tree()->set_local_surface_id(
+ host_impl_->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
DrawFrame();
@@ -4884,11 +4896,9 @@ class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
bool tile_missing,
bool had_incomplete_tile,
bool animating,
- ResourceProvider* resource_provider,
scoped_refptr<AnimationTimeline> timeline) {
return base::WrapUnique(new MissingTextureAnimatingLayer(
- tree_impl, id, tile_missing, had_incomplete_tile, animating,
- resource_provider, timeline));
+ tree_impl, id, tile_missing, had_incomplete_tile, animating, timeline));
}
void AppendQuads(viz::RenderPass* render_pass,
@@ -4906,7 +4916,6 @@ class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
bool tile_missing,
bool had_incomplete_tile,
bool animating,
- ResourceProvider* resource_provider,
scoped_refptr<AnimationTimeline> timeline)
: DidDrawCheckLayer(tree_impl, id),
tile_missing_(tile_missing),
@@ -4946,8 +4955,7 @@ static void CreateLayerFromState(
static int layer_id = 2;
root->test_properties()->AddChild(MissingTextureAnimatingLayer::Create(
root->layer_tree_impl(), layer_id++, state.has_missing_tile,
- state.has_incomplete_tile, state.is_animating,
- root->layer_tree_impl()->resource_provider(), timeline));
+ state.has_incomplete_tile, state.is_animating, timeline));
auto* layer =
static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back());
if (state.has_copy_request)
@@ -6692,9 +6700,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) {
EXPECT_EQ(gfx::ScrollOffset(0, 50), child_layer->CurrentScrollOffset());
host_impl_->DidFinishImplFrame();
- // Second ScrollAnimated should still latch to the grand_child_layer.
+ // Second ScrollAnimated should still latch to the grand_child_layer. Since it
+ // is already at its extent and no scrolling happens, the scroll result must
+ // be ignored.
EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
+ InputHandler::SCROLL_IGNORED,
host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, -100)).thread);
begin_frame_args.frame_time =
@@ -8364,15 +8374,10 @@ class BlendStateCheckLayer : public LayerImpl {
quads_appended_(false),
quad_rect_(5, 5, 5, 5),
quad_visible_rect_(5, 5, 5, 5) {
- if (tree_impl->context_provider()) {
- resource_id_ = resource_provider->CreateGpuTextureResource(
- gfx::Size(1, 1), viz::ResourceTextureHint::kDefault, viz::RGBA_8888,
- gfx::ColorSpace());
- } else {
- resource_id_ = resource_provider->CreateBitmapResource(
- gfx::Size(1, 1), gfx::ColorSpace(), viz::RGBA_8888);
- }
- resource_provider->AllocateForTesting(resource_id_);
+ resource_id_ = resource_provider->ImportResource(
+ viz::TransferableResource::MakeSoftware(
+ viz::SharedBitmap::GenerateId(), gfx::Size(1, 1), viz::RGBA_8888),
+ viz::SingleReleaseCallback::Create(base::DoNothing()));
SetBounds(gfx::Size(10, 10));
SetDrawsContent(true);
}
@@ -9053,10 +9058,11 @@ class FakeDrawableLayerImpl : public LayerImpl {
// submitted to the LayerTreeFrameSink, where it should request to swap only
// the sub-buffer that is damaged.
TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_have_post_sub_buffer(true);
scoped_refptr<viz::TestContextProvider> context_provider(
- viz::TestContextProvider::Create());
+ viz::TestContextProvider::Create(std::move(gl_owned)));
context_provider->BindToCurrentThread();
- context_provider->TestContext3d()->set_have_post_sub_buffer(true);
std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink(
FakeLayerTreeFrameSink::Create3d(context_provider));
@@ -9090,7 +9096,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
root->test_properties()->AddChild(std::move(child));
layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root));
layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting();
- layer_tree_host_impl->active_tree()->set_local_surface_id(
+ layer_tree_host_impl->active_tree()->SetLocalSurfaceIdFromParent(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)));
TestFrameData frame;
@@ -9190,11 +9196,10 @@ class FakeLayerWithQuads : public LayerImpl {
};
TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
- std::unique_ptr<TestWebGraphicsContext3D> context =
- TestWebGraphicsContext3D::Create();
- TestWebGraphicsContext3D* context3d = context.get();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ viz::TestGLES2Interface* gl = gl_owned.get();
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink(
- FakeLayerTreeFrameSink::Create3d(std::move(context)));
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
std::unique_ptr<LayerImpl> root_layer =
@@ -9215,27 +9220,21 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer));
host_impl_->active_tree()->BuildPropertyTreesForTesting();
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
TestFrameData frame;
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
- EXPECT_GT(context3d->NumTextures(), 0u);
+ EXPECT_GT(gl->NumTextures(), 0u);
// Kill the layer tree.
host_impl_->active_tree()->DetachLayers();
// There should be no textures left in use after.
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
}
-class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
- public:
- MOCK_METHOD1(useProgram, void(GLuint program));
- MOCK_METHOD4(drawElements,
- void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
-};
TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
@@ -9548,8 +9547,7 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) {
AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr);
// Gpu compositing.
- layer_tree_frame_sink_ =
- FakeLayerTreeFrameSink::Create3d(TestWebGraphicsContext3D::Create());
+ layer_tree_frame_sink_ = FakeLayerTreeFrameSink::Create3d();
host_impl_->SetVisible(true);
host_impl_->InitializeRenderer(layer_tree_frame_sink_.get());
{
@@ -9712,58 +9710,58 @@ TEST_F(LayerTreeHostImplTestPrepareTiles, PrepareTilesWhenInvisible) {
}
TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
- std::unique_ptr<TestWebGraphicsContext3D> context =
- TestWebGraphicsContext3D::Create();
- TestWebGraphicsContext3D* context3d = context.get();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ viz::TestGLES2Interface* gl = gl_owned.get();
+
std::unique_ptr<FakeLayerTreeFrameSink> layer_tree_frame_sink =
- FakeLayerTreeFrameSink::Create3d();
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned));
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
UIResourceId ui_resource_id = 1;
bool is_opaque = false;
UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
viz::ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
// Multiple requests with the same id is allowed. The previous texture is
// deleted.
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
viz::ResourceId id2 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id2);
EXPECT_NE(id1, id2);
// Deleting invalid UIResourceId is allowed and does not change state.
host_impl_->DeleteUIResource(-1);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
// Should return zero for invalid UIResourceId. Number of textures should
// not change.
EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
host_impl_->DeleteUIResource(ui_resource_id);
EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
// Should not change state for multiple deletion on one UIResourceId
host_impl_->DeleteUIResource(ui_resource_id);
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
}
TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
- std::unique_ptr<TestWebGraphicsContext3D> context =
- TestWebGraphicsContext3D::Create();
- TestWebGraphicsContext3D* context3d = context.get();
- context3d->set_support_compressed_texture_etc1(true);
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_support_compressed_texture_etc1(true);
+ viz::TestGLES2Interface* gl = gl_owned.get();
+
CreateHostImpl(DefaultSettings(),
- FakeLayerTreeFrameSink::Create3d(std::move(context)));
+ FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)));
- EXPECT_EQ(0u, context3d->NumTextures());
+ EXPECT_EQ(0u, gl->NumTextures());
gfx::Size size(4, 4);
// SkImageInfo has no support for ETC1. The |info| below contains the right
@@ -9776,7 +9774,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
UIResourceBitmap bitmap(std::move(pixel_ref), size);
UIResourceId ui_resource_id = 1;
host_impl_->CreateUIResource(ui_resource_id, bitmap);
- EXPECT_EQ(1u, context3d->NumTextures());
+ EXPECT_EQ(1u, gl->NumTextures());
viz::ResourceId id1 = host_impl_->ResourceIdForUIResource(ui_resource_id);
EXPECT_NE(0u, id1);
}
@@ -9854,9 +9852,8 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
constexpr double refresh_rate = 60.0;
auto layer_tree_frame_sink = std::make_unique<viz::TestLayerTreeFrameSink>(
context_provider, viz::TestContextProvider::CreateWorker(), nullptr,
- nullptr, viz::RendererSettings(),
- base::ThreadTaskRunnerHandle::Get().get(), synchronous_composite,
- disable_display_vsync, refresh_rate);
+ viz::RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
layer_tree_frame_sink->SetClient(&test_client);
CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink));
@@ -10257,8 +10254,7 @@ TEST_F(LayerTreeHostImplLatencyInfoRendererTest,
// component attached via LatencyInfoSwapPromise.
ui::LatencyInfo latency_info;
latency_info.set_trace_id(5);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
- 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0);
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(latency_info));
host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
@@ -10313,8 +10309,7 @@ TEST_F(LayerTreeHostImplLatencyInfoUITest,
// component attached via LatencyInfoSwapPromise.
ui::LatencyInfo latency_info;
latency_info.set_trace_id(5);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0,
- 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0);
std::unique_ptr<SwapPromise> swap_promise(
new LatencyInfoSwapPromise(latency_info));
host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise));
@@ -11626,6 +11621,52 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) {
EXPECT_FALSE(last_on_draw_frame_->has_no_damage);
}
+// TODO(gyuyoung): OnMemoryPressure disabled on ASAN, TSAN, Android, windows
+// due to the test failure. Will be handled on
+// http://crbug.com/839687.
+#if defined(OS_WIN) || defined(OS_ANDROID) || defined(ADDRESS_SANITIZER) || \
+ defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
+ defined(LEAK_SANITIZER)
+#define MAYBE_OnMemoryPressure DISABLED_OnMemoryPressure
+#else
+#define MAYBE_OnMemoryPressure OnMemoryPressure
+#endif
+
+TEST_F(LayerTreeHostImplTest, MAYBE_OnMemoryPressure) {
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableLowEndDeviceMode);
+
+ const gfx::Size viewport_size(100, 100);
+ host_impl_->SetViewportSize(viewport_size);
+ host_impl_->CreatePendingTree();
+ scoped_refptr<FakeRasterSource> raster_source(
+ FakeRasterSource::CreateFilled(viewport_size));
+ std::unique_ptr<FakePictureLayerImpl> layer(
+ FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(),
+ 11, raster_source));
+ layer->SetBounds(viewport_size);
+ layer->SetDrawsContent(true);
+ host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer));
+ host_impl_->pending_tree()->BuildPropertyTreesForTesting();
+ host_impl_->ActivateSyncTree();
+ const gfx::Transform draw_transform;
+ host_impl_->OnDraw(draw_transform, gfx::Rect(viewport_size), false);
+
+ std::unique_ptr<base::ProcessMetrics> metric(
+ base::ProcessMetrics::CreateCurrentProcessMetrics());
+ size_t current_memory_usage = metric->GetMallocUsage();
+
+ base::MemoryPressureListener::SimulatePressureNotification(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+ base::RunLoop().RunUntilIdle();
+
+ size_t memory_usage_after_memory_pressure = metric->GetMallocUsage();
+
+ // Memory usage after the memory pressure should be less than previous one.
+ EXPECT_LT(memory_usage_after_memory_pressure, current_memory_usage);
+ EXPECT_FALSE(host_impl_->use_gpu_rasterization());
+}
+
// We will force the touch event handler to be passive if we touch on a layer
// which is the current scrolling layer.
TEST_F(LayerTreeHostImplTest, TouchInsideFlingLayer) {
@@ -13464,8 +13505,7 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnLayerTreeFrameSinkChange) {
host_impl_->SetVisible(true);
// InitializeRenderer with a gpu-raster enabled output surface.
- auto gpu_raster_layer_tree_frame_sink =
- FakeLayerTreeFrameSink::Create3d(TestWebGraphicsContext3D::Create());
+ auto gpu_raster_layer_tree_frame_sink = FakeLayerTreeFrameSink::Create3d();
host_impl_->InitializeRenderer(gpu_raster_layer_tree_frame_sink.get());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
@@ -13743,7 +13783,10 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) {
std::unique_ptr<FakeRecordingSource> recording_source =
FakeRecordingSource::CreateFilledRecordingSource(layer_size);
PaintImage checkerable_image =
- CreateDiscardablePaintImage(gfx::Size(500, 500));
+ PaintImageBuilder::WithCopy(
+ CreateDiscardablePaintImage(gfx::Size(500, 500)))
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
+ .TakePaintImage();
recording_source->add_draw_image(checkerable_image, gfx::Point(0, 0));
SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
@@ -13773,6 +13816,11 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) {
root->SetDrawsContent(true);
pending_tree->BuildPropertyTreesForTesting();
+ // Update the decoding state map for the tracker so it knows the correct
+ // decoding preferences for the image.
+ host_impl_->tile_manager()->checker_image_tracker().UpdateImageDecodingHints(
+ raster_source->TakeDecodingModeMap());
+
// CompleteCommit which should perform a PrepareTiles, adding tilings for the
// root layer, each one having a raster task.
host_impl_->CommitComplete();
@@ -14251,5 +14299,211 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) {
EXPECT_TRUE(selection_2.end.visible());
}
+// Tests ScrollBy() to see if the method sets the scroll tree's currently
+// scrolling node and the ScrollState properly.
+TEST_F(LayerTreeHostImplTest, ScrollByScrollingNode) {
+ SetupScrollAndContentsLayers(gfx::Size(100, 100));
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ // Create a ScrollState object with no scrolling element.
+ ScrollStateData scroll_state_data;
+ scroll_state_data.set_current_native_scrolling_element(ElementId());
+ std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data));
+
+ ScrollTree& scroll_tree =
+ host_impl_->active_tree()->property_trees()->scroll_tree;
+
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point()).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
+
+ ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
+ EXPECT_TRUE(scroll_node);
+
+ host_impl_->ScrollBy(scroll_state.get());
+
+ // Check to see the scroll tree's currently scrolling node is
+ // still the same. |scroll_state|'s scrolling node should match
+ // it.
+ EXPECT_EQ(scroll_node, scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_node(),
+ scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_element(),
+ scroll_tree.CurrentlyScrollingNode()->element_id);
+
+ // Set the scroll tree's currently scrolling node to null. Calling
+ // ScrollBy() should set the node to the one inside |scroll_state|.
+ host_impl_->active_tree()->SetCurrentlyScrollingNode(nullptr);
+ EXPECT_FALSE(scroll_tree.CurrentlyScrollingNode());
+
+ host_impl_->ScrollBy(scroll_state.get());
+
+ EXPECT_EQ(scroll_node, scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_node(),
+ scroll_tree.CurrentlyScrollingNode());
+ EXPECT_EQ(scroll_state->data()->current_native_scrolling_element(),
+ scroll_tree.CurrentlyScrollingNode()->element_id);
+}
+
+class HitTestRegionListGeneratingLayerTreeHostImplTest
+ : public LayerTreeHostImplTest {
+ public:
+ bool CreateHostImpl(
+ const LayerTreeSettings& settings,
+ std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) override {
+ // Enable hit test data generation with the CompositorFrame.
+ LayerTreeSettings new_settings = settings;
+ new_settings.build_hit_test_data = true;
+ return CreateHostImplWithTaskRunnerProvider(
+ new_settings, std::move(layer_tree_frame_sink), &task_runner_provider_);
+ }
+};
+
+// When disabled, no HitTestRegionList should be generated.
+// Test to ensure that hit test data is created correctly from the active layer
+// tree.
+TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) {
+ // Setup surface layers in LayerTreeHostImpl.
+ host_impl_->CreatePendingTree();
+ host_impl_->ActivateSyncTree();
+ host_impl_->SetViewportSize(gfx::Size(1024, 768));
+
+ std::unique_ptr<LayerImpl> root =
+ LayerImpl::Create(host_impl_->active_tree(), 1);
+ std::unique_ptr<SurfaceLayerImpl> surface_child =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), 3);
+
+ surface_child->SetPosition(gfx::PointF(50, 50));
+ surface_child->SetBounds(gfx::Size(100, 100));
+ surface_child->SetDrawsContent(true);
+ surface_child->SetSurfaceHitTestable(true);
+
+ root->test_properties()->AddChild(std::move(surface_child));
+ host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ base::Optional<viz::HitTestRegionList> hit_test_region_list =
+ host_impl_->BuildHitTestData();
+ EXPECT_FALSE(hit_test_region_list);
+}
+
+// Test to ensure that hit test data is created correctly from the active layer
+// tree.
+TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) {
+ // Setup surface layers in LayerTreeHostImpl.
+ host_impl_->CreatePendingTree();
+ host_impl_->ActivateSyncTree();
+
+ // The structure of the layer tree:
+ // +-Root (1024x768)
+ // +---intermediate_layer (200, 300), 200x200
+ // +-----surface_child1 (50, 50), 100x100, Rotate(45)
+ // +---surface_child2 (450, 300), 100x100
+ // +---overlapping_layer (500, 350), 200x200
+ std::unique_ptr<LayerImpl> intermediate_layer =
+ LayerImpl::Create(host_impl_->active_tree(), 2);
+ std::unique_ptr<SurfaceLayerImpl> surface_child1 =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), 3);
+ std::unique_ptr<SurfaceLayerImpl> surface_child2 =
+ SurfaceLayerImpl::Create(host_impl_->active_tree(), 4);
+ std::unique_ptr<LayerImpl> overlapping_layer =
+ LayerImpl::Create(host_impl_->active_tree(), 5);
+
+ host_impl_->SetViewportSize(gfx::Size(1024, 768));
+
+ intermediate_layer->SetPosition(gfx::PointF(200, 300));
+ intermediate_layer->SetBounds(gfx::Size(200, 200));
+
+ surface_child1->SetPosition(gfx::PointF(50, 50));
+ surface_child1->SetBounds(gfx::Size(100, 100));
+ gfx::Transform rotate;
+ rotate.Rotate(45);
+ surface_child1->test_properties()->transform = rotate;
+ surface_child1->SetDrawsContent(true);
+ surface_child1->SetSurfaceHitTestable(true);
+
+ surface_child2->SetPosition(gfx::PointF(450, 300));
+ surface_child2->SetBounds(gfx::Size(100, 100));
+ surface_child2->SetDrawsContent(true);
+ surface_child2->SetSurfaceHitTestable(true);
+
+ overlapping_layer->SetPosition(gfx::PointF(500, 350));
+ overlapping_layer->SetBounds(gfx::Size(200, 200));
+ overlapping_layer->SetDrawsContent(true);
+
+ viz::LocalSurfaceId child_local_surface_id(2,
+ base::UnguessableToken::Create());
+ viz::FrameSinkId frame_sink_id(2, 0);
+ viz::SurfaceId child_surface_id(frame_sink_id, child_local_surface_id);
+ surface_child1->SetPrimarySurfaceId(child_surface_id, base::nullopt);
+ surface_child2->SetPrimarySurfaceId(child_surface_id, base::nullopt);
+
+ std::unique_ptr<LayerImpl> root =
+ LayerImpl::Create(host_impl_->active_tree(), 1);
+ host_impl_->active_tree()->SetRootLayerForTesting(std::move(root));
+ intermediate_layer->test_properties()->AddChild(std::move(surface_child1));
+ host_impl_->active_tree()
+ ->root_layer_for_testing()
+ ->test_properties()
+ ->AddChild(std::move(intermediate_layer));
+ host_impl_->active_tree()
+ ->root_layer_for_testing()
+ ->test_properties()
+ ->AddChild(std::move(surface_child2));
+ host_impl_->active_tree()
+ ->root_layer_for_testing()
+ ->test_properties()
+ ->AddChild(std::move(overlapping_layer));
+
+ host_impl_->active_tree()->BuildPropertyTreesForTesting();
+
+ constexpr gfx::Rect kFrameRect(0, 0, 1024, 768);
+
+ base::Optional<viz::HitTestRegionList> hit_test_region_list =
+ host_impl_->BuildHitTestData();
+ // Generating HitTestRegionList should have been enabled for this test.
+ ASSERT_TRUE(hit_test_region_list);
+
+ // Since surface_child2 draws in front of surface_child1, it should also be in
+ // the front of the hit test region list.
+ uint32_t expected_flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch |
+ viz::HitTestRegionFlags::kHitTestMine;
+ EXPECT_EQ(expected_flags, hit_test_region_list->flags);
+ EXPECT_EQ(kFrameRect, hit_test_region_list->bounds);
+ EXPECT_EQ(2u, hit_test_region_list->regions.size());
+
+ EXPECT_EQ(child_surface_id.frame_sink_id(),
+ hit_test_region_list->regions[1].frame_sink_id);
+ expected_flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch |
+ viz::HitTestRegionFlags::kHitTestChildSurface;
+ EXPECT_EQ(expected_flags, hit_test_region_list->regions[1].flags);
+ gfx::Transform child1_transform;
+ child1_transform.Rotate(-45);
+ child1_transform.Translate(-250, -350);
+ EXPECT_TRUE(child1_transform.ApproximatelyEqual(
+ hit_test_region_list->regions[1].transform));
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ hit_test_region_list->regions[1].rect.ToString());
+
+ EXPECT_EQ(child_surface_id.frame_sink_id(),
+ hit_test_region_list->regions[0].frame_sink_id);
+ expected_flags = viz::HitTestRegionFlags::kHitTestMouse |
+ viz::HitTestRegionFlags::kHitTestTouch |
+ viz::HitTestRegionFlags::kHitTestChildSurface |
+ viz::HitTestRegionFlags::kHitTestAsk;
+ EXPECT_EQ(expected_flags, hit_test_region_list->regions[0].flags);
+ gfx::Transform child2_transform;
+ child2_transform.Translate(-450, -300);
+ EXPECT_TRUE(child2_transform.ApproximatelyEqual(
+ hit_test_region_list->regions[0].transform));
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ hit_test_region_list->regions[0].rect.ToString());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc
index 92765547065..871e1a10a17 100644
--- a/chromium/cc/trees/layer_tree_host_perftest.cc
+++ b/chromium/cc/trees/layer_tree_host_perftest.cc
@@ -59,9 +59,8 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
return std::make_unique<viz::TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
- refresh_rate);
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
}
void BeginTest() override {
@@ -140,7 +139,8 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest {
void ReadTestFile(const std::string& name) {
base::FilePath test_data_dir;
- ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
+ ASSERT_TRUE(
+ base::PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
}
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index c0706014c1a..378d4338879 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -37,8 +37,8 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackgroundFilters(filters);
-#if defined(OS_WIN)
- // Windows has 436 pixels off by 1: crbug.com/259915
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
+ // Windows and ARM64 have 436 pixels off by 1: crbug.com/259915
float percentage_pixels_large_error = 1.09f; // 436px / (200*200)
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
@@ -79,9 +79,14 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
5.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackgroundFilters(filters);
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
// Windows has 5.9325% pixels by at most 2: crbug.com/259922
float percentage_pixels_large_error = 6.0f;
+#else
+ // Loongson has 8.685% pixels by at most 2: crbug.com/819110
+ float percentage_pixels_large_error = 8.7f;
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 2.f;
int large_error_allowed = 2;
@@ -141,12 +146,17 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
2.f, SkBlurImageFilter::kClamp_TileMode));
blur->SetBackgroundFilters(filters);
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 116 pixels off by at most 2: crbug.com/225027
float percentage_pixels_large_error = 0.3f; // 116px / (200*200), rounded up
+ int large_error_allowed = 2;
+#else
+ float percentage_pixels_large_error = 0.25f; // 96px / (200*200), rounded up
+ int large_error_allowed = 1;
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
- int large_error_allowed = 2;
int small_error_allowed = 0;
pixel_comparator_.reset(new FuzzyPixelComparator(
true, // discard_alpha
@@ -414,12 +424,21 @@ class ImageScaledBackgroundFilter : public LayerTreeHostFiltersPixelTest {
filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f));
filter->SetBackgroundFilters(filters);
+#if defined(OS_WIN) || defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 153 pixels off by at most 2: crbug.com/225027
float percentage_pixels_large_error = 0.3825f; // 153px / (200*200)
+ int large_error_allowed = 2;
+#elif defined(_MIPS_ARCH_LOONGSON)
+ // Loongson has 2 pixels off by at most 2: crbug.com/819075
+ float percentage_pixels_large_error = 0.005f; // 2px / (200*200)
+ int large_error_allowed = 2;
+#else
+ float percentage_pixels_large_error = 0.0325f; // 13px / (200*200)
+ int large_error_allowed = 1;
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
- int large_error_allowed = 2;
int small_error_allowed = 0;
pixel_comparator_.reset(new FuzzyPixelComparator(
true, // discard_alpha
@@ -726,8 +745,8 @@ class RotatedDropShadowFilterTest : public LayerTreeHostFiltersPixelTest {
background->AddChild(child);
-#if defined(OS_WIN)
- // Windows has 3 pixels off by 1: crbug.com/259915
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
+ // Windows and ARM64 have 3 pixels off by 1: crbug.com/259915
float percentage_pixels_large_error = 0.00333334f; // 3px / (300*300)
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
@@ -941,9 +960,15 @@ class BlurFilterWithClip : public LayerTreeHostFiltersPixelTest {
// Force the allocation a larger textures.
set_enlarge_texture_amount(gfx::Size(50, 50));
+#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 1880 pixels off by 1: crbug.com/259915
float percentage_pixels_large_error = 4.7f; // 1880px / (200*200)
+#else
+ // Differences in floating point calculation on ARM means a small percentage
+ // of pixels will have small differences.
+ float percentage_pixels_large_error = 2.76f; // 1104px / (200*200)
+#endif
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
int large_error_allowed = 2;
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
index 02e0e7bf246..6a6cfa4d11e 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -312,13 +312,13 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
float average_error_allowed_in_bad_pixels = 100.0f;
int large_error_allowed = 256;
int small_error_allowed = 0;
- pixel_comparator_.reset(new FuzzyPixelComparator(
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
true, // discard_alpha
percentage_pixels_large_error,
percentage_pixels_small_error,
average_error_allowed_in_bad_pixels,
large_error_allowed,
- small_error_allowed));
+ small_error_allowed);
RunPixelResourceTest(background,
base::FilePath(
@@ -363,13 +363,13 @@ TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
float average_error_allowed_in_bad_pixels = 256.0f;
int large_error_allowed = 256;
int small_error_allowed = 0;
- pixel_comparator_.reset(new FuzzyPixelComparator(
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
true, // discard_alpha
percentage_pixels_large_error,
percentage_pixels_small_error,
average_error_allowed_in_bad_pixels,
large_error_allowed,
- small_error_allowed));
+ small_error_allowed);
RunPixelResourceTest(background,
base::FilePath(
@@ -428,13 +428,21 @@ class LayerTreeHostMaskAsBlendingPixelTest
average_error_allowed_in_bad_pixels = 3.5f;
large_error_allowed = 15;
small_error_allowed = 1;
+ } else {
+#if defined(ARCH_CPU_ARM64)
+ // Differences in floating point calculation on ARM means a small
+ // percentage of pixels will be off by 1.
+ percentage_pixels_error = 0.112f;
+ average_error_allowed_in_bad_pixels = 1.f;
+ large_error_allowed = 1;
+#endif
}
- pixel_comparator_.reset(new FuzzyPixelComparator(
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
false, // discard_alpha
percentage_pixels_error, percentage_pixels_small_error,
average_error_allowed_in_bad_pixels, large_error_allowed,
- small_error_allowed));
+ small_error_allowed);
}
static scoped_refptr<Layer> CreateCheckerboardLayer(const gfx::Size& bounds) {
@@ -714,6 +722,59 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) {
"mask_as_blending_rotated_circle_underflow.png")));
}
+TEST_P(LayerTreeHostMasksForBackgroundFiltersPixelTest,
+ MaskOfLayerWithBackgroundFilterAndBlend) {
+ scoped_refptr<SolidColorLayer> background =
+ CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE);
+
+ gfx::Size picture_bounds(128, 128);
+ CheckerContentLayerClient picture_client_vertical(picture_bounds,
+ SK_ColorGREEN, true);
+ scoped_refptr<PictureLayer> picture_vertical =
+ PictureLayer::Create(&picture_client_vertical);
+ picture_vertical->SetBounds(picture_bounds);
+ picture_vertical->SetIsDrawable(true);
+
+ CheckerContentLayerClient picture_client_horizontal(picture_bounds,
+ SK_ColorMAGENTA, false);
+ scoped_refptr<PictureLayer> picture_horizontal =
+ PictureLayer::Create(&picture_client_horizontal);
+ picture_horizontal->SetBounds(picture_bounds);
+ picture_horizontal->SetIsDrawable(true);
+ picture_horizontal->SetContentsOpaque(false);
+ picture_horizontal->SetBlendMode(SkBlendMode::kMultiply);
+
+ FilterOperations filters;
+ filters.Append(FilterOperation::CreateGrayscaleFilter(1.0));
+ picture_horizontal->SetBackgroundFilters(filters);
+
+ background->AddChild(picture_vertical);
+ background->AddChild(picture_horizontal);
+
+ gfx::Size mask_bounds(128, 128);
+ CircleContentLayerClient mask_client(mask_bounds);
+ scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client);
+ mask->SetBounds(mask_bounds);
+ mask->SetIsDrawable(true);
+ mask->SetLayerMaskType(mask_type_);
+ picture_horizontal->SetMaskLayer(mask.get());
+
+ float percentage_pixels_large_error = 0.062f; // 0.062%, ~10px / (128*128)
+ float percentage_pixels_small_error = 0.0f;
+ float average_error_allowed_in_bad_pixels = 200.0f;
+ int large_error_allowed = 256;
+ int small_error_allowed = 0;
+ pixel_comparator_ = std::make_unique<FuzzyPixelComparator>(
+ true, // discard_alpha
+ percentage_pixels_large_error, percentage_pixels_small_error,
+ average_error_allowed_in_bad_pixels, large_error_allowed,
+ small_error_allowed);
+
+ RunPixelResourceTest(background,
+ base::FilePath(FILE_PATH_LITERAL(
+ "mask_of_background_filter_and_blend.png")));
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index a4f98ae353a..b251df562ab 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -150,7 +150,7 @@ TEST_F(LayerTreeHostScrollbarsPixelTest, HugeTransformScale) {
background->AddChild(layer);
scoped_refptr<TestInProcessContextProvider> context(
- new TestInProcessContextProvider(nullptr, false));
+ new TestInProcessContextProvider(/*enable_oop_rasterization=*/false));
context->BindToCurrentThread();
int max_texture_size = 0;
context->ContextGL()->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index bf42914b95d..eabe1909a4f 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -60,13 +60,13 @@ class LayerTreeHostTilesPixelTest : public LayerTreePixelTest {
case PARTIAL_GPU_LOW_BIT_DEPTH:
settings->gpu_rasterization_forced = true;
settings->use_partial_raster = true;
- settings->preferred_tile_format = viz::RGBA_4444;
+ settings->use_rgba_4444 = true;
settings->unpremultiply_and_dither_low_bit_depth_tiles = true;
break;
case FULL_GPU_LOW_BIT_DEPTH:
settings->gpu_rasterization_forced = true;
settings->use_partial_raster = false;
- settings->preferred_tile_format = viz::RGBA_4444;
+ settings->use_rgba_4444 = true;
settings->unpremultiply_and_dither_low_bit_depth_tiles = true;
break;
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index acbd577abcd..e66bf23fa85 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -65,6 +65,7 @@
#include "components/viz/service/display/output_surface.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_output_surface.h"
+#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -460,14 +461,14 @@ class LayerTreeHostContextCacheTest : public LayerTreeHostTest {
// Create the main viz::ContextProvider with a MockContextSupport.
auto main_support = std::make_unique<MockContextSupport>();
mock_main_context_support_ = main_support.get();
- auto test_main_context_provider = viz::TestContextProvider::Create(
- viz::TestWebGraphicsContext3D::Create(), std::move(main_support));
+ auto test_main_context_provider =
+ viz::TestContextProvider::Create(std::move(main_support));
// Create the main viz::ContextProvider with a MockContextSupport.
auto worker_support = std::make_unique<MockContextSupport>();
mock_worker_context_support_ = worker_support.get();
- auto test_worker_context_provider = viz::TestContextProvider::CreateWorker(
- viz::TestWebGraphicsContext3D::Create(), std::move(worker_support));
+ auto test_worker_context_provider =
+ viz::TestContextProvider::CreateWorker(std::move(worker_support));
// At init, visibility is set to true, so SetAggressivelyFreeResources will
// be disabled.
@@ -563,7 +564,8 @@ class LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimitSynchronous
}
};
-SINGLE_AND_MULTI_THREAD_TEST_F(
+// Android Webview only runs in multi-threaded compositing mode.
+MULTI_THREAD_TEST_F(
LayerTreeHostFreesWorkerContextResourcesOnZeroMemoryLimitSynchronous);
// Test if the LTH successfully frees main and worker resources when the
@@ -1231,9 +1233,12 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
}
}
+ void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ PostSetNeedsCommitToMainThread();
+ }
+
void DidInvalidateLayerTreeFrameSink(LayerTreeHostImpl* impl) override {
int frame_number = impl->active_tree()->source_frame_number();
-
// Frames 0 and 1 invalidate because the early damage check is not enabled
// during this setup. But frames 1 and 2 are not damaged, so the early
// check should prevent frame 2 from invalidating.
@@ -1250,8 +1255,6 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
EndTest();
return;
}
-
- PostSetNeedsCommitToMainThread();
}
void AfterTest() override {
@@ -1269,9 +1272,7 @@ class LayerTreeHostTestEarlyDamageCheckStops : public LayerTreeHostTest {
// This behavior is specific to Android WebView, which only uses
// multi-threaded compositor.
-// Flaky on Win7 Tests (dbg)(1). https://crbug.com/813578
-// Flaky on linux_chromium_tsan_rel_ng. https://crbug.com/822473
-// MULTI_THREAD_TEST_F(LayerTreeHostTestEarlyDamageCheckStops);
+MULTI_THREAD_TEST_F(LayerTreeHostTestEarlyDamageCheckStops);
// Verify CanDraw() is false until first commit.
class LayerTreeHostTestCantDrawBeforeCommit : public LayerTreeHostTest {
@@ -2241,7 +2242,7 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate
// a second commit as a result.
layer_tree_host()->SetViewportSizeAndScale(
layer_tree_host()->device_viewport_size(), 4.f,
- layer_tree_host()->local_surface_id());
+ layer_tree_host()->local_surface_id_from_parent());
break;
default:
// No extra commits.
@@ -2286,7 +2287,7 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest {
if (layer_tree_host()->SourceFrameNumber() == 1) {
layer_tree_host()->SetViewportSizeAndScale(
layer_tree_host()->device_viewport_size(), 4.f,
- layer_tree_host()->local_surface_id());
+ layer_tree_host()->local_surface_id_from_parent());
}
}
@@ -3811,7 +3812,6 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
OnDrawLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> compositor_context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider,
- viz::SharedBitmapManager* shared_bitmap_manager,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const viz::RendererSettings& renderer_settings,
base::SingleThreadTaskRunner* task_runner,
@@ -3820,7 +3820,6 @@ class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
base::Closure invalidate_callback)
: TestLayerTreeFrameSink(std::move(compositor_context_provider),
std::move(worker_context_provider),
- shared_bitmap_manager,
gpu_memory_buffer_manager,
renderer_settings,
task_runner,
@@ -3862,8 +3861,8 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor
base::Unretained(this));
auto frame_sink = std::make_unique<OnDrawLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), false /* synchronous_composite */, refresh_rate,
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ false /* synchronous_composite */, refresh_rate,
std::move(on_draw_callback));
layer_tree_frame_sink_ = frame_sink.get();
return std::move(frame_sink);
@@ -5710,19 +5709,22 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
void SetVisibleFalseAndQueueSwapPromise() {
layer_tree_host()->SetVisible(false);
- std::unique_ptr<SwapPromise> swap_promise(
- new TestSwapPromise(&swap_promise_result_));
+ auto swap_promise =
+ std::make_unique<TestSwapPromise>(&swap_promise_result_);
layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
std::move(swap_promise));
}
void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl,
const viz::BeginFrameArgs& args) override {
- MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&LayerTreeHostTestBreakSwapPromiseForVisibility::
- SetVisibleFalseAndQueueSwapPromise,
- base::Unretained(this)));
+ if (!sent_queue_request_) {
+ sent_queue_request_ = true;
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestBreakSwapPromiseForVisibility::
+ SetVisibleFalseAndQueueSwapPromise,
+ base::Unretained(this)));
+ }
}
void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
@@ -5742,11 +5744,10 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility
}
TestSwapPromiseResult swap_promise_result_;
+ bool sent_queue_request_ = false;
};
-// Flaky: https://crbug.com/657910
-// SINGLE_AND_MULTI_THREAD_TEST_F(
-// LayerTreeHostTestBreakSwapPromiseForVisibility);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility);
class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
public:
@@ -5895,41 +5896,43 @@ class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
LayerTreeHostTest::SetupTree();
ui_resource_ =
FakeScopedUIResource::Create(layer_tree_host()->GetUIResourceManager());
- client_.set_bounds(layer_tree_host()->root_layer()->bounds());
}
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ if (TestEnded())
+ return;
+
host_impl->EvictAllUIResources();
// Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY
// mode. Active tree should require high-res to draw after entering this
// mode to ensure that high-res tiles are also required for a pending tree
// to be activated.
EXPECT_TRUE(host_impl->RequiresHighResToDraw());
+
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &LayerTreeHostTestHighResRequiredAfterEvictingUIResources::
+ DeleteResourceAndEndTest,
+ base::Unretained(this)));
}
- void DidCommit() override {
- int frame = layer_tree_host()->SourceFrameNumber();
- switch (frame) {
- case 1:
- PostSetNeedsCommitToMainThread();
- break;
- case 2:
- ui_resource_ = nullptr;
- EndTest();
- break;
- }
+ void DeleteResourceAndEndTest() {
+ // This must be destroyed before the test ends and tears down the
+ // LayerTreeHost. It causes another commit+activation though, which
+ // may run before the test exits.
+ ui_resource_ = nullptr;
+ EndTest();
}
void AfterTest() override {}
- FakeContentLayerClient client_;
std::unique_ptr<FakeScopedUIResource> ui_resource_;
};
-// This test is flaky, see http://crbug.com/386199
-// MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources)
+MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);
class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
protected:
@@ -6323,10 +6326,6 @@ class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
: will_begin_impl_frame_count_(0), did_finish_impl_frame_count_(0) {}
void BeginTest() override {
- // Test terminates when a main frame is no longer expected so request that
- // this message is actually sent.
- layer_tree_host()->RequestBeginMainFrameNotExpected(true);
-
PostSetNeedsCommitToMainThread();
}
@@ -6341,27 +6340,20 @@ class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame
did_finish_impl_frame_count_++;
EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
- // Request a number of commits to cause multiple impl frames. We expect to
- // get one more impl frames than the number of commits requested because
- // after a commit it takes one frame to become idle.
- if (did_finish_impl_frame_count_ < kExpectedNumImplFrames - 1)
- PostSetNeedsCommitToMainThread();
+ // Trigger a new impl frame until we are done testing.
+ if (did_finish_impl_frame_count_ < kExpectedNumImplFrames)
+ PostSetNeedsRedrawToMainThread();
+ else
+ EndTest();
}
- void BeginMainFrameNotExpectedSoon() override { EndTest(); }
-
void AfterTest() override {
EXPECT_GT(will_begin_impl_frame_count_, 0);
EXPECT_GT(did_finish_impl_frame_count_, 0);
EXPECT_EQ(will_begin_impl_frame_count_, did_finish_impl_frame_count_);
- // TODO(mithro): Figure out why the multithread version of this test
- // sometimes has one more frame then expected. Possibly related to
- // http://crbug.com/443185
- if (!HasImplThread()) {
- EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
- EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
- }
+ EXPECT_EQ(will_begin_impl_frame_count_, kExpectedNumImplFrames);
+ EXPECT_EQ(did_finish_impl_frame_count_, kExpectedNumImplFrames);
}
private:
@@ -6593,9 +6585,8 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
!layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
return std::make_unique<viz::TestLayerTreeFrameSink>(
compositor_context_provider, std::move(worker_context_provider),
- shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
- ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
- refresh_rate);
+ gpu_memory_buffer_manager(), renderer_settings, ImplThreadTaskRunner(),
+ synchronous_composite, disable_display_vsync, refresh_rate);
}
void BeginTest() override {
@@ -7400,478 +7391,6 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests);
-class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
- : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // The masked layer has bounds 50x50, but it has a child that causes
- // the surface bounds to be larger. It also has a parent that clips the
- // masked layer and its surface.
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::Size layer_size(100, 100);
- content_layer->SetBounds(layer_size);
-
- gfx::Size mask_size(100, 100);
- mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
- mask_layer_id_ = mask_layer->id();
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
- outer_viewport_scroll_layer->SetBounds(layer_size);
- CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer,
- gfx::Size(50, 50), gfx::Size(50, 50),
- layer_tree_host());
- layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true);
- outer_viewport_scroll_layer->AddChild(content_layer);
-
- client_.set_bounds(root->bounds());
- outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(50.f / texture_size.width(), 50.f / texture_size.height(),
- 50.f / texture_size.width(), 50.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- EndTest();
- return draw_result;
- }
-
- void AfterTest() override {}
-
- int mask_layer_id_;
- FakeContentLayerClient client_;
-};
-
-class LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin
- : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestSingleTextureMaskLayerForSurfaceWithContentRectNotAtOrigin);
-
-class LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin
- : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMultiTextureMaskLayerForSurfaceWithContentRectNotAtOrigin);
-
-class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // The masked layer has bounds 50x50, but it has a child that causes
- // the surface bounds to be larger. It also has a parent that clips the
- // masked layer and its surface.
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<Layer> clipping_layer = Layer::Create();
- root->AddChild(clipping_layer);
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
- clipping_layer->AddChild(content_layer);
-
- scoped_refptr<FakePictureLayer> content_child_layer =
- FakePictureLayer::Create(&client_);
- content_layer->AddChild(content_child_layer);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::PointF clipping_origin(20.f, 10.f);
- gfx::Size clipping_size(10, 20);
- clipping_layer->SetBounds(clipping_size);
- clipping_layer->SetPosition(clipping_origin);
- clipping_layer->SetMasksToBounds(true);
-
- gfx::Size layer_size(50, 50);
- content_layer->SetBounds(layer_size);
- content_layer->SetPosition(gfx::PointF() -
- clipping_origin.OffsetFromOrigin());
-
- gfx::Size child_size(50, 50);
- content_child_layer->SetBounds(child_size);
- content_child_layer->SetPosition(gfx::PointF(20.f, 0.f));
-
- gfx::Size mask_size(50, 50);
- mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
- mask_layer_id_ = mask_layer->id();
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- client_.set_bounds(root->bounds());
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- // The surface is clipped to 10x20.
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
- render_pass_quad->rect.ToString());
- // The masked layer is 50x50, but the surface size is 10x20. So the texture
- // coords in the mask are scaled by 10/50 and 20/50.
- // The surface is clipped to (20,10) so the mask texture coords are offset
- // by 20/50 and 10/50
- if (host_impl->settings().enable_mask_tiling) {
- PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
- host_impl->active_tree()->LayerById(mask_layer_id_));
- gfx::SizeF texture_size(
- mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
- EXPECT_EQ(
- gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
- 10.f / texture_size.width(), 20.f / texture_size.height())
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
- .ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- EndTest();
- return draw_result;
- }
-
- void AfterTest() override {}
-
- int mask_layer_id_;
- FakeContentLayerClient client_;
-};
-
-class LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer
- : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestSingleTextureMaskLayerForSurfaceWithClippedLayer);
-
-class LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer
- : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeTestMultiTextureMaskLayerForSurfaceWithClippedLayer);
-
-class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // Root
- // |
- // +-- Scaling Layer (adds a 2x scale)
- // |
- // +-- Content Layer
- // +--Mask
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<Layer> scaling_layer = Layer::Create();
- root->AddChild(scaling_layer);
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
- scaling_layer->AddChild(content_layer);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 10), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 10, 100, 90), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::Size scaling_layer_size(50, 50);
- scaling_layer->SetBounds(scaling_layer_size);
- gfx::Transform scale;
- scale.Scale(2.f, 2.f);
- scaling_layer->SetTransform(scale);
-
- content_layer->SetBounds(scaling_layer_size);
-
- mask_layer->SetBounds(scaling_layer_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- client_.set_bounds(root->bounds());
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- switch (host_impl->active_tree()->source_frame_number()) {
- case 0:
- // Check that the tree scaling is correctly taken into account for the
- // mask, that should fully map onto the quad.
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- EXPECT_EQ(
- gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- break;
- case 1:
- // Applying a DSF should change the render surface size, but won't
- // affect which part of the mask is used.
- EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
- render_pass_quad->rect.ToString());
- if (host_impl->settings().enable_mask_tiling) {
- EXPECT_EQ(
- gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- } else {
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- }
- EndTest();
- break;
- }
- return draw_result;
- }
-
- void DidCommit() override {
- switch (layer_tree_host()->SourceFrameNumber()) {
- case 1:
- gfx::Size double_root_size(200, 200);
- layer_tree_host()->SetViewportSizeAndScale(double_root_size, 2.f,
- viz::LocalSurfaceId());
- break;
- }
- }
-
- void AfterTest() override {}
-
- FakeContentLayerClient client_;
-};
-
-class LayerTreeTestSingleTextureMaskLayerWithScaling
- : public LayerTreeTestMaskLayerWithScaling {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = false;
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestSingleTextureMaskLayerWithScaling);
-
-class LayerTreeTestMultiTextureMaskLayerWithScaling
- : public LayerTreeTestMaskLayerWithScaling {
- public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->enable_mask_tiling = true;
- settings->layer_transforms_should_scale_layer_contents = true;
- }
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMultiTextureMaskLayerWithScaling);
-
-class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
- protected:
- void SetupTree() override {
- // The masked layer has bounds 100x100, but is allocated a 120x150 texture.
-
- scoped_refptr<Layer> root = Layer::Create();
-
- scoped_refptr<FakePictureLayer> content_layer =
- FakePictureLayer::Create(&client_);
- root->AddChild(content_layer);
-
- std::unique_ptr<RecordingSource> recording_source =
- FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
- PaintFlags paint1, paint2;
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
- static_cast<FakeRecordingSource*>(recording_source.get())
- ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
- client_.set_fill_with_nonsolid_color(true);
- static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
-
- scoped_refptr<FakePictureLayer> mask_layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client_, std::move(recording_source));
- content_layer->SetMaskLayer(mask_layer.get());
-
- gfx::Size root_size(100, 100);
- root->SetBounds(root_size);
-
- gfx::Size layer_size(100, 100);
- content_layer->SetBounds(layer_size);
-
- gfx::Size mask_size(100, 100);
- gfx::Size mask_texture_size(120, 150);
- mask_layer->SetBounds(mask_size);
- mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
- mask_layer->set_fixed_tile_size(mask_texture_size);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- client_.set_bounds(root->bounds());
- }
-
- void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
- DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawResult draw_result) override {
- EXPECT_EQ(2u, frame_data->render_passes.size());
- viz::RenderPass* root_pass = frame_data->render_passes.back().get();
- EXPECT_EQ(2u, root_pass->quad_list.size());
-
- // There's a solid color quad under everything.
- EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
- root_pass->quad_list.back()->material);
-
- // The surface is 100x100
- EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
- root_pass->quad_list.front()->material);
- const viz::RenderPassDrawQuad* render_pass_quad =
- viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
- EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
- render_pass_quad->rect.ToString());
- // The mask layer is 100x100, but is backed by a 120x150 image.
- EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(),
- render_pass_quad->mask_uv_rect.ToString());
- EndTest();
- return draw_result;
- }
-
- void AfterTest() override {}
-
- int mask_layer_id_;
- FakeContentLayerClient client_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize);
-
class LayerTreeTestPageScaleFlags : public LayerTreeTest {
protected:
void SetupTree() override {
@@ -7993,6 +7512,25 @@ class LayerTreeHostTestPaintedDeviceScaleFactor : public LayerTreeHostTest {
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor);
+// Makes sure that presentation-time requests are correctly propagated to the
+// frame's metadata.
+class LayerTreeHostTestPresentationTimeRequest : public LayerTreeHostTest {
+ protected:
+ void BeginTest() override {
+ layer_tree_host()->RequestPresentationTimeForNextFrame(base::DoNothing());
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void DisplayReceivedCompositorFrameOnThread(
+ const viz::CompositorFrame& frame) override {
+ EXPECT_NE(0u, frame.metadata.presentation_token);
+ EndTest();
+ }
+
+ void AfterTest() override {}
+};
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTimeRequest);
+
// Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink.
class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
protected:
@@ -8001,7 +7539,7 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
}
void BeginTest() override {
- expected_local_surface_id_ = allocator_.GenerateId();
+ expected_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
PostSetLocalSurfaceIdToMainThread(expected_local_surface_id_);
}
@@ -8010,7 +7548,7 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
DrawResult draw_result) override {
EXPECT_EQ(DRAW_SUCCESS, draw_result);
EXPECT_EQ(expected_local_surface_id_,
- host_impl->active_tree()->local_surface_id());
+ host_impl->active_tree()->local_surface_id_from_parent());
return draw_result;
}
@@ -8025,9 +7563,56 @@ class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
viz::LocalSurfaceId expected_local_surface_id_;
viz::ParentLocalSurfaceIdAllocator allocator_;
};
-
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLocalSurfaceId);
+// Makes sure that viz::LocalSurfaceId allocation requests propagate all the way
+// to LayerTreeFrameSink.
+class LayerTreeHostTestRequestNewLocalSurfaceId : public LayerTreeHostTest {
+ protected:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_surface_synchronization = true;
+ }
+
+ void BeginTest() override {
+ expected_parent_local_surface_id_ = allocator_.GetCurrentLocalSurfaceId();
+ PostSetLocalSurfaceIdToMainThread(expected_parent_local_surface_id_);
+ PostRequestNewLocalSurfaceIdToMainThread();
+ }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(DRAW_SUCCESS, draw_result);
+ EXPECT_EQ(expected_parent_local_surface_id_,
+ host_impl->active_tree()->local_surface_id_from_parent());
+ return draw_result;
+ }
+
+ void DisplayReceivedLocalSurfaceIdOnThread(
+ const viz::LocalSurfaceId& local_surface_id) override {
+ viz::LocalSurfaceId child_local_surface_id(
+ expected_parent_local_surface_id_.parent_sequence_number(),
+ expected_parent_local_surface_id_.child_sequence_number() + 1,
+ expected_parent_local_surface_id_.embed_token());
+ EXPECT_NE(expected_parent_local_surface_id_, local_surface_id);
+ EXPECT_EQ(child_local_surface_id, local_surface_id);
+ }
+
+ // This gets called after DispllayReceivedLocalSurfaceIdOnThread.
+ void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
+ // Verify that the request bit doesn't stick after we submit a frame.
+ EXPECT_FALSE(
+ host_impl->active_tree()->new_local_surface_id_request_for_testing());
+ EndTest();
+ }
+
+ void AfterTest() override {}
+
+ viz::LocalSurfaceId expected_parent_local_surface_id_;
+ viz::ParentLocalSurfaceIdAllocator allocator_;
+};
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestNewLocalSurfaceId);
+
// The GPU image decode controller hands images off to Skia for rasterization.
// When used with large images, the images in question could be deleted before
// Skia was done with them, causing a crash. This test performs an end-to-end
@@ -8144,6 +7729,20 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameMetadata);
class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
protected:
+ std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+ const viz::RendererSettings& renderer_settings,
+ double refresh_rate,
+ scoped_refptr<viz::ContextProvider> compositor_context_provider,
+ scoped_refptr<viz::RasterContextProvider> worker_context_provider)
+ override {
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
+ gl_owned->set_have_extension_egl_image(true);
+ auto provider = viz::TestContextProvider::Create(std::move(gl_owned));
+ return LayerTreeTest::CreateLayerTreeFrameSink(
+ renderer_settings, refresh_rate, std::move(provider),
+ std::move(worker_context_provider));
+ }
+
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
@@ -8154,15 +7753,12 @@ class LayerTreeHostTestSubmitFrameResources : public LayerTreeHostTest {
viz::RenderPass* child_pass =
AddRenderPass(&frame->render_passes, 2, gfx::Rect(3, 3, 10, 10),
gfx::Transform(), FilterOperations());
- gpu::SyncToken mailbox_sync_token;
- AddOneOfEveryQuadType(child_pass, host_impl->resource_provider(), 0,
- &mailbox_sync_token);
+ AddOneOfEveryQuadType(child_pass, host_impl->resource_provider(), 0);
viz::RenderPass* pass =
AddRenderPass(&frame->render_passes, 1, gfx::Rect(3, 3, 10, 10),
gfx::Transform(), FilterOperations());
- AddOneOfEveryQuadType(pass, host_impl->resource_provider(), child_pass->id,
- &mailbox_sync_token);
+ AddOneOfEveryQuadType(pass, host_impl->resource_provider(), child_pass->id);
return draw_result;
}
@@ -8293,11 +7889,9 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
void ReadyToCommitOnThread(LayerTreeHostImpl* impl) override {
if (one_commit_done_)
return;
- EXPECT_TRUE(
+ EXPECT_FALSE(
impl->tile_manager()->checker_image_tracker().ShouldCheckerImage(
image_, WhichTree::PENDING_TREE));
- // Reset the tracker as if it has never seen this image.
- impl->tile_manager()->checker_image_tracker().ClearTracker(true);
}
void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index f71c658c3fa..929c6658fe8 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -60,6 +60,9 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest {
content_layer_client_.set_fill_with_nonsolid_color(true);
PaintImage checkerable_image =
CreateDiscardablePaintImage(gfx::Size(450, 450));
+ checkerable_image = PaintImageBuilder::WithCopy(checkerable_image)
+ .set_decoding_mode(PaintImage::DecodingMode::kAsync)
+ .TakePaintImage();
content_layer_client_.add_draw_image(checkerable_image, gfx::Point(0, 0),
PaintFlags());
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index 024ca0204ab..f3ec645e85a 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -34,6 +34,7 @@
#include "cc/trees/single_thread_proxy.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "components/viz/test/test_context_provider.h"
+#include "components/viz/test/test_gles2_interface.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "components/viz/test/test_shared_bitmap_manager.h"
#include "components/viz/test/test_web_graphics_context_3d.h"
@@ -56,7 +57,6 @@ class LayerTreeHostContextTest : public LayerTreeTest {
public:
LayerTreeHostContextTest()
: LayerTreeTest(),
- context3d_(nullptr),
times_to_fail_create_(0),
times_to_lose_during_commit_(0),
times_to_lose_during_draw_(0),
@@ -72,15 +72,15 @@ class LayerTreeHostContextTest : public LayerTreeTest {
void LoseContext() {
// CreateDisplayLayerTreeFrameSink happens on a different thread, so lock
- // context3d_ to make sure we don't set it to null after recreating it
+ // gl_ to make sure we don't set it to null after recreating it
// there.
- base::AutoLock lock(context3d_lock_);
+ base::AutoLock lock(gl_lock_);
// For sanity-checking tests, they should only call this when the
// context is not lost.
- CHECK(context3d_);
- context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
- GL_INNOCENT_CONTEXT_RESET_ARB);
- context3d_ = nullptr;
+ CHECK(gl_);
+ gl_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB);
+ gl_ = nullptr;
}
std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
@@ -89,26 +89,26 @@ class LayerTreeHostContextTest : public LayerTreeTest {
scoped_refptr<viz::ContextProvider> compositor_context_provider,
scoped_refptr<viz::RasterContextProvider> worker_context_provider)
override {
- base::AutoLock lock(context3d_lock_);
+ base::AutoLock lock(gl_lock_);
- std::unique_ptr<viz::TestWebGraphicsContext3D> compositor_context3d =
- viz::TestWebGraphicsContext3D::Create();
+ auto gl_owned = std::make_unique<viz::TestGLES2Interface>();
if (context_should_support_io_surface_) {
- compositor_context3d->set_have_extension_io_surface(true);
- compositor_context3d->set_have_extension_egl_image(true);
+ gl_owned->set_have_extension_io_surface(true);
+ gl_owned->set_have_extension_egl_image(true);
}
- context3d_ = compositor_context3d.get();
+ gl_ = gl_owned.get();
+
+ auto provider = viz::TestContextProvider::Create(std::move(gl_owned));
if (times_to_fail_create_) {
--times_to_fail_create_;
ExpectCreateToFail();
- context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
- GL_INNOCENT_CONTEXT_RESET_ARB);
+ gl_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
+ GL_INNOCENT_CONTEXT_RESET_ARB);
}
return LayerTreeTest::CreateLayerTreeFrameSink(
- renderer_settings, refresh_rate,
- viz::TestContextProvider::Create(std::move(compositor_context3d)),
+ renderer_settings, refresh_rate, std::move(provider),
std::move(worker_context_provider));
}
@@ -158,10 +158,10 @@ class LayerTreeHostContextTest : public LayerTreeTest {
void ExpectCreateToFail() { ++times_to_expect_create_failed_; }
protected:
- // Protects use of context3d_ so LoseContext and
+ // Protects use of gl_ so LoseContext and
// CreateDisplayLayerTreeFrameSink can both use it on different threads.
- base::Lock context3d_lock_;
- viz::TestWebGraphicsContext3D* context3d_;
+ base::Lock gl_lock_;
+ viz::TestGLES2Interface* gl_ = nullptr;
int times_to_fail_create_;
int times_to_lose_during_commit_;
@@ -887,7 +887,7 @@ class LayerTreeHostContextTestDontUseLostResources
shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>();
child_resource_provider_ =
FakeResourceProvider::CreateLayerTreeResourceProvider(
- child_context_provider_.get(), shared_bitmap_manager_.get());
+ child_context_provider_.get());
}
static void EmptyReleaseCallback(const gpu::SyncToken& sync_token,
@@ -1008,7 +1008,7 @@ class LayerTreeHostContextTestDontUseLostResources
if (host_impl->active_tree()->source_frame_number() == 2) {
// Lose the context after draw on the second commit. This will cause
// a third commit to recover.
- context3d_->set_times_bind_texture_succeeds(0);
+ gl_->set_times_bind_texture_succeeds(0);
}
return draw_result;
}
@@ -1042,7 +1042,7 @@ class LayerTreeHostContextTestDontUseLostResources
scoped_refptr<viz::TestContextProvider> child_context_provider_;
std::unique_ptr<viz::SharedBitmapManager> shared_bitmap_manager_;
- std::unique_ptr<ResourceProvider> child_resource_provider_;
+ std::unique_ptr<LayerTreeResourceProvider> child_resource_provider_;
scoped_refptr<VideoFrame> color_video_frame_;
scoped_refptr<VideoFrame> hw_video_frame_;
@@ -1345,8 +1345,9 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple {
UIResourceId test_id1_;
};
-// http://crbug.com/803532 : Flaky on Win 7 (dbg).
-#if defined(NDEBUG) || !defined(OS_WIN)
+// http://crbug.com/803532 : Flaky on Win 7 (dbg) and linux tsan
+#if (defined(NDEBUG) || !defined(OS_WIN)) && \
+ (!defined(THREAD_SANITIZER) || !defined(OS_LINUX))
SINGLE_THREAD_TEST_F(UIResourceLostBeforeCommit);
#endif
MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit);
@@ -1479,7 +1480,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl, bool visible) override {
if (!visible) {
// All resources should have been evicted.
- ASSERT_EQ(0u, context3d_->NumTextures());
+ ASSERT_EQ(0u, gl_->NumTextures());
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource3_->id()));
@@ -1499,7 +1500,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
case 1:
// The first two resources should have been created on LTHI after the
// commit.
- ASSERT_EQ(2u, context3d_->NumTextures());
+ ASSERT_EQ(2u, gl_->NumTextures());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(1, ui_resource_->resource_create_count);
@@ -1507,7 +1508,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
EXPECT_TRUE(impl->CanDraw());
// Evict all UI resources. This will trigger a commit.
impl->EvictAllUIResources();
- ASSERT_EQ(0u, context3d_->NumTextures());
+ ASSERT_EQ(0u, gl_->NumTextures());
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(0u, impl->ResourceIdForUIResource(ui_resource2_->id()));
EXPECT_EQ(1, ui_resource_->resource_create_count);
@@ -1516,7 +1517,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
break;
case 2:
// The first two resources should have been recreated.
- ASSERT_EQ(2u, context3d_->NumTextures());
+ ASSERT_EQ(2u, gl_->NumTextures());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(2, ui_resource_->resource_create_count);
EXPECT_EQ(1, ui_resource_->lost_resource_count);
@@ -1528,7 +1529,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple {
case 3:
// The first resource should have been recreated after visibility was
// restored.
- ASSERT_EQ(2u, context3d_->NumTextures());
+ ASSERT_EQ(2u, gl_->NumTextures());
EXPECT_NE(0u, impl->ResourceIdForUIResource(ui_resource_->id()));
EXPECT_EQ(3, ui_resource_->resource_create_count);
EXPECT_EQ(2, ui_resource_->lost_resource_count);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index edc62a8e36a..fcc95241448 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -1049,63 +1049,6 @@ class LayerTreeHostCopyRequestTestCreatesTexture
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestCreatesTexture);
-class LayerTreeHostCopyRequestTestProvideTexture
- : public LayerTreeHostCopyRequestTestCountTextures {
- protected:
- void BeginTest() override {
- external_context_provider_ = viz::TestContextProvider::Create();
- EXPECT_EQ(external_context_provider_->BindToCurrentThread(),
- gpu::ContextResult::kSuccess);
- LayerTreeHostCopyRequestTestCountTextures::BeginTest();
- }
-
- void CopyOutputCallback(std::unique_ptr<viz::CopyOutputResult> result) {
- EXPECT_FALSE(result->IsEmpty());
- EXPECT_EQ(result->format(), viz::CopyOutputResult::Format::RGBA_TEXTURE);
- ASSERT_NE(nullptr, result->GetTextureResult());
-
- std::unique_ptr<viz::SingleReleaseCallback> release_callback =
- result->TakeTextureOwnership();
- ASSERT_TRUE(release_callback);
- release_callback->Run(gpu::SyncToken(), false);
- }
-
- void RequestCopy(Layer* layer) override {
- // Request a copy to a provided texture. This should not create a new
- // texture.
- std::unique_ptr<viz::CopyOutputRequest> request =
- std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
- base::BindOnce(
- &LayerTreeHostCopyRequestTestProvideTexture::CopyOutputCallback,
- base::Unretained(this)));
-
- gpu::gles2::GLES2Interface* gl = external_context_provider_->ContextGL();
- gpu::Mailbox mailbox;
- gl->GenMailboxCHROMIUM(mailbox.name);
-
- gl->GenSyncTokenCHROMIUM(sync_token_.GetData());
-
- request->SetMailbox(mailbox, sync_token_);
- EXPECT_TRUE(request->has_mailbox());
-
- copy_layer_->RequestCopyOfOutput(std::move(request));
- }
-
- void AfterTest() override {
- // Expect the compositor to have waited for the sync point provided with the
- // mailbox.
- EXPECT_EQ(sync_token_, waited_sync_token_after_readback_);
- // Except the copy to have *not* made another texture.
- EXPECT_EQ(num_textures_without_readback_, num_textures_with_readback_);
- }
-
- scoped_refptr<viz::TestContextProvider> external_context_provider_;
- gpu::SyncToken sync_token_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestProvideTexture);
-
class LayerTreeHostCopyRequestTestDestroyBeforeCopy
: public LayerTreeHostCopyRequestTest {
protected:
diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
new file mode 100644
index 00000000000..b1615f0eb7e
--- /dev/null
+++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc
@@ -0,0 +1,666 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/layer_tree_host.h"
+
+#include "cc/test/fake_picture_layer.h"
+#include "cc/test/fake_recording_source.h"
+#include "cc/test/layer_tree_test.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "components/viz/common/quads/render_pass_draw_quad.h"
+
+namespace cc {
+namespace {
+
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin
+ : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size layer_size(100, 100);
+ content_layer->SetBounds(layer_size);
+
+ gfx::Size mask_size(100, 100);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
+ outer_viewport_scroll_layer->SetBounds(layer_size);
+ CreateVirtualViewportLayers(root.get(), outer_viewport_scroll_layer,
+ gfx::Size(50, 50), gfx::Size(50, 50),
+ layer_tree_host());
+ layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true);
+ outer_viewport_scroll_layer->AddChild(content_layer);
+
+ client_.set_bounds(root->bounds());
+ outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
+ EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
+ rect_in_target_space.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(50.f / texture_size.width(), 50.f / texture_size.height(),
+ 50.f / texture_size.width(), 50.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Untiled
+ : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Untiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Tiled
+ : public LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin_Tiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<Layer> clipping_layer = Layer::Create();
+ root->AddChild(clipping_layer);
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ clipping_layer->AddChild(content_layer);
+
+ scoped_refptr<FakePictureLayer> content_child_layer =
+ FakePictureLayer::Create(&client_);
+ content_layer->AddChild(content_child_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::PointF clipping_origin(20.f, 10.f);
+ gfx::Size clipping_size(10, 20);
+ clipping_layer->SetBounds(clipping_size);
+ clipping_layer->SetPosition(clipping_origin);
+ clipping_layer->SetMasksToBounds(true);
+
+ gfx::Size layer_size(50, 50);
+ content_layer->SetBounds(layer_size);
+ content_layer->SetPosition(gfx::PointF() -
+ clipping_origin.OffsetFromOrigin());
+
+ gfx::Size child_size(50, 50);
+ content_child_layer->SetBounds(child_size);
+ content_child_layer->SetPosition(gfx::PointF(20.f, 0.f));
+
+ gfx::Size mask_size(50, 50);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ // The surface is clipped to 10x20.
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
+ EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
+ rect_in_target_space.ToString());
+ // The masked layer is 50x50, but the surface size is 10x20. So the texture
+ // coords in the mask are scaled by 10/50 and 20/50.
+ // The surface is clipped to (20,10) so the mask texture coords are offset
+ // by 20/50 and 10/50
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
+ 10.f / texture_size.width(), 20.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Untiled
+ : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Untiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Tiled
+ : public LayerTreeTestMaskLayerForSurfaceWithClippedLayer {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithClippedLayer_Tiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithDifferentScale
+ : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 50x50, but it has a child that causes
+ // the surface bounds to be larger. It also has a parent that clips the
+ // masked layer and its surface.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<Layer> clipping_scaling_layer = Layer::Create();
+ root->AddChild(clipping_scaling_layer);
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ clipping_scaling_layer->AddChild(content_layer);
+
+ scoped_refptr<FakePictureLayer> content_child_layer =
+ FakePictureLayer::Create(&client_);
+ content_layer->AddChild(content_child_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(50, 50));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 50, 40), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 40, 50, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Transform scale;
+ scale.Scale(2, 2);
+ gfx::PointF clipping_origin(20.f, 10.f);
+ gfx::Size clipping_size(10, 20);
+ clipping_scaling_layer->SetBounds(clipping_size);
+ clipping_scaling_layer->SetPosition(clipping_origin);
+ // This changes scale between contributing layer and render surface to 2.
+ clipping_scaling_layer->SetTransform(scale);
+ clipping_scaling_layer->SetMasksToBounds(true);
+
+ gfx::Size layer_size(50, 50);
+ content_layer->SetBounds(layer_size);
+ content_layer->SetPosition(gfx::PointF() -
+ clipping_origin.OffsetFromOrigin());
+
+ gfx::Size child_size(50, 50);
+ content_child_layer->SetBounds(child_size);
+ content_child_layer->SetPosition(gfx::PointF(20.f, 0.f));
+
+ gfx::Size mask_size(50, 50);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+ // Setting will change transform on mask layer will make it not adjust
+ // raster scale, which will remain 1. This means the mask_layer and render
+ // surface will have a scale of 2 during draw time.
+ mask_layer->SetHasWillChangeTransformHint(true);
+ mask_layer_id_ = mask_layer->id();
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ // The surface is clipped to 10x20, and then scaled by 2, which ends up
+ // being 20x40.
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->rect);
+ EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(),
+ rect_in_target_space.ToString());
+ gfx::Rect visible_rect_in_target_space = MathUtil::MapEnclosingClippedRect(
+ render_pass_quad->shared_quad_state->quad_to_target_transform,
+ render_pass_quad->visible_rect);
+ EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(),
+ visible_rect_in_target_space.ToString());
+ // The masked layer is 50x50, but the surface size is 10x20. So the texture
+ // coords in the mask are scaled by 10/50 and 20/50.
+ // The surface is clipped to (20,10) so the mask texture coords are offset
+ // by 20/50 and 10/50
+ if (host_impl->settings().enable_mask_tiling) {
+ PictureLayerImpl* mask_layer_impl = static_cast<PictureLayerImpl*>(
+ host_impl->active_tree()->LayerById(mask_layer_id_));
+ gfx::SizeF texture_size(
+ mask_layer_impl->CalculateTileSize(mask_layer_impl->bounds()));
+ EXPECT_EQ(
+ gfx::RectF(20.f / texture_size.width(), 10.f / texture_size.height(),
+ 10.f / texture_size.width(), 20.f / texture_size.height())
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
+ .ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Untiled
+ : public LayerTreeTestMaskLayerForSurfaceWithDifferentScale {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Untiled);
+
+class LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Tiled
+ : public LayerTreeTestMaskLayerForSurfaceWithDifferentScale {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskLayerForSurfaceWithDifferentScale_Tiled);
+
+class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // Root
+ // |
+ // +-- Scaling Layer (adds a 2x scale)
+ // |
+ // +-- Content Layer
+ // +--Mask
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<Layer> scaling_layer = Layer::Create();
+ root->AddChild(scaling_layer);
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ scaling_layer->AddChild(content_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 10), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 10, 100, 90), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size scaling_layer_size(50, 50);
+ scaling_layer->SetBounds(scaling_layer_size);
+ gfx::Transform scale;
+ scale.Scale(2.f, 2.f);
+ scaling_layer->SetTransform(scale);
+
+ content_layer->SetBounds(scaling_layer_size);
+
+ mask_layer->SetBounds(scaling_layer_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ // Check that the tree scaling is correctly taken into account for the
+ // mask, that should fully map onto the quad.
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ render_pass_quad->rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(
+ gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ break;
+ case 1:
+ // Applying a DSF should change the render surface size, but won't
+ // affect which part of the mask is used.
+ EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
+ render_pass_quad->rect.ToString());
+ if (host_impl->settings().enable_mask_tiling) {
+ EXPECT_EQ(
+ gfx::RectF(0.f, 0.f, 100.f / 128.f, 100.f / 128.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ } else {
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ }
+ EndTest();
+ break;
+ }
+ return draw_result;
+ }
+
+ void DidCommit() override {
+ switch (layer_tree_host()->SourceFrameNumber()) {
+ case 1:
+ gfx::Size double_root_size(200, 200);
+ layer_tree_host()->SetViewportSizeAndScale(double_root_size, 2.f,
+ viz::LocalSurfaceId());
+ break;
+ }
+ }
+
+ void AfterTest() override {}
+
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskLayerWithScaling_Untiled
+ : public LayerTreeTestMaskLayerWithScaling {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ settings->layer_transforms_should_scale_layer_contents = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling_Untiled);
+
+class LayerTreeTestMaskLayerWithScaling_Tiled
+ : public LayerTreeTestMaskLayerWithScaling {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ settings->layer_transforms_should_scale_layer_contents = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithScaling_Tiled);
+
+class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest {
+ protected:
+ void SetupTree() override {
+ // The masked layer has bounds 100x100, but is allocated a 120x150 texture.
+
+ scoped_refptr<Layer> root = Layer::Create();
+
+ scoped_refptr<FakePictureLayer> content_layer =
+ FakePictureLayer::Create(&client_);
+ root->AddChild(content_layer);
+
+ std::unique_ptr<RecordingSource> recording_source =
+ FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100));
+ PaintFlags paint1, paint2;
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1);
+ static_cast<FakeRecordingSource*>(recording_source.get())
+ ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2);
+ client_.set_fill_with_nonsolid_color(true);
+ static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord();
+
+ scoped_refptr<FakePictureLayer> mask_layer =
+ FakePictureLayer::CreateWithRecordingSource(
+ &client_, std::move(recording_source));
+ content_layer->SetMaskLayer(mask_layer.get());
+
+ gfx::Size root_size(100, 100);
+ root->SetBounds(root_size);
+
+ gfx::Size layer_size(100, 100);
+ content_layer->SetBounds(layer_size);
+
+ gfx::Size mask_size(100, 100);
+ gfx::Size mask_texture_size(120, 150);
+ mask_layer->SetBounds(mask_size);
+ mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK);
+ mask_layer->set_fixed_tile_size(mask_texture_size);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ client_.set_bounds(root->bounds());
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawResult draw_result) override {
+ EXPECT_EQ(2u, frame_data->render_passes.size());
+ viz::RenderPass* root_pass = frame_data->render_passes.back().get();
+ EXPECT_EQ(2u, root_pass->quad_list.size());
+
+ // There's a solid color quad under everything.
+ EXPECT_EQ(viz::DrawQuad::SOLID_COLOR,
+ root_pass->quad_list.back()->material);
+
+ // The surface is 100x100
+ EXPECT_EQ(viz::DrawQuad::RENDER_PASS,
+ root_pass->quad_list.front()->material);
+ const viz::RenderPassDrawQuad* render_pass_quad =
+ viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front());
+ EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
+ render_pass_quad->rect.ToString());
+ // The mask layer is 100x100, but is backed by a 120x150 image.
+ EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(),
+ render_pass_quad->mask_uv_rect.ToString());
+ EndTest();
+ return draw_result;
+ }
+
+ void AfterTest() override {}
+
+ int mask_layer_id_;
+ FakeContentLayerClient client_;
+};
+
+class LayerTreeTestMaskWithNonExactTextureSize_Untiled
+ : public LayerTreeTestMaskWithNonExactTextureSize {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = false;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeTestMaskWithNonExactTextureSize_Untiled);
+
+class LayerTreeTestMaskWithNonExactTextureSize_Tiled
+ : public LayerTreeTestMaskWithNonExactTextureSize {
+ public:
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->enable_mask_tiling = true;
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskWithNonExactTextureSize_Tiled);
+
+} // namespace
+} // namespace cc
diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
index 40aeeb1acb3..205d1f2c648 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc
@@ -41,14 +41,16 @@ class LayerTreeHostPictureTestTwinLayer
}
void BeginTest() override {
- activates_ = 0;
+ // Commit and activate to produce a pending (recycled) layer and an active
+ // layer.
PostSetNeedsCommitToMainThread();
}
void DidCommit() override {
switch (layer_tree_host()->SourceFrameNumber()) {
case 1:
- // Activate while there are pending and active twins in place.
+ // Activate reusing an existing recycled pending layer, to an already
+ // existing active layer.
layer_tree_host()->SetNeedsCommit();
break;
case 2:
@@ -66,12 +68,9 @@ class LayerTreeHostPictureTestTwinLayer
break;
}
case 4:
- // Active while there are pending and active twins again.
+ // Activate while there are pending and active twins again.
layer_tree_host()->SetNeedsCommit();
break;
- case 5:
- EndTest();
- break;
}
}
@@ -131,11 +130,14 @@ class LayerTreeHostPictureTestTwinLayer
}
++activates_;
+ if (activates_ == 5)
+ EndTest();
}
- void AfterTest() override { EXPECT_EQ(5, activates_); }
+ void AfterTest() override {}
+
+ int activates_ = 0;
- int activates_;
int picture_id1_;
int picture_id2_;
};
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index 68982f6f0cf..dc45563a2c7 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1250,7 +1250,7 @@ class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent
layer_tree_host()
->inner_viewport_scroll_layer()
->AddMainThreadScrollingReasons(
- MainThreadScrollingReason::kNonFastScrollableRegion);
+ MainThreadScrollingReason::kScrollbarScrolling);
}
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
@@ -1268,7 +1268,7 @@ class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent
impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
scroll_tree, inner_scroll_node);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
- EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
+ EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
status.main_thread_scrolling_reasons);
status = impl->TryScroll(gfx::PointF(1.f, 1.f), InputHandler::TOUCHSCREEN,
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index fa670feff83..a6b06c59e26 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -468,8 +468,11 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
target_tree->elastic_overscroll()->PushPendingToActive();
target_tree->set_content_source_id(content_source_id());
+ target_tree->set_request_presentation_time(request_presentation_time());
- target_tree->set_local_surface_id(local_surface_id());
+ if (TakeNewLocalSurfaceIdRequest())
+ target_tree->RequestNewLocalSurfaceId();
+ target_tree->SetLocalSurfaceIdFromParent(local_surface_id_from_parent());
target_tree->pending_page_scale_animation_ =
std::move(pending_page_scale_animation_);
@@ -963,6 +966,21 @@ void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) {
host_impl_->SetNeedUpdateGpuRasterizationStatus();
}
+void LayerTreeImpl::SetLocalSurfaceIdFromParent(
+ const viz::LocalSurfaceId& local_surface_id_from_parent) {
+ local_surface_id_from_parent_ = local_surface_id_from_parent;
+}
+
+void LayerTreeImpl::RequestNewLocalSurfaceId() {
+ new_local_surface_id_request_ = true;
+}
+
+bool LayerTreeImpl::TakeNewLocalSurfaceIdRequest() {
+ bool new_local_surface_id_request = new_local_surface_id_request_;
+ new_local_surface_id_request_ = false;
+ return new_local_surface_id_request;
+}
+
void LayerTreeImpl::SetRasterColorSpace(
int raster_color_space_id,
const gfx::ColorSpace& raster_color_space) {
@@ -1085,7 +1103,7 @@ bool LayerTreeImpl::UpdateDrawProperties(
device_scale_factor(), current_page_scale_factor(), PageScaleLayer(),
InnerViewportScrollLayer(), OuterViewportScrollLayer(),
elastic_overscroll()->Current(IsActiveTree()),
- OverscrollElasticityLayer(), resource_provider()->max_texture_size(),
+ OverscrollElasticityLayer(), max_texture_size(),
settings().layer_transforms_should_scale_layer_contents,
&render_surface_list_, &property_trees_);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
@@ -1376,6 +1394,10 @@ LayerTreeFrameSink* LayerTreeImpl::layer_tree_frame_sink() {
return host_impl_->layer_tree_frame_sink();
}
+int LayerTreeImpl::max_texture_size() const {
+ return host_impl_->max_texture_size();
+}
+
const LayerTreeSettings& LayerTreeImpl::settings() const {
return host_impl_->settings();
}
@@ -1388,10 +1410,6 @@ viz::ContextProvider* LayerTreeImpl::context_provider() const {
return host_impl_->layer_tree_frame_sink()->context_provider();
}
-viz::SharedBitmapManager* LayerTreeImpl::shared_bitmap_manager() const {
- return host_impl_->layer_tree_frame_sink()->shared_bitmap_manager();
-}
-
LayerTreeResourceProvider* LayerTreeImpl::resource_provider() const {
return host_impl_->resource_provider();
}
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 62c31dbd0a1..11e406e78d4 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -106,10 +106,10 @@ class CC_EXPORT LayerTreeImpl {
// Methods called by the layer tree that pass-through or access LTHI.
// ---------------------------------------------------------------------------
LayerTreeFrameSink* layer_tree_frame_sink();
+ int max_texture_size() const;
const LayerTreeSettings& settings() const;
const LayerTreeDebugState& debug_state() const;
viz::ContextProvider* context_provider() const;
- viz::SharedBitmapManager* shared_bitmap_manager() const;
LayerTreeResourceProvider* resource_provider() const;
TileManager* tile_manager() const;
ImageDecodeCache* image_decode_cache() const;
@@ -299,11 +299,15 @@ class CC_EXPORT LayerTreeImpl {
void set_content_source_id(uint32_t id) { content_source_id_ = id; }
uint32_t content_source_id() { return content_source_id_; }
- void set_local_surface_id(const viz::LocalSurfaceId& id) {
- local_surface_id_ = id;
+ void SetLocalSurfaceIdFromParent(const viz::LocalSurfaceId& id);
+ const viz::LocalSurfaceId& local_surface_id_from_parent() const {
+ return local_surface_id_from_parent_;
}
- const viz::LocalSurfaceId& local_surface_id() const {
- return local_surface_id_;
+
+ void RequestNewLocalSurfaceId();
+ bool TakeNewLocalSurfaceIdRequest();
+ bool new_local_surface_id_request_for_testing() const {
+ return new_local_surface_id_request_;
}
void SetRasterColorSpace(int raster_color_space_id,
@@ -608,7 +612,8 @@ class CC_EXPORT LayerTreeImpl {
gfx::ColorSpace raster_color_space_;
uint32_t content_source_id_;
- viz::LocalSurfaceId local_surface_id_;
+ viz::LocalSurfaceId local_surface_id_from_parent_;
+ bool new_local_surface_id_request_ = false;
scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_;
diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc
index 08137e0e846..3f3000b41bf 100644
--- a/chromium/cc/trees/layer_tree_settings.cc
+++ b/chromium/cc/trees/layer_tree_settings.cc
@@ -15,8 +15,7 @@ LayerTreeSettings::LayerTreeSettings()
minimum_occlusion_tracking_size(gfx::Size(160, 160)),
memory_policy(64 * 1024 * 1024,
gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
- ManagedMemoryPolicy::kDefaultNumResourcesLimit),
- preferred_tile_format(viz::PlatformColor::BestTextureFormat()) {}
+ ManagedMemoryPolicy::kDefaultNumResourcesLimit) {}
LayerTreeSettings::LayerTreeSettings(const LayerTreeSettings& other) = default;
LayerTreeSettings::~LayerTreeSettings() = default;
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 2584543f863..50b8805bc7a 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -93,7 +93,7 @@ class CC_EXPORT LayerTreeSettings {
ManagedMemoryPolicy memory_policy;
size_t decoded_image_working_set_budget_bytes = 128 * 1024 * 1024;
int max_preraster_distance_in_screen_pixels = 1000;
- viz::ResourceFormat preferred_tile_format;
+ bool use_rgba_4444 = false;
bool unpremultiply_and_dither_low_bit_depth_tiles = false;
bool enable_mask_tiling = true;
@@ -156,6 +156,10 @@ class CC_EXPORT LayerTreeSettings {
// Whether SetViewportSizeAndScale should update the painted scale factor or
// the device scale factor.
bool use_painted_device_scale_factor = false;
+
+ // Whether a HitTestRegionList should be built from the active layer tree when
+ // submitting a CompositorFrame.
+ bool build_hit_test_data = false;
};
} // namespace cc
diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h
index e4aae914bae..18b7fe5118c 100644
--- a/chromium/cc/trees/mutator_host.h
+++ b/chromium/cc/trees/mutator_host.h
@@ -129,7 +129,6 @@ class MutatorHost {
virtual size_t CompositedAnimationsCount() const = 0;
virtual size_t MainThreadAnimationsCount() const = 0;
- virtual size_t MainThreadCompositableAnimationsCount() const = 0;
virtual bool CurrentFrameHadRAF() const = 0;
virtual bool NextFrameHasPendingRAF() const = 0;
};
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index 4c4cdd4c632..06b051455ed 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -367,10 +367,6 @@ size_t ProxyImpl::MainThreadAnimationsCount() const {
return host_impl_->mutator_host()->MainThreadAnimationsCount();
}
-size_t ProxyImpl::MainThreadCompositableAnimationsCount() const {
- return host_impl_->mutator_host()->MainThreadCompositableAnimationsCount();
-}
-
bool ProxyImpl::CurrentFrameHadRAF() const {
return host_impl_->mutator_host()->CurrentFrameHadRAF();
}
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index 0e3347383df..467f0e616d8 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -125,7 +125,6 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
base::TimeTicks time) override;
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
- size_t MainThreadCompositableAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
bool NextFrameHasPendingRAF() const override;
diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc
index 7b7589167bb..668e674e30d 100644
--- a/chromium/cc/trees/proxy_main.cc
+++ b/chromium/cc/trees/proxy_main.cc
@@ -300,7 +300,7 @@ void ProxyMain::BeginMainFrame(
// commit.
ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT, 0, 0,
+ ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT, 0,
begin_main_frame_state->begin_frame_args.frame_time, 1);
layer_tree_host_->QueueSwapPromise(
std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
diff --git a/chromium/cc/trees/render_frame_metadata.cc b/chromium/cc/trees/render_frame_metadata.cc
index 4466cb928c1..5678f5c8987 100644
--- a/chromium/cc/trees/render_frame_metadata.cc
+++ b/chromium/cc/trees/render_frame_metadata.cc
@@ -21,7 +21,15 @@ bool RenderFrameMetadata::HasAlwaysUpdateMetadataChanged(
const RenderFrameMetadata& rfm2) {
return rfm1.root_background_color != rfm2.root_background_color ||
rfm1.is_scroll_offset_at_top != rfm2.is_scroll_offset_at_top ||
- rfm1.selection != rfm2.selection;
+ rfm1.selection != rfm2.selection ||
+ rfm1.is_mobile_optimized != rfm2.is_mobile_optimized ||
+ rfm1.device_scale_factor != rfm2.device_scale_factor ||
+ rfm1.viewport_size_in_pixels != rfm2.viewport_size_in_pixels ||
+ rfm1.local_surface_id != rfm2.local_surface_id ||
+ rfm1.top_controls_height != rfm2.top_controls_height ||
+ rfm1.top_controls_shown_ratio != rfm2.top_controls_shown_ratio ||
+ rfm1.bottom_controls_height != rfm2.bottom_controls_height ||
+ rfm1.bottom_controls_shown_ratio != rfm2.bottom_controls_shown_ratio;
}
RenderFrameMetadata& RenderFrameMetadata::operator=(
@@ -30,14 +38,22 @@ RenderFrameMetadata& RenderFrameMetadata::operator=(
RenderFrameMetadata& RenderFrameMetadata::operator=(
RenderFrameMetadata&& other) = default;
-bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) {
+bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const {
return root_scroll_offset == other.root_scroll_offset &&
root_background_color == other.root_background_color &&
is_scroll_offset_at_top == other.is_scroll_offset_at_top &&
- selection == other.selection;
+ selection == other.selection &&
+ is_mobile_optimized == other.is_mobile_optimized &&
+ device_scale_factor == other.device_scale_factor &&
+ viewport_size_in_pixels == other.viewport_size_in_pixels &&
+ local_surface_id == other.local_surface_id &&
+ top_controls_height == other.top_controls_height &&
+ top_controls_shown_ratio == other.top_controls_shown_ratio &&
+ bottom_controls_height == other.bottom_controls_height &&
+ bottom_controls_shown_ratio == other.bottom_controls_shown_ratio;
}
-bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) {
+bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) const {
return !operator==(other);
}
diff --git a/chromium/cc/trees/render_frame_metadata.h b/chromium/cc/trees/render_frame_metadata.h
index 0a20fa8d73c..d07d7d4bfc6 100644
--- a/chromium/cc/trees/render_frame_metadata.h
+++ b/chromium/cc/trees/render_frame_metadata.h
@@ -8,7 +8,9 @@
#include "base/optional.h"
#include "cc/cc_export.h"
#include "components/viz/common/quads/selection.h"
+#include "components/viz/common/surfaces/local_surface_id.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gfx/selection_bound.h"
@@ -29,8 +31,8 @@ class CC_EXPORT RenderFrameMetadata {
RenderFrameMetadata& operator=(const RenderFrameMetadata&);
RenderFrameMetadata& operator=(RenderFrameMetadata&& other);
- bool operator==(const RenderFrameMetadata& other);
- bool operator!=(const RenderFrameMetadata& other);
+ bool operator==(const RenderFrameMetadata& other) const;
+ bool operator!=(const RenderFrameMetadata& other) const;
// Indicates whether the scroll offset of the root layer is at top, i.e.,
// whether scroll_offset.y() == 0.
@@ -48,6 +50,32 @@ class CC_EXPORT RenderFrameMetadata {
// Selection region relative to the current viewport. If the selection is
// empty or otherwise unused, the bound types will indicate such.
viz::Selection<gfx::SelectionBound> selection;
+
+ // Determines whether the page is mobile optimized or not, which means at
+ // least one of the following has to be true:
+ // - page has a width=device-width or narrower viewport.
+ // - page prevents zooming in or out (i.e. min and max page scale factors
+ // are the same).
+ bool is_mobile_optimized = false;
+
+ // The device scale factor used to generate a CompositorFrame.
+ float device_scale_factor = 1.f;
+
+ // The size of the viewport used to generate a CompositorFrame.
+ gfx::Size viewport_size_in_pixels;
+
+ // The last viz::LocalSurfaceId used to submit a CompositorFrame.
+ base::Optional<viz::LocalSurfaceId> local_surface_id;
+
+ // Used to position the Android location top bar and page content, whose
+ // precise position is computed by the renderer compositor.
+ float top_controls_height = 0.f;
+ float top_controls_shown_ratio = 0.f;
+
+ // Used to position Android bottom bar, whose position is computed by the
+ // renderer compositor.
+ float bottom_controls_height = 0.f;
+ float bottom_controls_shown_ratio = 0.f;
};
} // namespace cc
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 541e264e720..28c45b6196b 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -381,10 +381,6 @@ size_t SingleThreadProxy::MainThreadAnimationsCount() const {
return 0;
}
-size_t SingleThreadProxy::MainThreadCompositableAnimationsCount() const {
- return 0;
-}
-
bool SingleThreadProxy::CurrentFrameHadRAF() const {
return false;
}
@@ -748,8 +744,8 @@ void SingleThreadProxy::BeginMainFrame(
// know we will commit since QueueSwapPromise itself requests a commit.
ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
new_latency_info.AddLatencyNumberWithTimestamp(
- ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, 0, 0,
- begin_frame_args.frame_time, 1);
+ ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, 0, begin_frame_args.frame_time,
+ 1);
layer_tree_host_->QueueSwapPromise(
std::make_unique<LatencyInfoSwapPromise>(new_latency_info));
@@ -839,7 +835,9 @@ void SingleThreadProxy::ScheduledActionPrepareTiles() {
}
void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink() {
- NOTREACHED();
+ // This is an Android WebView codepath, which only uses multi-thread
+ // compositor. So this should not occur in single-thread mode.
+ NOTREACHED() << "Android Webview use-case, so multi-thread only";
}
void SingleThreadProxy::ScheduledActionPerformImplSideInvalidation() {
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index 07b8ca1f53c..f505320da40 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -92,7 +92,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
base::TimeTicks time) override;
size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
- size_t MainThreadCompositableAnimationsCount() const override;
bool CurrentFrameHadRAF() const override;
bool NextFrameHasPendingRAF() const override;