Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(607)

Unified Diff: cc/tiles/tile_manager_unittest.cc

Issue 2555743004: Delay activation/draw on GPU tile work completion (Closed)
Patch Set: rebase compile fix Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/tiles/tile_manager.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/tiles/tile_manager_unittest.cc
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index 73460f67a7420869162e879fbf3162ebce6444c2..b657339e72acb3e9fb4b07957fc0480fd32b2214 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -5,6 +5,8 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/bind.h"
+#include "base/callback.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -39,6 +41,11 @@
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
+using testing::_;
+using testing::Invoke;
+using testing::Return;
+using testing::StrictMock;
+
namespace cc {
namespace {
@@ -1489,7 +1496,7 @@ class TileManagerTest : public TestLayerTreeHostBase {
const LayerTreeSettings& settings,
TaskRunnerProvider* task_runner_provider,
TaskGraphRunner* task_graph_runner) override {
- return base::MakeUnique<MockLayerTreeHostImpl>(
+ return base::MakeUnique<testing::NiceMock<MockLayerTreeHostImpl>>(
settings, task_runner_provider, task_graph_runner);
}
@@ -1925,5 +1932,336 @@ TEST_F(TileManagerTest, PartialRasterSuccessfullyDisabled) {
RunPartialRasterCheck(TakeHostImpl(), false /* partial_raster_enabled */);
}
+// FakeRasterBufferProviderImpl that allows us to mock ready to draw
+// functionality.
+class MockReadyToDrawRasterBufferProviderImpl
+ : public FakeRasterBufferProviderImpl {
+ public:
+ MOCK_CONST_METHOD1(IsResourceReadyToDraw, bool(ResourceId resource_id));
+ MOCK_CONST_METHOD3(
+ SetReadyToDrawCallback,
+ uint64_t(const ResourceProvider::ResourceIdArray& resource_ids,
+ const base::Closure& callback,
+ uint64_t pending_callback_id));
+
+ std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+ const Resource* resource,
+ uint64_t resource_content_id,
+ uint64_t previous_content_id) override {
+ return base::MakeUnique<FakeRasterBuffer>();
+ }
+
+ private:
+ class FakeRasterBuffer : public RasterBuffer {
+ public:
+ void Playback(
+ const RasterSource* raster_source,
+ const gfx::Rect& raster_full_rect,
+ const gfx::Rect& raster_dirty_rect,
+ uint64_t new_content_id,
+ float scale,
+ const RasterSource::PlaybackSettings& playback_settings) override {}
+ };
+};
+
+class TileManagerReadyToDrawTest : public TileManagerTest {
+ public:
+ ~TileManagerReadyToDrawTest() override {
+ // Ensure that the host impl doesn't outlive |raster_buffer_provider_|.
+ TakeHostImpl();
+ }
+
+ void SetUp() override {
+ TileManagerTest::SetUp();
+ host_impl()->tile_manager()->SetRasterBufferProviderForTesting(
+ &mock_raster_buffer_provider_);
+
+ const gfx::Size layer_bounds(1000, 1000);
+
+ solid_color_recording_source_ =
+ FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
+
+ SkPaint solid_paint;
+ SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
+ solid_paint.setColor(solid_color);
+ solid_color_recording_source_->add_draw_rect_with_paint(
+ gfx::Rect(layer_bounds), solid_paint);
+
+ solid_color_recording_source_->Rerecord();
+
+ recording_source_ =
+ FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
+ SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
+ SkPaint non_solid_paint;
+ non_solid_paint.setColor(non_solid_color);
+
+ for (int i = 0; i < 100; ++i) {
+ for (int j = 0; j < 100; ++j) {
+ recording_source_->add_draw_rect_with_paint(
+ gfx::Rect(10 * i, 10 * j, 5, 5), non_solid_paint);
+ }
+ }
+ recording_source_->Rerecord();
+ }
+
+ LayerTreeSettings CreateSettings() override {
+ LayerTreeSettingsForTesting settings;
+ settings.renderer_settings.buffer_to_texture_target_map =
+ DefaultBufferToTextureTargetMapForTesting();
+ return settings;
+ }
+
+ void SetupTreesWithActiveTreeTiles() {
+ scoped_refptr<RasterSource> active_tree_raster_source =
+ RasterSource::CreateFromRecordingSource(recording_source_.get(), false);
+ scoped_refptr<RasterSource> pending_tree_raster_source =
+ RasterSource::CreateFromRecordingSource(
+ solid_color_recording_source_.get(), false);
+
+ SetupTrees(pending_tree_raster_source, active_tree_raster_source);
+ }
+
+ void SetupTreesWithPendingTreeTiles() {
+ scoped_refptr<RasterSource> active_tree_raster_source =
+ RasterSource::CreateFromRecordingSource(
+ solid_color_recording_source_.get(), false);
+ scoped_refptr<RasterSource> pending_tree_raster_source =
+ RasterSource::CreateFromRecordingSource(recording_source_.get(), false);
+
+ SetupTrees(pending_tree_raster_source, active_tree_raster_source);
+ }
+
+ TileManager* tile_manager() { return host_impl()->tile_manager(); }
+ MockReadyToDrawRasterBufferProviderImpl* mock_raster_buffer_provider() {
+ return &mock_raster_buffer_provider_;
+ }
+
+ private:
+ StrictMock<MockReadyToDrawRasterBufferProviderImpl>
+ mock_raster_buffer_provider_;
+ std::unique_ptr<FakeRecordingSource> recording_source_;
+ std::unique_ptr<FakeRecordingSource> solid_color_recording_source_;
+};
+
+TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) {
+ host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
+ SetupTreesWithPendingTreeTiles();
+
+ base::Closure callback;
+ {
+ base::RunLoop run_loop;
+
+ // Until we activate our ready to draw callback, treat all resources as not
+ // ready to draw.
+ EXPECT_CALL(*mock_raster_buffer_provider(),
+ IsResourceReadyToDraw(testing::_))
+ .WillRepeatedly(Return(false));
+
+ EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
+ .WillOnce(testing::Invoke([&run_loop, &callback](
+ const ResourceProvider::ResourceIdArray& resource_ids,
+ const base::Closure& callback_in, uint64_t pending_callback_id) {
+ callback = callback_in;
+ run_loop.Quit();
+ return 1;
+ }));
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ run_loop.Run();
+ }
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());
+
+ {
+ base::RunLoop run_loop;
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
+ .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
+ EXPECT_CALL(*mock_raster_buffer_provider(),
+ IsResourceReadyToDraw(testing::_))
+ .WillRepeatedly(Return(true));
+ callback.Run();
+ run_loop.Run();
+ }
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+}
+
+TEST_F(TileManagerReadyToDrawTest, NonSmoothActivationDoesNotWaitOnCallback) {
+ SetupTreesWithPendingTreeTiles();
+
+ // We're using a StrictMock on the RasterBufferProvider, so any function call
+ // will cause a test failure.
+ base::RunLoop run_loop;
+
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
+ .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
+ run_loop.Run();
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+}
+
+TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) {
+ host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
+ SetupTreesWithActiveTreeTiles();
+
+ base::Closure callback;
+ {
+ base::RunLoop run_loop;
+
+ // Until we activate our ready to draw callback, treat all resources as not
+ // ready to draw.
+ EXPECT_CALL(*mock_raster_buffer_provider(),
+ IsResourceReadyToDraw(testing::_))
+ .WillRepeatedly(Return(false));
+
+ EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
+ .WillOnce(Invoke([&run_loop, &callback](
+ const ResourceProvider::ResourceIdArray& resource_ids,
+ const base::Closure& callback_in, uint64_t pending_callback_id) {
+ callback = callback_in;
+ run_loop.Quit();
+ return 1;
+ }));
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ run_loop.Run();
+ }
+
+ EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+
+ {
+ base::RunLoop run_loop;
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw())
+ .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
+ EXPECT_CALL(*mock_raster_buffer_provider(),
+ IsResourceReadyToDraw(testing::_))
+ .WillRepeatedly(Return(true));
+ callback.Run();
+ run_loop.Run();
+ }
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+}
+
+TEST_F(TileManagerReadyToDrawTest, NonSmoothDrawDoesNotWaitOnCallback) {
+ SetupTreesWithActiveTreeTiles();
+
+ // We're using a StrictMock on the RasterBufferProvider, so any function call
+ // will cause a test failure.
+ base::RunLoop run_loop;
+
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw())
+ .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
+ run_loop.Run();
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+}
+
+TEST_F(TileManagerReadyToDrawTest, NoCallbackWhenAlreadyReadyToDraw) {
+ host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
+ SetupTreesWithPendingTreeTiles();
+
+ base::RunLoop run_loop;
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
+ .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
+ EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(_))
+ .WillRepeatedly(Return(true));
+ run_loop.Run();
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+}
+
+void UpdateVisibleRect(FakePictureLayerImpl* layer,
+ const gfx::Rect visible_rect) {
+ PictureLayerTilingSet* tiling_set = layer->tilings();
+ for (size_t j = 0; j < tiling_set->num_tilings(); ++j) {
+ PictureLayerTiling* tiling = tiling_set->tiling_at(j);
+ tiling->SetTilePriorityRectsForTesting(
+ visible_rect, // Visible rect.
+ visible_rect, // Skewport rect.
+ visible_rect, // Soon rect.
+ gfx::Rect(0, 0, 1000, 1000)); // Eventually rect.
+ }
+}
+
+TEST_F(TileManagerReadyToDrawTest, ReadyToDrawRespectsRequirementChange) {
+ host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
+ SetupTreesWithPendingTreeTiles();
+
+ // Initially create a tiling with a visible rect of (0, 0, 100, 100) and
+ // a soon rect of the rest of the layer.
+ UpdateVisibleRect(pending_layer(), gfx::Rect(0, 0, 100, 100));
+
+ // Mark all these tiles as ready to draw.
+ base::RunLoop run_loop;
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
+ .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
+ EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(_))
+ .WillRepeatedly(Return(true));
+ run_loop.Run();
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+
+ // Move the viewport to (900, 900, 100, 100), so that we need a different set
+ // of tilings.
+ UpdateVisibleRect(pending_layer(), gfx::Rect(900, 900, 100, 100));
+
+ EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(testing::_))
+ .WillRepeatedly(Return(false));
+
+ base::Closure callback;
+ {
+ base::RunLoop run_loop;
+
+ EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
+ .WillOnce(testing::Invoke([&run_loop, &callback](
+ const ResourceProvider::ResourceIdArray& resource_ids,
+ const base::Closure& callback_in, uint64_t pending_callback_id) {
+ callback = callback_in;
+ run_loop.Quit();
+ return 1;
+ }));
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ run_loop.Run();
+ }
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());
+
+ // Now switch back to our original tiling. We should be immediately able to
+ // activate, as we still have the original tile, and no longer need the
+ // tiles from the previous callback.
+ UpdateVisibleRect(pending_layer(), gfx::Rect(0, 0, 100, 100));
+
+ {
+ base::RunLoop run_loop;
+ host_impl()->tile_manager()->DidModifyTilePriorities();
+ host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
+ EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
+ .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
+ run_loop.Run();
+ }
+
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
+ EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
+}
+
} // namespace
} // namespace cc
« no previous file with comments | « cc/tiles/tile_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698