summaryrefslogtreecommitdiffstats
path: root/cc/trees/occlusion_tracker_perftest.cc
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-12 17:30:55 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-12 17:30:55 +0000
commit8a82269dafa5aca936588a6d9a7b74acfc8565c9 (patch)
treeb9bec591201c984a051cf95e1754985b70ee3802 /cc/trees/occlusion_tracker_perftest.cc
parentf734b224073190d8a32986c6550b7e5492e92735 (diff)
downloadchromium_src-8a82269dafa5aca936588a6d9a7b74acfc8565c9.zip
chromium_src-8a82269dafa5aca936588a6d9a7b74acfc8565c9.tar.gz
chromium_src-8a82269dafa5aca936588a6d9a7b74acfc8565c9.tar.bz2
Avoid int->float->int conversion in OcclusionTracker for int translates.
If the transform on a layer is an integer translation, we can easily avoid converting the query rectangle to floats just to convert them back to integers again. This is super costly. Added a perftest for this. On an N4 the results are Before: 20.553817749023438 us After: 13.440165519714355 us For about 35% reduction in time in this scnario. Also renames MapClippedRect(Rect) to MapEnclosingClippedRect(Rect) to describe what it does better, and audit callsides of MapClippedRect to change any others that then ToEnclosingRect to call the MapEnclosingClippedRect instead. Similar for Project. R=enne BUG=342848 Review URL: https://codereview.chromium.org/143293005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250739 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/trees/occlusion_tracker_perftest.cc')
-rw-r--r--cc/trees/occlusion_tracker_perftest.cc141
1 files changed, 141 insertions, 0 deletions
diff --git a/cc/trees/occlusion_tracker_perftest.cc b/cc/trees/occlusion_tracker_perftest.cc
new file mode 100644
index 0000000..32b85a4
--- /dev/null
+++ b/cc/trees/occlusion_tracker_perftest.cc
@@ -0,0 +1,141 @@
+// Copyright 2014 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/occlusion_tracker.h"
+
+#include "base/time/time.h"
+#include "cc/layers/layer_iterator.h"
+#include "cc/layers/solid_color_layer_impl.h"
+#include "cc/test/fake_layer_tree_host_impl_client.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/fake_proxy.h"
+#include "cc/test/fake_rendering_stats_instrumentation.h"
+#include "cc/test/lap_timer.h"
+#include "cc/trees/layer_tree_host_impl.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+namespace cc {
+namespace {
+
+static const int kTimeLimitMillis = 2000;
+static const int kWarmupRuns = 5;
+static const int kTimeCheckInterval = 10;
+
+class OcclusionTrackerPerfTest : public testing::Test {
+ public:
+ OcclusionTrackerPerfTest()
+ : timer_(kWarmupRuns,
+ base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+ kTimeCheckInterval) {}
+ void CreateHost() {
+ LayerTreeSettings settings;
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, &client_, &proxy_, &stats_, NULL, 1);
+ host_impl_->InitializeRenderer(
+ FakeOutputSurface::Create3d().PassAs<OutputSurface>());
+
+ scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1);
+ active_tree()->SetRootLayer(root_layer.Pass());
+ }
+
+ LayerTreeImpl* active_tree() { return host_impl_->active_tree(); }
+
+ void SetTestName(const std::string& name) { test_name_ = name; }
+
+ void PrintResults() {
+ CHECK(!test_name_.empty()) << "Must SetTestName() before AfterTest().";
+ perf_test::PrintResult("occlusion_tracker_time",
+ "",
+ test_name_,
+ 1000 * timer_.MsPerLap(),
+ "us",
+ true);
+ }
+
+ protected:
+ LapTimer timer_;
+ std::string test_name_;
+ FakeLayerTreeHostImplClient client_;
+ FakeProxy proxy_;
+ FakeRenderingStatsInstrumentation stats_;
+ scoped_ptr<LayerTreeHostImpl> host_impl_;
+};
+
+// Simulates a page with several large, transformed and animated layers.
+TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) {
+ SetTestName("unoccluded_content_rect_fully_occluded");
+
+ gfx::Rect viewport_rect(768, 1038);
+ OcclusionTrackerBase<LayerImpl, LayerImpl::RenderSurfaceType> tracker(
+ viewport_rect, false);
+
+ CreateHost();
+ host_impl_->SetViewportSize(viewport_rect.size());
+
+ scoped_ptr<SolidColorLayerImpl> opaque_layer =
+ SolidColorLayerImpl::Create(active_tree(), 2);
+ opaque_layer->SetBackgroundColor(SK_ColorRED);
+ opaque_layer->SetContentsOpaque(true);
+ opaque_layer->SetDrawsContent(true);
+ opaque_layer->SetBounds(viewport_rect.size());
+ opaque_layer->SetContentBounds(viewport_rect.size());
+ active_tree()->root_layer()->AddChild(opaque_layer.PassAs<LayerImpl>());
+
+ active_tree()->UpdateDrawProperties();
+ const LayerImplList& rsll = active_tree()->RenderSurfaceLayerList();
+ ASSERT_EQ(1u, rsll.size());
+ EXPECT_EQ(1u, rsll[0]->render_surface()->layer_list().size());
+
+ typedef LayerIterator<LayerImpl,
+ LayerImpl::LayerListType,
+ LayerImpl::RenderSurfaceType,
+ LayerIteratorActions::FrontToBack> IteratorType;
+ IteratorType begin = IteratorType::Begin(&rsll);
+ IteratorType end = IteratorType::End(&rsll);
+
+ LayerIteratorPosition<LayerImpl> pos = begin;
+
+ // The opaque_layer adds occlusion over the whole viewport.
+ tracker.EnterLayer(pos);
+ tracker.LeaveLayer(pos);
+
+ gfx::Transform transform_to_target;
+ transform_to_target.Translate(0, 96);
+ bool impl_draw_transform_is_unknown = false;
+
+ do {
+ for (int x = 0; x < viewport_rect.width(); x += 256) {
+ for (int y = 0; y < viewport_rect.height(); y += 256) {
+ gfx::Rect query_content_rect(x, y, 256, 256);
+ gfx::Rect unoccluded =
+ tracker.UnoccludedContentRect(pos.target_render_surface_layer,
+ query_content_rect,
+ transform_to_target,
+ impl_draw_transform_is_unknown);
+ // Sanity test that we're not hitting early outs.
+ bool expect_empty =
+ query_content_rect.right() <= viewport_rect.width() &&
+ query_content_rect.bottom() + 96 <= viewport_rect.height();
+ CHECK_EQ(expect_empty, unoccluded.IsEmpty())
+ << query_content_rect.ToString();
+ }
+ }
+
+ timer_.NextLap();
+ } while (!timer_.HasTimeLimitExpired());
+
+ ++begin;
+ LayerIteratorPosition<LayerImpl> next = begin;
+ EXPECT_EQ(active_tree()->root_layer(), next.current_layer);
+
+ ++begin;
+ EXPECT_EQ(end, begin);
+
+ PrintResults();
+}
+
+} // namespace
+} // namespace cc