#include "base/auto_reset.h"
#include "base/synchronization/lock.h"
#include "cc/animation/timing_function.h"
+#include "cc/base/swap_promise.h"
#include "cc/debug/frame_rate_counter.h"
#include "cc/layers/content_layer.h"
#include "cc/layers/content_layer_client.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/output/output_surface.h"
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/io_surface_draw_quad.h"
#include "cc/resources/prioritized_resource.h"
#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_update_queue.h"
-#include "cc/scheduler/frame_rate_controller.h"
#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_content_layer_impl.h"
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_tree_test.h"
-#include "cc/test/occlusion_tracker_test_common.h"
+#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
namespace cc {
namespace {
-class LayerTreeHostTest : public LayerTreeTest {
-};
+class LayerTreeHostTest : public LayerTreeTest {};
// Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
// draw with frame 0.
: num_draws_(0),
bounds_(50, 50),
invalid_rect_(10, 10, 20, 20),
- root_layer_(ContentLayer::Create(&client_)) {
- }
+ root_layer_(ContentLayer::Create(&client_)) {}
virtual void BeginTest() OVERRIDE {
root_layer_->SetIsDrawable(true);
PostSetNeedsCommitToMainThread();
}
- virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- bool result) OVERRIDE {
- EXPECT_TRUE(result);
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
+ EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
gfx::RectF root_damage_rect;
if (!frame_data->render_passes.empty())
EXPECT_TRUE(root_damage_rect.Contains(invalid_rect_));
}
- return result;
+ return draw_result;
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
num_draws_++;
}
- virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(2, num_draws_);
- }
+ virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_draws_); }
private:
int num_draws_;
LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() == 1)
LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() == 1)
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- bool result) OVERRIDE {
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
int sfn = host_impl->active_tree()->source_frame_number();
EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
sfn == kReadbackSourceFrameNumber ||
PostReadbackToMainThread();
}
- // Returning false will result in a forced draw.
- return false;
+ // Aborting for checkerboarding animations will result in a forced draw.
+ return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- bool result) OVERRIDE {
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
int sfn = host_impl->active_tree()->source_frame_number();
EXPECT_TRUE(sfn == kFirstCommitSourceFrameNumber ||
sfn == kForcedDrawSourceFrameNumber ||
sfn == kReadbackReplacementSourceFrameNumber)
<< sfn;
- // Returning false will result in a forced draw.
- return false;
+ // Aborting for checkerboarding animations will result in a forced draw.
+ return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
}
virtual void DidCommit() OVERRIDE {
: num_draws_(0),
bounds_(50, 50),
invalid_rect_(10, 10, 20, 20),
- root_layer_(ContentLayer::Create(&client_)) {
- }
+ root_layer_(ContentLayer::Create(&client_)) {}
virtual void BeginTest() OVERRIDE {
root_layer_->SetIsDrawable(true);
host_impl->SetNeedsRedrawRect(invalid_rect_);
}
- virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- bool result) OVERRIDE {
- EXPECT_TRUE(result);
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
+ EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
gfx::RectF root_damage_rect;
if (!frame_data->render_passes.empty())
NOTREACHED();
}
- return result;
+ return draw_result;
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
num_draws_++;
}
- virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(5, num_draws_);
- }
+ virtual void AfterTest() OVERRIDE { EXPECT_EQ(5, num_draws_); }
private:
int num_draws_;
class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
public:
LayerTreeHostTestUndrawnLayersDamageLater()
- : root_layer_(ContentLayer::Create(&client_)) {
- }
+ : root_layer_(ContentLayer::Create(&client_)) {}
virtual void SetupTree() OVERRIDE {
root_layer_->SetIsDrawable(true);
LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- bool result) OVERRIDE {
- EXPECT_TRUE(result);
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
+ EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
gfx::RectF root_damage_rect;
if (!frame_data->render_passes.empty())
NOTREACHED();
}
- return result;
+ return draw_result;
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
}
}
-
virtual void AfterTest() OVERRIDE {}
private:
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
-// If the layerTreeHost says it can't draw, Then we should not try to draw.
-class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
+// Tests that if a layer is not drawn because of some reason in the parent,
+// causing its content bounds to not be computed, then when it is later drawn,
+// its content bounds get pushed.
+class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
+ : public LayerTreeHostTest {
public:
- LayerTreeHostTestCanDrawBlocksDrawing() : num_commits_(0), done_(false) {}
+ LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
+ : root_layer_(Layer::Create()) {}
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+ virtual void SetupTree() OVERRIDE {
+ root_layer_->SetIsDrawable(true);
+ root_layer_->SetBounds(gfx::Size(20, 20));
+ layer_tree_host()->SetRootLayer(root_layer_);
- virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- if (done_)
- return;
- // Only the initial draw should bring us here.
- EXPECT_TRUE(impl->CanDraw());
- EXPECT_EQ(0, impl->active_tree()->source_frame_number());
+ parent_layer_ = Layer::Create();
+ parent_layer_->SetBounds(gfx::Size(20, 20));
+ parent_layer_->SetOpacity(0.0f);
+ root_layer_->AddChild(parent_layer_);
+
+ child_layer_ = Layer::Create();
+ child_layer_->SetBounds(gfx::Size(15, 15));
+ parent_layer_->AddChild(child_layer_);
+
+ LayerTreeHostTest::SetupTree();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- if (done_)
- return;
- if (num_commits_ >= 1) {
- // After the first commit, we should not be able to draw.
- EXPECT_FALSE(impl->CanDraw());
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->active_tree()->root_layer();
+ LayerImpl* parent = root->children()[0];
+ LayerImpl* child = parent->children()[0];
+
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ EXPECT_EQ(0.f, parent->opacity());
+ EXPECT_EQ(gfx::SizeF(), child->content_bounds());
+ break;
+ case 1:
+ EXPECT_EQ(1.f, parent->opacity());
+ EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
}
}
virtual void DidCommit() OVERRIDE {
- num_commits_++;
- if (num_commits_ == 1) {
- // Make the viewport empty so the host says it can't draw.
- layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
- } else if (num_commits_ == 2) {
- char pixels[4];
- layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
- } else if (num_commits_ == 3) {
- // Let it draw so we go idle and end the test.
- layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
- done_ = true;
- EndTest();
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ parent_layer_->SetOpacity(1.0f);
+ break;
+ case 2:
+ break;
+ default:
+ NOTREACHED();
}
}
virtual void AfterTest() OVERRIDE {}
private:
- int num_commits_;
- bool done_;
+ scoped_refptr<Layer> root_layer_;
+ scoped_refptr<Layer> parent_layer_;
+ scoped_refptr<Layer> child_layer_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
-// beginLayerWrite should prevent draws from executing until a commit occurs
-class LayerTreeHostTestWriteLayersRedraw : public LayerTreeHostTest {
+// If the layerTreeHost says it can't draw, Then we should not try to draw.
+class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
public:
- LayerTreeHostTestWriteLayersRedraw() : num_commits_(0), num_draws_(0) {}
+ LayerTreeHostTestCanDrawBlocksDrawing() : done_(false) {}
- virtual void BeginTest() OVERRIDE {
- PostAcquireLayerTextures();
- PostSetNeedsRedrawToMainThread(); // should be inhibited without blocking
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_draws_++;
- EXPECT_EQ(num_draws_, num_commits_);
+ if (done_)
+ return;
+ // Only the initial draw should bring us here.
+ EXPECT_TRUE(impl->CanDraw());
+ EXPECT_EQ(0, impl->active_tree()->source_frame_number());
}
virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_commits_++;
- EndTest();
+ if (done_)
+ return;
+ if (LastCommittedSourceFrameNumber(impl) >= 1) {
+ // After the first commit, we should not be able to draw.
+ EXPECT_FALSE(impl->CanDraw());
+ }
}
- virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_commits_); }
-
- private:
- int num_commits_;
- int num_draws_;
-};
-
-MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersRedraw);
-
-// Verify that when resuming visibility, Requesting layer write permission
-// will not deadlock the main thread even though there are not yet any
-// scheduled redraws. This behavior is critical for reliably surviving tab
-// switching. There are no failure conditions to this test, it just passes
-// by not timing out.
-class LayerTreeHostTestWriteLayersAfterVisible : public LayerTreeHostTest {
- public:
- LayerTreeHostTestWriteLayersAfterVisible() : num_commits_(0) {}
-
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
-
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_commits_++;
- if (num_commits_ == 2)
- EndTest();
- else if (num_commits_ < 2) {
- PostSetVisibleToMainThread(false);
- PostSetVisibleToMainThread(true);
- PostAcquireLayerTextures();
- PostSetNeedsCommitToMainThread();
+ virtual void DidCommit() OVERRIDE {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // Make the viewport empty so the host says it can't draw.
+ layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
+ break;
+ case 2: {
+ char pixels[4];
+ layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
+ break;
+ }
+ case 3:
+ // Let it draw so we go idle and end the test.
+ layer_tree_host()->SetViewportSize(gfx::Size(1, 1));
+ done_ = true;
+ EndTest();
+ break;
}
}
virtual void AfterTest() OVERRIDE {}
private:
- int num_commits_;
+ bool done_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestWriteLayersAfterVisible);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCanDrawBlocksDrawing);
// A compositeAndReadback while invisible should force a normal commit without
// assertion.
PostSetNeedsCommitToMainThread();
}
- virtual void BeginCommitOnThread(LayerTreeHostImpl *impl) OVERRIDE {
+ virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
EXPECT_EQ(frame_count_with_pending_tree_, 0);
impl->BlockNotifyReadyToActivateForTesting(true);
}
if (impl->pending_tree())
frame_count_with_pending_tree_++;
- if (frame_count_with_pending_tree_ == 2)
- impl->BlockNotifyReadyToActivateForTesting(false);
- }
-
- virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* impl,
- const BeginFrameArgs& args) OVERRIDE {
if (frame_count_with_pending_tree_ == 1) {
EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
first_frame_time_ = impl->CurrentFrameTimeTicks();
+ } else if (frame_count_with_pending_tree_ == 2) {
+ impl->BlockNotifyReadyToActivateForTesting(false);
}
}
// Since we might use a low-resolution clock on Windows, we need to
// make sure that the clock has incremented past first_frame_time_.
- while (first_frame_time_ == gfx::FrameTime::Now()) {}
+ while (first_frame_time_ == gfx::FrameTime::Now()) {
+ }
return;
}
// Verifies that StartPageScaleAnimation events propagate correctly
// from LayerTreeHost to LayerTreeHostImpl in the MT compositor.
-class LayerTreeHostTestStartPageScaleAnimation
- : public LayerTreeHostTest {
+class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
public:
LayerTreeHostTestStartPageScaleAnimation() {}
scroll_layer_ = FakeContentLayer::Create(&client_);
}
- scroll_layer_->SetScrollable(true);
+ Layer* root_layer = layer_tree_host()->root_layer();
+ scroll_layer_->SetScrollClipLayerId(root_layer->id());
+ scroll_layer_->SetIsContainerForFixedPositionLayers(true);
+ scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
+ 2 * root_layer->bounds().height()));
scroll_layer_->SetScrollOffset(gfx::Vector2d());
layer_tree_host()->root_layer()->AddChild(scroll_layer_);
+ // This test requires the page_scale and inner viewport layers to be
+ // identified.
+ layer_tree_host()->RegisterViewportLayers(
+ root_layer, scroll_layer_.get(), NULL);
layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
- OVERRIDE {
+ virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta,
+ float scale) OVERRIDE {
gfx::Vector2d offset = scroll_layer_->scroll_offset();
scroll_layer_->SetScrollOffset(offset + scroll_delta);
layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; }
- virtual void PaintContents(SkCanvas*, gfx::Rect, gfx::RectF*) OVERRIDE {
+ virtual void PaintContents(
+ SkCanvas* canvas,
+ const gfx::Rect& clip,
+ gfx::RectF* opaque,
+ ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
// Set layer opacity to 0.
if (test_layer_)
test_layer_->SetOpacity(0.f);
}
virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
+ virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
private:
Layer* test_layer_;
void ResetPaintContentsCount() { paint_contents_count_ = 0; }
virtual bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker* occlusion) OVERRIDE {
+ const OcclusionTracker<Layer>* occlusion) OVERRIDE {
bool updated = ContentLayer::Update(queue, occlusion);
paint_contents_count_++;
return updated;
virtual void CalculateContentsScale(float ideal_contents_scale,
float device_scale_factor,
float page_scale_factor,
+ float maximum_animation_contents_scale,
bool animating_transform_to_screen,
float* contents_scale_x,
float* contents_scale_y,
Layer::CalculateContentsScale(ideal_contents_scale,
device_scale_factor,
page_scale_factor,
+ maximum_animation_contents_scale,
animating_transform_to_screen,
contents_scale_x,
contents_scale_y,
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ TestWebGraphicsContext3D* context = TestContext();
switch (impl->active_tree()->source_frame_number()) {
case 0:
EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
context->ResetUsedTextures();
- PostSetNeedsCommitToMainThread();
break;
case 1:
// Number of textures should be one for scrollbar layer since it was
// New textures should have been used.
EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
context->ResetUsedTextures();
- PostSetNeedsCommitToMainThread();
break;
case 2:
EndTest();
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ TestWebGraphicsContext3D* context = TestContext();
if (drew_frame_ == impl->active_tree()->source_frame_number()) {
EXPECT_EQ(0u, context->NumUsedTextures()) << "For frame " << drew_frame_;
// We draw/ship one texture each frame for each layer.
EXPECT_EQ(2u, context->NumUsedTextures());
context->ResetUsedTextures();
+
+ if (!TestEnded())
+ PostSetNeedsCommitToMainThread();
}
virtual void Layout() OVERRIDE {
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ TestWebGraphicsContext3D* context = TestContext();
switch (impl->active_tree()->source_frame_number()) {
case 0:
EXPECT_TRUE(context->UsedTexture(context->TextureAt(0)));
EXPECT_TRUE(context->UsedTexture(context->TextureAt(1)));
context->ResetUsedTextures();
- PostSetNeedsCommitToMainThread();
break;
case 1:
// Number of textures should be doubled as the first context layer
EXPECT_TRUE(context->UsedTexture(context->TextureAt(2)));
EXPECT_TRUE(context->UsedTexture(context->TextureAt(3)));
context->ResetUsedTextures();
- PostSetNeedsCommitToMainThread();
break;
case 2:
EndTest();
static void SetLayerPropertiesForTesting(Layer* layer,
Layer* parent,
const gfx::Transform& transform,
- gfx::PointF anchor,
- gfx::PointF position,
- gfx::Size bounds,
+ const gfx::PointF& anchor,
+ const gfx::PointF& position,
+ const gfx::Size& bounds,
bool opaque) {
layer->RemoveAllChildren();
if (parent)
LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommitAndDrawFrame() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates);
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ TestWebGraphicsContext3D* context = TestContext();
switch (impl->active_tree()->source_frame_number()) {
case 0:
virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
EXPECT_LT(impl->active_tree()->source_frame_number(), 5);
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ TestWebGraphicsContext3D* context = TestContext();
// Number of textures used for drawing should one per layer except for
// frame 3 where the viewport only contains one layer.
if (impl->active_tree()->source_frame_number() == 3) {
EXPECT_EQ(1u, context->NumUsedTextures());
} else {
- EXPECT_EQ(2u, context->NumUsedTextures()) <<
- "For frame " << impl->active_tree()->source_frame_number();
+ EXPECT_EQ(2u, context->NumUsedTextures())
+ << "For frame " << impl->active_tree()->source_frame_number();
}
context->ResetUsedTextures();
return;
once_ = true;
layer_tree_host()->SetNeedsRedraw();
- layer_tree_host()->AcquireLayerTextures();
{
base::AutoLock lock(lock_);
draw_count_ = 0;
LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
Renderer* renderer = host_impl->renderer();
RenderPass::Id surface1_render_pass_id = host_impl->active_tree()
- ->root_layer()->children()[0]->render_surface()->RenderPassId();
- RenderPass::Id surface2_render_pass_id =
- host_impl->active_tree()->root_layer()->children()[0]->children()[0]
- ->render_surface()->RenderPassId();
+ ->root_layer()
+ ->children()[0]
+ ->render_surface()
+ ->RenderPassId();
+ RenderPass::Id surface2_render_pass_id = host_impl->active_tree()
+ ->root_layer()
+ ->children()[0]
+ ->children()[0]
+ ->render_surface()
+ ->RenderPassId();
switch (host_impl->active_tree()->source_frame_number()) {
case 0:
- EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
- surface1_render_pass_id));
- EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
- surface2_render_pass_id));
+ EXPECT_TRUE(
+ renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
+ EXPECT_TRUE(
+ renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
// Reduce the memory limit to only fit the root layer and one render
// surface. This prevents any contents drawing into surfaces
host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2));
break;
case 1:
- EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
- surface1_render_pass_id));
- EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
- surface2_render_pass_id));
+ EXPECT_FALSE(
+ renderer->HasAllocatedResourcesForTesting(surface1_render_pass_id));
+ EXPECT_FALSE(
+ renderer->HasAllocatedResourcesForTesting(surface2_render_pass_id));
EndTest();
break;
}
virtual bool Update(ResourceUpdateQueue*,
- const OcclusionTracker*) OVERRIDE;
+ const OcclusionTracker<Layer>*) OVERRIDE;
virtual bool DrawsContent() const OVERRIDE { return true; }
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
texture_ = PrioritizedResource::Create(
layer_tree_host()->contents_texture_manager());
texture_->SetDimensions(gfx::Size(10, 10), RGBA_8888);
- bitmap_.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
- bitmap_.allocPixels();
+ bitmap_.allocN32Pixels(10, 10);
}
scoped_ptr<PrioritizedResource> texture_;
}
bool EvictionTestLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker*) {
+ const OcclusionTracker<Layer>* occlusion) {
CreateTextureIfNeeded();
if (!texture_)
return false;
scoped_ptr<FakeProxy> proxy)
: LayerTreeHost(client, NULL, settings) {
proxy->SetLayerTreeHost(this);
- EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
+ InitializeForTesting(proxy.PassAs<Proxy>());
}
};
LayerTreeSettings settings;
settings.max_partial_texture_updates = 4;
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, NULL, settings, NULL);
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
+ new TestSharedBitmapManager());
+ scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
+ &client, &client, shared_bitmap_manager.get(), settings);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
}
LayerTreeSettings settings;
settings.max_partial_texture_updates = 4;
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, NULL, settings, NULL);
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
+ new TestSharedBitmapManager());
+ scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
+ &client, &client, shared_bitmap_manager.get(), settings);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
}
LayerTreeSettings settings;
settings.max_partial_texture_updates = 4;
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, NULL, settings, NULL);
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
+ new TestSharedBitmapManager());
+ scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
+ &client, &client, shared_bitmap_manager.get(), settings);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
}
LayerTreeSettings settings;
settings.max_partial_texture_updates = 4;
- scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, NULL, settings, NULL);
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
+ new TestSharedBitmapManager());
+ scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded(
+ &client, &client, shared_bitmap_manager.get(), settings);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
}
layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
} else {
EXPECT_EQ(
- 0u,
- layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
+ 0u, layer_tree_host()->contents_texture_manager()->MemoryUseBytes());
}
// Make sure that contents textures are marked as having been
int paint_count() const { return paint_count_; }
int lcd_notification_count() const { return lcd_notification_count_; }
- virtual void PaintContents(SkCanvas* canvas,
- gfx::Rect clip,
- gfx::RectF* opaque) OVERRIDE {
+ virtual void PaintContents(
+ SkCanvas* canvas,
+ const gfx::Rect& clip,
+ gfx::RectF* opaque,
+ ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
++paint_count_;
}
virtual void DidChangeLayerCanUseLCDText() OVERRIDE {
++lcd_notification_count_;
layer_->SetNeedsDisplay();
}
+ virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
private:
Layer* layer_;
SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
-// Verify that the BeginImplFrame notification is used to initiate rendering.
-class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
+// Verify that the BeginFrame notification is used to initiate rendering.
+class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
public:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->begin_impl_frame_scheduling_enabled = true;
+ settings->begin_frame_scheduling_enabled = true;
}
virtual void BeginTest() OVERRIDE {
- // This will trigger a SetNeedsBeginImplFrame which will trigger a
- // BeginImplFrame.
+ // This will trigger a SetNeedsBeginFrame which will trigger a
+ // BeginFrame.
PostSetNeedsCommitToMainThread();
}
- virtual bool PrepareToDrawOnThread(
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
LayerTreeHostImpl* host_impl,
LayerTreeHostImpl::FrameData* frame,
- bool result) OVERRIDE {
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
EndTest();
- return true;
+ return DrawSwapReadbackResult::DRAW_SUCCESS;
}
virtual void AfterTest() OVERRIDE {}
base::TimeTicks frame_time_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification);
+MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
-class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
+class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
: public LayerTreeHostTest {
public:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->begin_impl_frame_scheduling_enabled = true;
+ settings->begin_frame_scheduling_enabled = true;
settings->using_synchronous_renderer_compositor = true;
}
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- // The BeginImplFrame notification is turned off now but will get enabled
+ // The BeginFrame notification is turned off now but will get enabled
// once we return. End test while it's enabled.
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest,
+ base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
base::Unretained(this)));
}
};
MULTI_THREAD_TEST_F(
- LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled);
+ LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
protected:
LayerTreeHostTestAbortedCommitDoesntStall()
- : commit_count_(0), commit_complete_count_(0) {}
+ : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {}
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->begin_impl_frame_scheduling_enabled = true;
+ settings->begin_frame_scheduling_enabled = true;
}
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommit() OVERRIDE {
commit_count_++;
- if (commit_count_ == 2) {
- // A commit was just aborted, request a real commit now to make sure a
+ if (commit_count_ == 4) {
+ // After two aborted commits, request a real commit now to make sure a
// real commit following an aborted commit will still complete and
// end the test even when the Impl thread is idle.
layer_tree_host()->SetNeedsCommit();
}
}
+ virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
+ bool did_handle) OVERRIDE {
+ commit_abort_count_++;
+ // Initiate another abortable commit.
+ host_impl->SetNeedsCommit();
+ }
+
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
commit_complete_count_++;
if (commit_complete_count_ == 1) {
- // Initiate an aborted commit after the first commit.
+ // Initiate an abortable commit after the first commit.
host_impl->SetNeedsCommit();
} else {
EndTest();
}
virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(commit_count_, 3);
+ EXPECT_EQ(commit_count_, 5);
+ EXPECT_EQ(commit_abort_count_, 3);
EXPECT_EQ(commit_complete_count_, 2);
}
int commit_count_;
+ int commit_abort_count_;
int commit_complete_count_;
};
layer_tree_host()->root_layer()->AddChild(layer);
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
EndTest();
}
- virtual void AfterTest() OVERRIDE {
- }
+ virtual void AfterTest() OVERRIDE {}
FakeContentLayerClient client_;
};
void set_layer(Layer* layer) { layer_ = layer; }
- virtual void PaintContents(SkCanvas* canvas,
- gfx::Rect clip,
- gfx::RectF* opaque) OVERRIDE {
+ virtual void PaintContents(
+ SkCanvas* canvas,
+ const gfx::Rect& clip,
+ gfx::RectF* opaque,
+ ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
layer_->SetBounds(gfx::Size(2, 2));
}
virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
+ virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
+
private:
Layer* layer_;
};
class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D {
public:
MockIOSurfaceWebGraphicsContext3D() {
- test_capabilities_.iosurface = true;
- test_capabilities_.texture_rectangle = true;
+ test_capabilities_.gpu.iosurface = true;
+ test_capabilities_.gpu.texture_rectangle = true;
}
- virtual WebKit::WebGLId createTexture() OVERRIDE {
+ virtual GLuint createTexture() OVERRIDE {
return 1;
}
-
- MOCK_METHOD1(activeTexture, void(WebKit::WGC3Denum texture));
- MOCK_METHOD2(bindTexture, void(WebKit::WGC3Denum target,
- WebKit::WebGLId texture_id));
- MOCK_METHOD3(texParameteri, void(WebKit::WGC3Denum target,
- WebKit::WGC3Denum pname,
- WebKit::WGC3Dint param));
- MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(WebKit::WGC3Denum target,
- WebKit::WGC3Dint width,
- WebKit::WGC3Dint height,
- WebKit::WGC3Duint ioSurfaceId,
- WebKit::WGC3Duint plane));
- MOCK_METHOD4(drawElements, void(WebKit::WGC3Denum mode,
- WebKit::WGC3Dsizei count,
- WebKit::WGC3Denum type,
- WebKit::WGC3Dintptr offset));
- MOCK_METHOD1(deleteTexture, void(WebKit::WGC3Denum texture));
+ MOCK_METHOD1(activeTexture, void(GLenum texture));
+ MOCK_METHOD2(bindTexture, void(GLenum target,
+ GLuint texture_id));
+ MOCK_METHOD3(texParameteri, void(GLenum target,
+ GLenum pname,
+ GLint param));
+ MOCK_METHOD5(texImageIOSurface2DCHROMIUM, void(GLenum target,
+ GLint width,
+ GLint height,
+ GLuint ioSurfaceId,
+ GLuint plane));
+ MOCK_METHOD4(drawElements, void(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ GLintptr offset));
+ MOCK_METHOD1(deleteTexture, void(GLenum texture));
+ MOCK_METHOD2(produceTextureCHROMIUM,
+ void(GLenum target, const GLbyte* mailbox));
};
-
class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest {
protected:
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
+ virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
OVERRIDE {
scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned(
new MockIOSurfaceWebGraphicsContext3D);
mock_context_ = mock_context_owned.get();
- scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
- mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
- return output_surface.Pass();
+ if (delegating_renderer()) {
+ return FakeOutputSurface::CreateDelegating3d(
+ mock_context_owned.PassAs<TestWebGraphicsContext3D>());
+ } else {
+ return FakeOutputSurface::Create3d(
+ mock_context_owned.PassAs<TestWebGraphicsContext3D>());
+ }
}
virtual void SetupTree() OVERRIDE {
io_surface_layer->SetBounds(gfx::Size(10, 10));
io_surface_layer->SetAnchorPoint(gfx::PointF());
io_surface_layer->SetIsDrawable(true);
+ io_surface_layer->SetContentsOpaque(true);
io_surface_layer->SetIOSurfaceProperties(io_surface_id_, io_surface_size_);
layer_tree_host()->root_layer()->AddChild(io_surface_layer);
}
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ EXPECT_EQ(0u, host_impl->resource_provider()->num_resources());
// In WillDraw, the IOSurfaceLayer sets up the io surface texture.
- EXPECT_CALL(*mock_context_, activeTexture(_))
- .Times(0);
+ EXPECT_CALL(*mock_context_, activeTexture(_)).Times(0);
EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
.Times(AtLeast(1));
- EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
- GL_TEXTURE_MIN_FILTER,
- GL_LINEAR))
- .Times(1);
- EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
- GL_TEXTURE_MAG_FILTER,
- GL_LINEAR))
+ EXPECT_CALL(*mock_context_,
+ texParameteri(
+ GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
.Times(1);
- EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
- GL_TEXTURE_WRAP_S,
- GL_CLAMP_TO_EDGE))
+ EXPECT_CALL(*mock_context_,
+ texParameteri(
+ GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
.Times(1);
- EXPECT_CALL(*mock_context_, texParameteri(GL_TEXTURE_RECTANGLE_ARB,
- GL_TEXTURE_WRAP_T,
- GL_CLAMP_TO_EDGE))
- .Times(1);
-
- EXPECT_CALL(*mock_context_, texImageIOSurface2DCHROMIUM(
- GL_TEXTURE_RECTANGLE_ARB,
- io_surface_size_.width(),
- io_surface_size_.height(),
- io_surface_id_,
- 0))
- .Times(1);
-
- EXPECT_CALL(*mock_context_, bindTexture(_, 0))
- .Times(AnyNumber());
- }
-
- virtual bool PrepareToDrawOnThread(
+ EXPECT_CALL(*mock_context_,
+ texParameteri(GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_POOL_CHROMIUM,
+ GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)).Times(1);
+ EXPECT_CALL(*mock_context_,
+ texParameteri(GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE)).Times(1);
+ EXPECT_CALL(*mock_context_,
+ texParameteri(GL_TEXTURE_RECTANGLE_ARB,
+ GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE)).Times(1);
+
+ EXPECT_CALL(*mock_context_,
+ texImageIOSurface2DCHROMIUM(GL_TEXTURE_RECTANGLE_ARB,
+ io_surface_size_.width(),
+ io_surface_size_.height(),
+ io_surface_id_,
+ 0)).Times(1);
+
+ EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber());
+ }
+
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
LayerTreeHostImpl* host_impl,
LayerTreeHostImpl::FrameData* frame,
- bool result) OVERRIDE {
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
Mock::VerifyAndClearExpectations(&mock_context_);
+ ResourceProvider* resource_provider = host_impl->resource_provider();
+ EXPECT_EQ(1u, resource_provider->num_resources());
+ CHECK_EQ(1u, frame->render_passes.size());
+ CHECK_LE(1u, frame->render_passes[0]->quad_list.size());
+ const DrawQuad* quad = frame->render_passes[0]->quad_list[0];
+ CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material);
+ const IOSurfaceDrawQuad* io_surface_draw_quad =
+ IOSurfaceDrawQuad::MaterialCast(quad);
+ EXPECT_SIZE_EQ(io_surface_size_, io_surface_draw_quad->io_surface_size);
+ EXPECT_NE(0u, io_surface_draw_quad->io_surface_resource_id);
+ EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_RECTANGLE_ARB),
+ resource_provider->TargetForTesting(
+ io_surface_draw_quad->io_surface_resource_id));
- // The io surface layer's texture is drawn.
- EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0))
- .Times(AtLeast(1));
EXPECT_CALL(*mock_context_, bindTexture(GL_TEXTURE_RECTANGLE_ARB, 1))
.Times(1);
- EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
- .Times(AtLeast(1));
+ if (delegating_renderer()) {
+ // The io surface layer's resource should be sent to the parent.
+ EXPECT_CALL(*mock_context_,
+ produceTextureCHROMIUM(GL_TEXTURE_RECTANGLE_ARB, _)).Times(1);
+ } else {
+ // The io surface layer's texture is drawn.
+ EXPECT_CALL(*mock_context_, activeTexture(GL_TEXTURE0)).Times(AtLeast(1));
+ EXPECT_CALL(*mock_context_, drawElements(GL_TRIANGLES, 6, _, _))
+ .Times(AtLeast(1));
+ }
- return result;
+ return draw_result;
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
Mock::VerifyAndClearExpectations(&mock_context_);
- EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(1);
+ EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1));
EndTest();
}
gfx::Size io_surface_size_;
};
-// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- LayerTreeHostTestIOSurfaceDrawing);
-
-class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- root = FakeContentLayer::Create(&client_);
- root->SetBounds(gfx::Size(20, 20));
-
- child = FakeContentLayer::Create(&client_);
- child->SetBounds(gfx::Size(10, 10));
- root->AddChild(child);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeHostTest::SetupTree();
- }
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing);
+class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
+ public:
virtual void BeginTest() OVERRIDE {
+ frame_ = 0;
PostSetNeedsCommitToMainThread();
}
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- WaitForCallback();
- }
+ // Round 1: commit + draw
+ // Round 2: commit only (no draw/swap)
+ // Round 3: draw only (no commit)
+ // Round 4: composite & readback (2 commits, no draw/swap)
+ // Round 5: commit + draw
- void WaitForCallback() {
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(
- &LayerTreeHostTestAsyncReadback::NextStep,
- base::Unretained(this)));
+ virtual void DidCommit() OVERRIDE {
+ int commit = layer_tree_host()->source_frame_number();
+ switch (commit) {
+ case 2:
+ // Round 2 done.
+ EXPECT_EQ(1, frame_);
+ layer_tree_host()->SetNeedsRedraw();
+ break;
+ case 3:
+ // CompositeAndReadback in Round 4, first commit.
+ EXPECT_EQ(2, frame_);
+ break;
+ case 4:
+ // Round 4 done.
+ EXPECT_EQ(2, frame_);
+ layer_tree_host()->SetNeedsCommit();
+ layer_tree_host()->SetNeedsRedraw();
+ break;
+ }
}
- void NextStep() {
- int frame = layer_tree_host()->source_frame_number();
- switch (frame) {
+ virtual void DidCompleteSwapBuffers() OVERRIDE {
+ int commit = layer_tree_host()->source_frame_number();
+ ++frame_;
+ char pixels[4] = {0};
+ switch (frame_) {
case 1:
- child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
- base::Unretained(this))));
- EXPECT_EQ(0u, callbacks_.size());
+ // Round 1 done.
+ EXPECT_EQ(1, commit);
+ layer_tree_host()->SetNeedsCommit();
break;
case 2:
- if (callbacks_.size() < 1u) {
- WaitForCallback();
- return;
- }
- EXPECT_EQ(1u, callbacks_.size());
- EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[0].ToString());
-
- child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
- base::Unretained(this))));
- root->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
- base::Unretained(this))));
- child->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
- base::Bind(&LayerTreeHostTestAsyncReadback::CopyOutputCallback,
- base::Unretained(this))));
- EXPECT_EQ(1u, callbacks_.size());
+ // Round 3 done.
+ EXPECT_EQ(2, commit);
+ layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
break;
case 3:
- if (callbacks_.size() < 4u) {
- WaitForCallback();
- return;
- }
- EXPECT_EQ(4u, callbacks_.size());
- // The child was copied to a bitmap and passed back twice.
- EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[1].ToString());
- EXPECT_EQ(gfx::Size(10, 10).ToString(), callbacks_[2].ToString());
- // The root was copied to a bitmap and passed back also.
- EXPECT_EQ(gfx::Size(20, 20).ToString(), callbacks_[3].ToString());
+ // Round 5 done.
+ EXPECT_EQ(5, commit);
EndTest();
break;
}
}
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_TRUE(result->HasBitmap());
- scoped_ptr<SkBitmap> bitmap = result->TakeBitmap().Pass();
- EXPECT_EQ(result->size().ToString(),
- gfx::Size(bitmap->width(), bitmap->height()).ToString());
- callbacks_.push_back(result->size());
- }
+ virtual void AfterTest() OVERRIDE {}
- virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(4u, callbacks_.size());
- }
-
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
- OVERRIDE {
- scoped_ptr<FakeOutputSurface> output_surface;
- if (use_gl_renderer_) {
- output_surface = FakeOutputSurface::Create3d().Pass();
- } else {
- output_surface = FakeOutputSurface::CreateSoftware(
- make_scoped_ptr(new SoftwareOutputDevice)).Pass();
- }
- return output_surface.PassAs<OutputSurface>();
- }
-
- bool use_gl_renderer_;
- std::vector<gfx::Size> callbacks_;
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root;
- scoped_refptr<FakeContentLayer> child;
+ protected:
+ int frame_;
};
-// Readback can't be done with a delegating renderer.
-TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
- use_gl_renderer_ = true;
- RunTest(false, false, false);
-}
-
-TEST_F(LayerTreeHostTestAsyncReadback,
- GLRenderer_RunMultiThread_MainThreadPainting) {
- use_gl_renderer_ = true;
- RunTest(true, false, false);
+// Flaky on all platforms: http://crbug.com/327498
+TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_DelegatingRenderer) {
+ RunTest(true, true, true);
}
-TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
- use_gl_renderer_ = false;
- RunTest(false, false, false);
+TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) {
+ RunTest(true, false, true);
}
-TEST_F(LayerTreeHostTestAsyncReadback,
- SoftwareRenderer_RunMultiThread_MainThreadPainting) {
- use_gl_renderer_ = false;
- RunTest(true, false, false);
-}
+class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
+ public:
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ // PictureLayer can only be used with impl side painting enabled.
+ settings->impl_side_painting = true;
+ }
-class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
- protected:
virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
-
- main_destroyed_ = FakeContentLayer::Create(&client_);
- main_destroyed_->SetBounds(gfx::Size(15, 15));
- root_->AddChild(main_destroyed_);
-
- impl_destroyed_ = FakeContentLayer::Create(&client_);
- impl_destroyed_->SetBounds(gfx::Size(10, 10));
- root_->AddChild(impl_destroyed_);
-
- layer_tree_host()->SetRootLayer(root_);
+ layer_ = FakePictureLayer::Create(&client_);
+ // Force commits to not be aborted so new frames get drawn, otherwise
+ // the renderer gets deferred initialized but nothing new needs drawing.
+ layer_->set_always_update_resources(true);
+ layer_tree_host()->SetRootLayer(layer_);
LayerTreeHostTest::SetupTree();
}
virtual void BeginTest() OVERRIDE {
- callback_count_ = 0;
+ did_initialize_gl_ = false;
+ did_release_gl_ = false;
+ last_source_frame_number_drawn_ = -1; // Never drawn.
PostSetNeedsCommitToMainThread();
}
- virtual void DidCommit() OVERRIDE {
- int frame = layer_tree_host()->source_frame_number();
- switch (frame) {
- case 1:
- main_destroyed_->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackLayerDestroyed::
- CopyOutputCallback,
- base::Unretained(this))));
- impl_destroyed_->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackLayerDestroyed::
- CopyOutputCallback,
- base::Unretained(this))));
- EXPECT_EQ(0, callback_count_);
+ virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
+ OVERRIDE {
+ scoped_ptr<TestWebGraphicsContext3D> context3d(
+ TestWebGraphicsContext3D::Create());
- // Destroy the main thread layer right away.
- main_destroyed_->RemoveFromParent();
- main_destroyed_ = NULL;
+ return FakeOutputSurface::CreateDeferredGL(
+ scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice));
+ }
- // Should callback with a NULL bitmap.
- EXPECT_EQ(1, callback_count_);
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ ASSERT_TRUE(host_impl->RootLayer());
+ FakePictureLayerImpl* layer_impl =
+ static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
- // Prevent drawing so we can't make a copy of the impl_destroyed layer.
- layer_tree_host()->SetViewportSize(gfx::Size());
- break;
- case 2:
- // Flush the message loops and make sure the callbacks run.
- layer_tree_host()->SetNeedsCommit();
- break;
- case 3:
- // No drawing means no readback yet.
- EXPECT_EQ(1, callback_count_);
+ // The same frame can be draw multiple times if new visible tiles are
+ // rasterized. But we want to make sure we only post DeferredInitialize
+ // and ReleaseGL once, so early out if the same frame is drawn again.
+ if (last_source_frame_number_drawn_ ==
+ host_impl->active_tree()->source_frame_number())
+ return;
- // Destroy the impl thread layer.
- impl_destroyed_->RemoveFromParent();
- impl_destroyed_ = NULL;
+ last_source_frame_number_drawn_ =
+ host_impl->active_tree()->source_frame_number();
- // No callback yet because it's on the impl side.
- EXPECT_EQ(1, callback_count_);
- break;
- case 4:
- // Flush the message loops and make sure the callbacks run.
- layer_tree_host()->SetNeedsCommit();
- break;
- case 5:
- // We should get another callback with a NULL bitmap.
- EXPECT_EQ(2, callback_count_);
- EndTest();
- break;
+ if (!did_initialize_gl_) {
+ EXPECT_LE(1u, layer_impl->append_quads_count());
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
+ base::Unretained(this),
+ base::Unretained(host_impl)));
+ } else if (did_initialize_gl_ && !did_release_gl_) {
+ EXPECT_LE(2u, layer_impl->append_quads_count());
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
+ base::Unretained(this),
+ base::Unretained(host_impl)));
+ } else if (did_initialize_gl_ && did_release_gl_) {
+ EXPECT_LE(3u, layer_impl->append_quads_count());
+ EndTest();
}
}
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_TRUE(result->IsEmpty());
- ++callback_count_;
+ void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
+ EXPECT_FALSE(did_initialize_gl_);
+ // SetAndInitializeContext3D calls SetNeedsCommit.
+ FakeOutputSurface* fake_output_surface =
+ static_cast<FakeOutputSurface*>(host_impl->output_surface());
+ scoped_refptr<TestContextProvider> context_provider =
+ TestContextProvider::Create(); // Not bound to thread.
+ EXPECT_TRUE(
+ fake_output_surface->InitializeAndSetContext3d(context_provider));
+ did_initialize_gl_ = true;
+ }
+
+ void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
+ EXPECT_TRUE(did_initialize_gl_);
+ EXPECT_FALSE(did_release_gl_);
+ // ReleaseGL calls SetNeedsCommit.
+ static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
+ did_release_gl_ = true;
}
- virtual void AfterTest() OVERRIDE {}
+ virtual void AfterTest() OVERRIDE {
+ EXPECT_TRUE(did_initialize_gl_);
+ EXPECT_TRUE(did_release_gl_);
+ }
- int callback_count_;
+ private:
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> main_destroyed_;
- scoped_refptr<FakeContentLayer> impl_destroyed_;
+ scoped_refptr<FakePictureLayer> layer_;
+ bool did_initialize_gl_;
+ bool did_release_gl_;
+ int last_source_frame_number_drawn_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncReadbackLayerDestroyed);
-
-class LayerTreeHostTestAsyncReadbackInHiddenSubtree : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
-
- grand_parent_layer_ = FakeContentLayer::Create(&client_);
- grand_parent_layer_->SetBounds(gfx::Size(15, 15));
- root_->AddChild(grand_parent_layer_);
-
- // parent_layer_ owns a render surface.
- parent_layer_ = FakeContentLayer::Create(&client_);
- parent_layer_->SetBounds(gfx::Size(15, 15));
- parent_layer_->SetForceRenderSurface(true);
- grand_parent_layer_->AddChild(parent_layer_);
-
- copy_layer_ = FakeContentLayer::Create(&client_);
- copy_layer_->SetBounds(gfx::Size(10, 10));
- parent_layer_->AddChild(copy_layer_);
-
- layer_tree_host()->SetRootLayer(root_);
- LayerTreeHostTest::SetupTree();
- }
-
- void AddCopyRequest(Layer* layer) {
- layer->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackInHiddenSubtree::CopyOutputCallback,
- base::Unretained(this))));
- }
+MULTI_THREAD_DIRECT_RENDERER_TEST_F(LayerTreeHostTestDeferredInitialize);
- virtual void BeginTest() OVERRIDE {
- callback_count_ = 0;
- PostSetNeedsCommitToMainThread();
+// Test for UI Resource management.
+class LayerTreeHostTestUIResource : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestUIResource() : num_ui_resources_(0) {}
- AddCopyRequest(copy_layer_.get());
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->texture_id_allocation_chunk_size = 1;
}
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
- ++callback_count_;
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- switch (callback_count_) {
+ virtual void DidCommit() OVERRIDE {
+ int frame = layer_tree_host()->source_frame_number();
+ switch (frame) {
case 1:
- // Hide the copy request layer.
- grand_parent_layer_->SetHideLayerAndSubtree(false);
- parent_layer_->SetHideLayerAndSubtree(false);
- copy_layer_->SetHideLayerAndSubtree(true);
- AddCopyRequest(copy_layer_.get());
+ CreateResource();
+ CreateResource();
+ PostSetNeedsCommitToMainThread();
break;
case 2:
- // Hide the copy request layer's parent only.
- grand_parent_layer_->SetHideLayerAndSubtree(false);
- parent_layer_->SetHideLayerAndSubtree(true);
- copy_layer_->SetHideLayerAndSubtree(false);
- AddCopyRequest(copy_layer_.get());
+ // Usually ScopedUIResource are deleted from the manager in their
+ // destructor. Here we just want to test that a direct call to
+ // DeleteUIResource works.
+ layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
+ PostSetNeedsCommitToMainThread();
break;
case 3:
- // Hide the copy request layer's grand parent only.
- grand_parent_layer_->SetHideLayerAndSubtree(true);
- parent_layer_->SetHideLayerAndSubtree(false);
- copy_layer_->SetHideLayerAndSubtree(false);
- AddCopyRequest(copy_layer_.get());
+ // DeleteUIResource can be called with an invalid id.
+ layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
+ PostSetNeedsCommitToMainThread();
break;
case 4:
- // Hide the copy request layer's parent and grandparent.
- grand_parent_layer_->SetHideLayerAndSubtree(true);
- parent_layer_->SetHideLayerAndSubtree(true);
- copy_layer_->SetHideLayerAndSubtree(false);
- AddCopyRequest(copy_layer_.get());
+ CreateResource();
+ CreateResource();
+ PostSetNeedsCommitToMainThread();
break;
case 5:
- // Hide the copy request layer as well as its parent and grandparent.
- grand_parent_layer_->SetHideLayerAndSubtree(true);
- parent_layer_->SetHideLayerAndSubtree(true);
- copy_layer_->SetHideLayerAndSubtree(true);
- AddCopyRequest(copy_layer_.get());
- break;
- case 6:
+ ClearResources();
EndTest();
break;
}
}
- virtual void AfterTest() OVERRIDE {}
-
- int callback_count_;
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> grand_parent_layer_;
- scoped_refptr<FakeContentLayer> parent_layer_;
- scoped_refptr<FakeContentLayer> copy_layer_;
-};
-
-// No output to copy for delegated renderers.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
- LayerTreeHostTestAsyncReadbackInHiddenSubtree);
-
-class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
- : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
-
- grand_parent_layer_ = FakeContentLayer::Create(&client_);
- grand_parent_layer_->SetBounds(gfx::Size(15, 15));
- grand_parent_layer_->SetHideLayerAndSubtree(true);
- root_->AddChild(grand_parent_layer_);
+ void PerformTest(LayerTreeHostImpl* impl) {
+ TestWebGraphicsContext3D* context = TestContext();
- // parent_layer_ owns a render surface.
- parent_layer_ = FakeContentLayer::Create(&client_);
- parent_layer_->SetBounds(gfx::Size(15, 15));
- parent_layer_->SetForceRenderSurface(true);
- grand_parent_layer_->AddChild(parent_layer_);
+ int frame = impl->active_tree()->source_frame_number();
+ switch (frame) {
+ case 0:
+ ASSERT_EQ(0u, context->NumTextures());
+ break;
+ case 1:
+ // Created two textures.
+ ASSERT_EQ(2u, context->NumTextures());
+ break;
+ case 2:
+ // One texture left after one deletion.
+ ASSERT_EQ(1u, context->NumTextures());
+ break;
+ case 3:
+ // Resource manager state should not change when delete is called on an
+ // invalid id.
+ ASSERT_EQ(1u, context->NumTextures());
+ break;
+ case 4:
+ // Creation after deletion: two more creates should total up to
+ // three textures.
+ ASSERT_EQ(3u, context->NumTextures());
+ break;
+ }
+ }
- copy_layer_ = FakeContentLayer::Create(&client_);
- copy_layer_->SetBounds(gfx::Size(10, 10));
- parent_layer_->AddChild(copy_layer_);
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ if (!layer_tree_host()->settings().impl_side_painting)
+ PerformTest(impl);
+ }
- layer_tree_host()->SetRootLayer(root_);
- LayerTreeHostTest::SetupTree();
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ if (layer_tree_host()->settings().impl_side_painting)
+ PerformTest(impl);
}
- virtual void BeginTest() OVERRIDE {
- did_draw_ = false;
- PostSetNeedsCommitToMainThread();
+ virtual void AfterTest() OVERRIDE {}
- copy_layer_->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest::
- CopyOutputCallback,
- base::Unretained(this))));
+ private:
+ // Must clear all resources before exiting.
+ void ClearResources() {
+ for (int i = 0; i < num_ui_resources_; i++)
+ ui_resources_[i].reset();
}
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
- EndTest();
+ void CreateResource() {
+ ui_resources_[num_ui_resources_++] =
+ FakeScopedUIResource::Create(layer_tree_host());
}
- virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- Renderer* renderer = host_impl->renderer();
+ scoped_ptr<FakeScopedUIResource> ui_resources_[5];
+ int num_ui_resources_;
+};
- LayerImpl* root = host_impl->active_tree()->root_layer();
- LayerImpl* grand_parent = root->children()[0];
- LayerImpl* parent = grand_parent->children()[0];
- LayerImpl* copy_layer = parent->children()[0];
+MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
- // |parent| owns a surface, but it was hidden and not part of the copy
- // request so it should not allocate any resource.
- EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting(
- parent->render_surface()->RenderPassId()));
+class PushPropertiesCountingLayerImpl : public LayerImpl {
+ public:
+ static scoped_ptr<PushPropertiesCountingLayerImpl> Create(
+ LayerTreeImpl* tree_impl, int id) {
+ return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id));
+ }
- // |copy_layer| should have been rendered to a texture since it was needed
- // for a copy request.
- EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting(
- copy_layer->render_surface()->RenderPassId()));
+ virtual ~PushPropertiesCountingLayerImpl() {}
- did_draw_ = true;
+ virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
+ LayerImpl::PushPropertiesTo(layer);
+ push_properties_count_++;
+ // Push state to the active tree because we can only access it from there.
+ static_cast<PushPropertiesCountingLayerImpl*>(
+ layer)->push_properties_count_ = push_properties_count_;
}
- virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); }
-
- FakeContentLayerClient client_;
- bool did_draw_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> grand_parent_layer_;
- scoped_refptr<FakeContentLayer> parent_layer_;
- scoped_refptr<FakeContentLayer> copy_layer_;
-};
+ virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
+ OVERRIDE {
+ return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
+ PassAs<LayerImpl>();
+ }
-// No output to copy for delegated renderers.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest);
+ size_t push_properties_count() const { return push_properties_count_; }
+ void reset_push_properties_count() { push_properties_count_ = 0; }
-class LayerTreeHostTestAsyncReadbackClippedOut : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
+ private:
+ size_t push_properties_count_;
- parent_layer_ = FakeContentLayer::Create(&client_);
- parent_layer_->SetBounds(gfx::Size(15, 15));
- parent_layer_->SetMasksToBounds(true);
- root_->AddChild(parent_layer_);
-
- copy_layer_ = FakeContentLayer::Create(&client_);
- copy_layer_->SetPosition(gfx::Point(15, 15));
- copy_layer_->SetBounds(gfx::Size(10, 10));
- parent_layer_->AddChild(copy_layer_);
-
- layer_tree_host()->SetRootLayer(root_);
- LayerTreeHostTest::SetupTree();
- }
-
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
-
- copy_layer_->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackClippedOut::CopyOutputCallback,
- base::Unretained(this))));
- }
-
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- // We should still get a callback with no output if the copy requested layer
- // was completely clipped away.
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_EQ(gfx::Size().ToString(), result->size().ToString());
- EndTest();
+ PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id)
+ : LayerImpl(tree_impl, id),
+ push_properties_count_(0) {
+ SetAnchorPoint(gfx::PointF());
+ SetBounds(gfx::Size(1, 1));
}
-
- virtual void AfterTest() OVERRIDE {}
-
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> parent_layer_;
- scoped_refptr<FakeContentLayer> copy_layer_;
};
-// No output to copy for delegated renderers.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- LayerTreeHostTestAsyncReadbackClippedOut);
-
-class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
-
- copy_layer_ = FakeContentLayer::Create(&client_);
- copy_layer_->SetBounds(gfx::Size(10, 10));
- root_->AddChild(copy_layer_);
-
- layer_tree_host()->SetRootLayer(root_);
- LayerTreeHostTest::SetupTree();
- }
-
- void AddCopyRequest(Layer* layer) {
- layer->RequestCopyOfOutput(
- CopyOutputRequest::CreateBitmapRequest(base::Bind(
- &LayerTreeHostTestAsyncTwoReadbacksWithoutDraw::CopyOutputCallback,
- base::Unretained(this))));
+class PushPropertiesCountingLayer : public Layer {
+ public:
+ static scoped_refptr<PushPropertiesCountingLayer> Create() {
+ return new PushPropertiesCountingLayer();
}
- virtual void BeginTest() OVERRIDE {
- saw_copy_request_ = false;
- callback_count_ = 0;
- PostSetNeedsCommitToMainThread();
-
- // Prevent drawing.
- layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
-
- AddCopyRequest(copy_layer_.get());
+ virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
+ Layer::PushPropertiesTo(layer);
+ push_properties_count_++;
+ if (persist_needs_push_properties_)
+ needs_push_properties_ = true;
}
- virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- if (impl->active_tree()->source_frame_number() == 0) {
- LayerImpl* root = impl->active_tree()->root_layer();
- EXPECT_TRUE(root->children()[0]->HasCopyRequest());
- saw_copy_request_ = true;
- }
+ virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
+ OVERRIDE {
+ return PushPropertiesCountingLayerImpl::Create(tree_impl, id()).
+ PassAs<LayerImpl>();
}
- virtual void DidCommit() OVERRIDE {
- if (layer_tree_host()->source_frame_number() == 1) {
- // Allow drawing.
- layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds()));
+ size_t push_properties_count() const { return push_properties_count_; }
+ void reset_push_properties_count() { push_properties_count_ = 0; }
- AddCopyRequest(copy_layer_.get());
- }
+ void set_persist_needs_push_properties(bool persist) {
+ persist_needs_push_properties_ = persist;
}
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_EQ(copy_layer_->bounds().ToString(), result->size().ToString());
- ++callback_count_;
-
- if (callback_count_ == 2)
- EndTest();
+ private:
+ PushPropertiesCountingLayer()
+ : push_properties_count_(0), persist_needs_push_properties_(false) {
+ SetAnchorPoint(gfx::PointF());
+ SetBounds(gfx::Size(1, 1));
+ SetIsDrawable(true);
}
+ virtual ~PushPropertiesCountingLayer() {}
- virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); }
-
- bool saw_copy_request_;
- int callback_count_;
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
+ size_t push_properties_count_;
+ bool persist_needs_push_properties_;
};
-// No output to copy for delegated renderers.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
- LayerTreeHostTestAsyncTwoReadbacksWithoutDraw);
-
-class LayerTreeHostTestAsyncReadbackLostOutputSurface
- : public LayerTreeHostTest {
+class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
protected:
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
- OVERRIDE {
- if (!first_context_provider_.get()) {
- first_context_provider_ = TestContextProvider::Create();
- return FakeOutputSurface::Create3d(first_context_provider_)
- .PassAs<OutputSurface>();
- }
-
- EXPECT_FALSE(second_context_provider_.get());
- second_context_provider_ = TestContextProvider::Create();
- return FakeOutputSurface::Create3d(second_context_provider_)
- .PassAs<OutputSurface>();
+ virtual void BeginTest() OVERRIDE {
+ num_commits_ = 0;
+ expected_push_properties_root_ = 0;
+ expected_push_properties_child_ = 0;
+ expected_push_properties_grandchild_ = 0;
+ expected_push_properties_child2_ = 0;
+ expected_push_properties_other_root_ = 0;
+ expected_push_properties_leaf_layer_ = 0;
+ PostSetNeedsCommitToMainThread();
}
virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
+ root_ = PushPropertiesCountingLayer::Create();
+ child_ = PushPropertiesCountingLayer::Create();
+ child2_ = PushPropertiesCountingLayer::Create();
+ grandchild_ = PushPropertiesCountingLayer::Create();
+ leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
+ leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
- copy_layer_ = FakeContentLayer::Create(&client_);
- copy_layer_->SetBounds(gfx::Size(10, 10));
- root_->AddChild(copy_layer_);
+ root_->AddChild(child_);
+ root_->AddChild(child2_);
+ child_->AddChild(grandchild_);
+ child2_->AddChild(leaf_always_pushing_layer_);
- layer_tree_host()->SetRootLayer(root_);
+ other_root_ = PushPropertiesCountingLayer::Create();
+
+ // Don't set the root layer here.
LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
-
- void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {
- EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- EXPECT_EQ(gfx::Size(10, 10).ToString(), result->size().ToString());
- EXPECT_TRUE(result->HasTexture());
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ ++num_commits_;
- // Save the result for later.
- EXPECT_FALSE(result_);
- result_ = result.Pass();
+ EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
+ EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
+ EXPECT_EQ(expected_push_properties_grandchild_,
+ grandchild_->push_properties_count());
+ EXPECT_EQ(expected_push_properties_child2_,
+ child2_->push_properties_count());
+ EXPECT_EQ(expected_push_properties_other_root_,
+ other_root_->push_properties_count());
+ EXPECT_EQ(expected_push_properties_leaf_layer_,
+ leaf_always_pushing_layer_->push_properties_count());
- // Post a commit to lose the output surface.
- layer_tree_host()->SetNeedsCommit();
- }
+ // The scrollbar layer always needs to be pushed.
+ if (root_->layer_tree_host()) {
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(root_->needs_push_properties());
+ }
+ if (child2_->layer_tree_host()) {
+ EXPECT_TRUE(child2_->descendant_needs_push_properties());
+ EXPECT_FALSE(child2_->needs_push_properties());
+ }
+ if (leaf_always_pushing_layer_->layer_tree_host()) {
+ EXPECT_FALSE(
+ leaf_always_pushing_layer_->descendant_needs_push_properties());
+ EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
+ }
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- switch (layer_tree_host()->source_frame_number()) {
- case 1:
- // The layers have been pushed to the impl side. The layer textures have
- // been allocated.
+ // child_ and grandchild_ don't persist their need to push properties.
+ if (child_->layer_tree_host()) {
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ }
+ if (grandchild_->layer_tree_host()) {
+ EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild_->needs_push_properties());
+ }
- // Request a copy of the layer. This will use another texture.
- copy_layer_->RequestCopyOfOutput(
- CopyOutputRequest::CreateRequest(base::Bind(
- &LayerTreeHostTestAsyncReadbackLostOutputSurface::
- CopyOutputCallback,
- base::Unretained(this))));
- break;
- case 4:
- // With SingleThreadProxy it takes two commits to finally swap after a
- // context loss.
- case 5:
- // Now destroy the CopyOutputResult, releasing the texture inside back
- // to the compositor.
- EXPECT_TRUE(result_);
- result_.reset();
-
- // Check that it is released.
- ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&LayerTreeHostTestAsyncReadbackLostOutputSurface::
- CheckNumTextures,
- base::Unretained(this),
- num_textures_after_loss_ - 1));
- break;
+ if (other_root_->layer_tree_host()) {
+ EXPECT_FALSE(other_root_->descendant_needs_push_properties());
+ EXPECT_FALSE(other_root_->needs_push_properties());
}
- }
- virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
- OVERRIDE {
- switch (impl->active_tree()->source_frame_number()) {
- case 0:
- // The layers have been drawn, so their textures have been allocated.
- EXPECT_FALSE(result_);
- num_textures_without_readback_ =
- first_context_provider_->TestContext3d()->NumTextures();
- break;
+ switch (num_commits_) {
case 1:
- // We did a readback, so there will be a readback texture around now.
- EXPECT_LT(num_textures_without_readback_,
- first_context_provider_->TestContext3d()->NumTextures());
+ layer_tree_host()->SetRootLayer(root_);
+ // Layers added to the tree get committed.
+ ++expected_push_properties_root_;
+ ++expected_push_properties_child_;
+ ++expected_push_properties_grandchild_;
+ ++expected_push_properties_child2_;
break;
case 2:
- // The readback texture is collected.
- EXPECT_TRUE(result_);
-
- // Lose the output surface.
- first_context_provider_->TestContext3d()->loseContextCHROMIUM(
- GL_GUILTY_CONTEXT_RESET_ARB,
- GL_INNOCENT_CONTEXT_RESET_ARB);
+ layer_tree_host()->SetNeedsCommit();
+ // No layers need commit.
break;
case 3:
- // With SingleThreadProxy it takes two commits to finally swap after a
- // context loss.
+ layer_tree_host()->SetRootLayer(other_root_);
+ // Layers added to the tree get committed.
+ ++expected_push_properties_other_root_;
+ break;
case 4:
- // The output surface has been recreated.
- EXPECT_TRUE(second_context_provider_.get());
-
- num_textures_after_loss_ =
- first_context_provider_->TestContext3d()->NumTextures();
+ layer_tree_host()->SetRootLayer(root_);
+ // Layers added to the tree get committed.
+ ++expected_push_properties_root_;
+ ++expected_push_properties_child_;
+ ++expected_push_properties_grandchild_;
+ ++expected_push_properties_child2_;
+ break;
+ case 5:
+ layer_tree_host()->SetNeedsCommit();
+ // No layers need commit.
+ break;
+ case 6:
+ child_->RemoveFromParent();
+ // No layers need commit.
+ break;
+ case 7:
+ root_->AddChild(child_);
+ // Layers added to the tree get committed.
+ ++expected_push_properties_child_;
+ ++expected_push_properties_grandchild_;
+ break;
+ case 8:
+ grandchild_->RemoveFromParent();
+ // No layers need commit.
+ break;
+ case 9:
+ child_->AddChild(grandchild_);
+ // Layers added to the tree get committed.
+ ++expected_push_properties_grandchild_;
+ break;
+ case 10:
+ layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
+ // No layers need commit.
+ break;
+ case 11:
+ layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
+ // No layers need commit.
+ break;
+ case 12:
+ child_->SetPosition(gfx::Point(1, 1));
+ // The modified layer needs commit
+ ++expected_push_properties_child_;
+ break;
+ case 13:
+ child2_->SetPosition(gfx::Point(1, 1));
+ // The modified layer needs commit
+ ++expected_push_properties_child2_;
+ break;
+ case 14:
+ child_->RemoveFromParent();
+ root_->AddChild(child_);
+ // Layers added to the tree get committed.
+ ++expected_push_properties_child_;
+ ++expected_push_properties_grandchild_;
+ break;
+ case 15:
+ grandchild_->SetPosition(gfx::Point(1, 1));
+ // The modified layer needs commit
+ ++expected_push_properties_grandchild_;
+ break;
+ case 16:
+ // SetNeedsDisplay does not always set needs commit (so call it
+ // explicitly), but is a property change.
+ child_->SetNeedsDisplay();
+ ++expected_push_properties_child_;
+ layer_tree_host()->SetNeedsCommit();
+ break;
+ case 17:
+ EndTest();
break;
}
- }
- void CheckNumTextures(size_t expected_num_textures) {
- EXPECT_EQ(expected_num_textures,
- first_context_provider_->TestContext3d()->NumTextures());
- EndTest();
+ // The leaf layer always pushes.
+ if (leaf_always_pushing_layer_->layer_tree_host())
+ ++expected_push_properties_leaf_layer_;
}
virtual void AfterTest() OVERRIDE {}
- scoped_refptr<TestContextProvider> first_context_provider_;
- scoped_refptr<TestContextProvider> second_context_provider_;
- size_t num_textures_without_readback_;
- size_t num_textures_after_loss_;
+ int num_commits_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
- scoped_refptr<FakeContentLayer> copy_layer_;
- scoped_ptr<CopyOutputResult> result_;
-};
+ scoped_refptr<PushPropertiesCountingLayer> root_;
+ scoped_refptr<PushPropertiesCountingLayer> child_;
+ scoped_refptr<PushPropertiesCountingLayer> child2_;
+ scoped_refptr<PushPropertiesCountingLayer> grandchild_;
+ scoped_refptr<PushPropertiesCountingLayer> other_root_;
+ scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
+ size_t expected_push_properties_root_;
+ size_t expected_push_properties_child_;
+ size_t expected_push_properties_child2_;
+ size_t expected_push_properties_grandchild_;
+ size_t expected_push_properties_other_root_;
+ size_t expected_push_properties_leaf_layer_;
+};
-// No output to copy for delegated renderers.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F(
- LayerTreeHostTestAsyncReadbackLostOutputSurface);
+MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
-class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
- public:
+class LayerTreeHostTestImplLayersPushProperties
+ : public LayerTreeHostTestLayersPushProperties {
+ protected:
virtual void BeginTest() OVERRIDE {
- frame_ = 0;
- PostSetNeedsCommitToMainThread();
+ expected_push_properties_root_impl_ = 0;
+ expected_push_properties_child_impl_ = 0;
+ expected_push_properties_grandchild_impl_ = 0;
+ expected_push_properties_child2_impl_ = 0;
+ expected_push_properties_grandchild2_impl_ = 0;
+ LayerTreeHostTestLayersPushProperties::BeginTest();
}
- // Round 1: commit + draw
- // Round 2: commit only (no draw/swap)
- // Round 3: draw only (no commit)
- // Round 4: composite & readback (2 commits, no draw/swap)
- // Round 5: commit + draw
-
- virtual void DidCommit() OVERRIDE {
- int commit = layer_tree_host()->source_frame_number();
- switch (commit) {
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ // These commits are in response to the changes made in
+ // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame()
+ switch (num_commits_) {
+ case 0:
+ // Tree hasn't been setup yet don't bother to check anything.
+ return;
+ case 1:
+ // Root gets set up, Everyone is initialized.
+ ++expected_push_properties_root_impl_;
+ ++expected_push_properties_child_impl_;
+ ++expected_push_properties_grandchild_impl_;
+ ++expected_push_properties_child2_impl_;
+ ++expected_push_properties_grandchild2_impl_;
+ break;
case 2:
- // Round 2 done.
- EXPECT_EQ(1, frame_);
- layer_tree_host()->SetNeedsRedraw();
+ // Tree doesn't change but the one leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild2_impl_;
break;
case 3:
- // CompositeAndReadback in Round 4, first commit.
- EXPECT_EQ(2, frame_);
- break;
+ // Root is swapped here.
+ // Clear the expected push properties the tree will be rebuilt.
+ expected_push_properties_root_impl_ = 0;
+ expected_push_properties_child_impl_ = 0;
+ expected_push_properties_grandchild_impl_ = 0;
+ expected_push_properties_child2_impl_ = 0;
+ expected_push_properties_grandchild2_impl_ = 0;
+
+ // Make sure the new root is pushed.
+ EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>(
+ host_impl->RootLayer())->push_properties_count());
+ return;
case 4:
- // Round 4 done.
- EXPECT_EQ(2, frame_);
- layer_tree_host()->SetNeedsCommit();
- layer_tree_host()->SetNeedsRedraw();
+ // Root is swapped back all of the layers in the tree get pushed.
+ ++expected_push_properties_root_impl_;
+ ++expected_push_properties_child_impl_;
+ ++expected_push_properties_grandchild_impl_;
+ ++expected_push_properties_child2_impl_;
+ ++expected_push_properties_grandchild2_impl_;
break;
- }
- }
+ case 5:
+ // Tree doesn't change but the one leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild2_impl_;
+ break;
+ case 6:
+ // First child is removed. Structure of the tree changes here so swap
+ // some of the values. child_impl becomes child2_impl.
+ expected_push_properties_child_impl_ =
+ expected_push_properties_child2_impl_;
+ expected_push_properties_child2_impl_ = 0;
+ // grandchild_impl becomes grandchild2_impl.
+ expected_push_properties_grandchild_impl_ =
+ expected_push_properties_grandchild2_impl_;
+ expected_push_properties_grandchild2_impl_ = 0;
+
+ // grandchild_impl is now the leaf that always pushes. It is pushed.
+ ++expected_push_properties_grandchild_impl_;
+ break;
+ case 7:
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
- virtual void DidCompleteSwapBuffers() OVERRIDE {
- int commit = layer_tree_host()->source_frame_number();
- ++frame_;
- char pixels[4] = {0};
- switch (frame_) {
- case 1:
- // Round 1 done.
- EXPECT_EQ(1, commit);
- layer_tree_host()->SetNeedsCommit();
+ // Child is added back. New layers are initialized.
+ ++expected_push_properties_grandchild2_impl_;
+ ++expected_push_properties_child2_impl_;
break;
- case 2:
- // Round 3 done.
- EXPECT_EQ(2, commit);
- layer_tree_host()->CompositeAndReadback(pixels, gfx::Rect(0, 0, 1, 1));
+ case 8:
+ // Leaf is removed.
+ expected_push_properties_grandchild2_impl_ = 0;
+
+ // Always pushing.
+ ++expected_push_properties_grandchild_impl_;
break;
- case 3:
- // Round 5 done.
- EXPECT_EQ(5, commit);
- EndTest();
+ case 9:
+ // Leaf is added back
+ ++expected_push_properties_grandchild2_impl_;
+
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
break;
- }
- }
+ case 10:
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
+ break;
+ case 11:
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
+ break;
+ case 12:
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
- virtual void AfterTest() OVERRIDE {}
+ // This child position was changed.
+ ++expected_push_properties_child2_impl_;
+ break;
+ case 13:
+ // The position of this child was changed.
+ ++expected_push_properties_child_impl_;
- protected:
- int frame_;
-};
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
+ break;
+ case 14:
+ // Second child is removed from tree. Don't discard counts because
+ // they are added back before commit.
-TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
- RunTest(true, true, true);
-}
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
-TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
- RunTest(true, false, true);
-}
+ // Second child added back.
+ ++expected_push_properties_child2_impl_;
+ ++expected_push_properties_grandchild2_impl_;
-class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest {
- public:
- virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- // PictureLayer can only be used with impl side painting enabled.
- settings->impl_side_painting = true;
- }
+ break;
+ case 15:
+ // The position of this child was changed.
+ ++expected_push_properties_grandchild2_impl_;
- virtual void SetupTree() OVERRIDE {
- layer_ = FakePictureLayer::Create(&client_);
- // Force commits to not be aborted so new frames get drawn, otherwise
- // the renderer gets deferred initialized but nothing new needs drawing.
- layer_->set_always_update_resources(true);
- layer_tree_host()->SetRootLayer(layer_);
- LayerTreeHostTest::SetupTree();
- }
+ // The leaf that always pushes is pushed.
+ ++expected_push_properties_grandchild_impl_;
+ break;
+ case 16:
+ // Second child is invalidated with SetNeedsDisplay
+ ++expected_push_properties_child2_impl_;
- virtual void BeginTest() OVERRIDE {
- did_initialize_gl_ = false;
- did_release_gl_ = false;
- last_source_frame_number_drawn_ = -1; // Never drawn.
- PostSetNeedsCommitToMainThread();
- }
+ // The leaf that always pushed is pushed.
+ ++expected_push_properties_grandchild_impl_;
+ break;
+ }
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
- OVERRIDE {
- scoped_ptr<TestWebGraphicsContext3D> context3d(
- TestWebGraphicsContext3D::Create());
- context3d->set_support_swapbuffers_complete_callback(false);
+ PushPropertiesCountingLayerImpl* root_impl_ = NULL;
+ PushPropertiesCountingLayerImpl* child_impl_ = NULL;
+ PushPropertiesCountingLayerImpl* child2_impl_ = NULL;
+ PushPropertiesCountingLayerImpl* grandchild_impl_ = NULL;
+ PushPropertiesCountingLayerImpl* leaf_always_pushing_layer_impl_ = NULL;
- return FakeOutputSurface::CreateDeferredGL(
- scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice))
- .PassAs<OutputSurface>();
- }
+ // Pull the layers that we need from the tree assuming the same structure
+ // as LayerTreeHostTestLayersPushProperties
+ root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
+ host_impl->RootLayer());
- virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- ASSERT_TRUE(host_impl->RootLayer());
- FakePictureLayerImpl* layer_impl =
- static_cast<FakePictureLayerImpl*>(host_impl->RootLayer());
+ if (root_impl_ && root_impl_->children().size() > 0) {
+ child_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
+ root_impl_->children()[0]);
- // The same frame can be draw multiple times if new visible tiles are
- // rasterized. But we want to make sure we only post DeferredInitialize
- // and ReleaseGL once, so early out if the same frame is drawn again.
- if (last_source_frame_number_drawn_ ==
- host_impl->active_tree()->source_frame_number())
- return;
+ if (child_impl_ && child_impl_->children().size() > 0)
+ grandchild_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
+ child_impl_->children()[0]);
+ }
- last_source_frame_number_drawn_ =
- host_impl->active_tree()->source_frame_number();
+ if (root_impl_ && root_impl_->children().size() > 1) {
+ child2_impl_ = static_cast<PushPropertiesCountingLayerImpl*>(
+ root_impl_->children()[1]);
- if (!did_initialize_gl_) {
- EXPECT_LE(1u, layer_impl->append_quads_count());
- ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(
- &LayerTreeHostTestDeferredInitialize::DeferredInitializeAndRedraw,
- base::Unretained(this),
- base::Unretained(host_impl)));
- } else if (did_initialize_gl_ && !did_release_gl_) {
- EXPECT_LE(2u, layer_impl->append_quads_count());
- ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(
- &LayerTreeHostTestDeferredInitialize::ReleaseGLAndRedraw,
- base::Unretained(this),
- base::Unretained(host_impl)));
- } else if (did_initialize_gl_ && did_release_gl_) {
- EXPECT_LE(3u, layer_impl->append_quads_count());
- EndTest();
+ if (child2_impl_ && child2_impl_->children().size() > 0)
+ leaf_always_pushing_layer_impl_ =
+ static_cast<PushPropertiesCountingLayerImpl*>(
+ child2_impl_->children()[0]);
}
- }
- void DeferredInitializeAndRedraw(LayerTreeHostImpl* host_impl) {
- EXPECT_FALSE(did_initialize_gl_);
- // SetAndInitializeContext3D calls SetNeedsCommit.
- FakeOutputSurface* fake_output_surface =
- static_cast<FakeOutputSurface*>(host_impl->output_surface());
- scoped_refptr<TestContextProvider> context_provider =
- TestContextProvider::Create(); // Not bound to thread.
- EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d(
- context_provider, NULL));
- did_initialize_gl_ = true;
- }
+ if (root_impl_)
+ EXPECT_EQ(expected_push_properties_root_impl_,
+ root_impl_->push_properties_count());
+ if (child_impl_)
+ EXPECT_EQ(expected_push_properties_child_impl_,
+ child_impl_->push_properties_count());
+ if (grandchild_impl_)
+ EXPECT_EQ(expected_push_properties_grandchild_impl_,
+ grandchild_impl_->push_properties_count());
+ if (child2_impl_)
+ EXPECT_EQ(expected_push_properties_child2_impl_,
+ child2_impl_->push_properties_count());
+ if (leaf_always_pushing_layer_impl_)
+ EXPECT_EQ(expected_push_properties_grandchild2_impl_,
+ leaf_always_pushing_layer_impl_->push_properties_count());
+ }
+
+ size_t expected_push_properties_root_impl_;
+ size_t expected_push_properties_child_impl_;
+ size_t expected_push_properties_child2_impl_;
+ size_t expected_push_properties_grandchild_impl_;
+ size_t expected_push_properties_grandchild2_impl_;
+};
- void ReleaseGLAndRedraw(LayerTreeHostImpl* host_impl) {
- EXPECT_TRUE(did_initialize_gl_);
- EXPECT_FALSE(did_release_gl_);
- // ReleaseGL calls SetNeedsCommit.
- static_cast<FakeOutputSurface*>(host_impl->output_surface())->ReleaseGL();
- did_release_gl_ = true;
- }
+TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) {
+ RunTestWithImplSidePainting();
+}
- virtual void AfterTest() OVERRIDE {
- EXPECT_TRUE(did_initialize_gl_);
- EXPECT_TRUE(did_release_gl_);
- }
+class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
+ : public LayerTreeHostTest {
+ protected:
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- private:
- FakeContentLayerClient client_;
- scoped_refptr<FakePictureLayer> layer_;
- bool did_initialize_gl_;
- bool did_release_gl_;
- int last_source_frame_number_drawn_;
-};
+ virtual void SetupTree() OVERRIDE {
+ root_ = Layer::Create();
+ root_->SetBounds(gfx::Size(1, 1));
-MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize);
+ bool paint_scrollbar = true;
+ bool has_thumb = false;
+ scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
+ paint_scrollbar, has_thumb, root_->id());
-// Test for UI Resource management.
-class LayerTreeHostTestUIResource : public LayerTreeHostTest {
- public:
- LayerTreeHostTestUIResource() : num_ui_resources_(0), num_commits_(0) {}
+ root_->AddChild(scrollbar_layer_);
- virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->texture_id_allocation_chunk_size = 1;
+ layer_tree_host()->SetRootLayer(root_);
+ LayerTreeHostTest::SetupTree();
}
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 0:
+ break;
+ case 1: {
+ // During update, the ignore_set_needs_commit_ bit is set to true to
+ // avoid causing a second commit to be scheduled. If a property change
+ // is made during this, however, it needs to be pushed in the upcoming
+ // commit.
+ scoped_ptr<base::AutoReset<bool> > ignore =
+ scrollbar_layer_->IgnoreSetNeedsCommit();
- virtual void DidCommit() OVERRIDE {
- int frame = num_commits_;
- switch (frame) {
- case 1:
- CreateResource();
- CreateResource();
- PostSetNeedsCommitToMainThread();
+ scrollbar_layer_->SetBounds(gfx::Size(30, 30));
+
+ EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ layer_tree_host()->SetNeedsCommit();
+
+ scrollbar_layer_->reset_push_properties_count();
+ EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
break;
+ }
case 2:
- // Usually ScopedUIResource are deleted from the manager in their
- // destructor. Here we just want to test that a direct call to
- // DeleteUIResource works.
- layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
- PostSetNeedsCommitToMainThread();
- break;
- case 3:
- // DeleteUIResource can be called with an invalid id.
- layer_tree_host()->DeleteUIResource(ui_resources_[0]->id());
- PostSetNeedsCommitToMainThread();
- break;
- case 4:
- CreateResource();
- CreateResource();
- PostSetNeedsCommitToMainThread();
- break;
- case 5:
- ClearResources();
+ EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
EndTest();
break;
}
}
- void PerformTest(LayerTreeHostImpl* impl) {
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ virtual void AfterTest() OVERRIDE {}
- int frame = num_commits_;
- switch (frame) {
- case 1:
- ASSERT_EQ(0u, context->NumTextures());
- break;
- case 2:
- // Created two textures.
- ASSERT_EQ(2u, context->NumTextures());
- break;
- case 3:
- // One texture left after one deletion.
- ASSERT_EQ(1u, context->NumTextures());
- break;
- case 4:
- // Resource manager state should not change when delete is called on an
- // invalid id.
- ASSERT_EQ(1u, context->NumTextures());
- break;
- case 5:
- // Creation after deletion: two more creates should total up to
- // three textures.
- ASSERT_EQ(3u, context->NumTextures());
- break;
- }
- }
-
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- ++num_commits_;
- if (!layer_tree_host()->settings().impl_side_painting)
- PerformTest(impl);
- }
-
- virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- if (layer_tree_host()->settings().impl_side_painting)
- PerformTest(impl);
- }
-
- virtual void AfterTest() OVERRIDE {}
-
- private:
- // Must clear all resources before exiting.
- void ClearResources() {
- for (int i = 0; i < num_ui_resources_; i++)
- ui_resources_[i].reset();
- }
-
- void CreateResource() {
- ui_resources_[num_ui_resources_++] =
- FakeScopedUIResource::Create(layer_tree_host());
- }
-
- scoped_ptr<FakeScopedUIResource> ui_resources_[5];
- int num_ui_resources_;
- int num_commits_;
+ scoped_refptr<Layer> root_;
+ scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource);
-
-class PushPropertiesCountingLayer : public Layer {
- public:
- static scoped_refptr<PushPropertiesCountingLayer> Create() {
- return new PushPropertiesCountingLayer();
- }
-
- virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE {
- Layer::PushPropertiesTo(layer);
- push_properties_count_++;
- if (persist_needs_push_properties_)
- needs_push_properties_ = true;
- }
-
- size_t push_properties_count() const { return push_properties_count_; }
- void reset_push_properties_count() { push_properties_count_ = 0; }
-
- void set_persist_needs_push_properties(bool persist) {
- persist_needs_push_properties_ = persist;
- }
-
- private:
- PushPropertiesCountingLayer()
- : push_properties_count_(0),
- persist_needs_push_properties_(false) {
- SetAnchorPoint(gfx::PointF());
- SetBounds(gfx::Size(1, 1));
- SetIsDrawable(true);
- }
- virtual ~PushPropertiesCountingLayer() {}
-
- size_t push_properties_count_;
- bool persist_needs_push_properties_;
-};
+MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
-class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest {
+class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
+ : public LayerTreeHostTest {
protected:
virtual void BeginTest() OVERRIDE {
- num_commits_ = 0;
expected_push_properties_root_ = 0;
expected_push_properties_child_ = 0;
- expected_push_properties_grandchild_ = 0;
- expected_push_properties_child2_ = 0;
- expected_push_properties_other_root_ = 0;
- expected_push_properties_leaf_layer_ = 0;
+ expected_push_properties_grandchild1_ = 0;
+ expected_push_properties_grandchild2_ = 0;
+ expected_push_properties_grandchild3_ = 0;
PostSetNeedsCommitToMainThread();
}
virtual void SetupTree() OVERRIDE {
root_ = PushPropertiesCountingLayer::Create();
child_ = PushPropertiesCountingLayer::Create();
- child2_ = PushPropertiesCountingLayer::Create();
- grandchild_ = PushPropertiesCountingLayer::Create();
- leaf_always_pushing_layer_ = PushPropertiesCountingLayer::Create();
- leaf_always_pushing_layer_->set_persist_needs_push_properties(true);
+ grandchild1_ = PushPropertiesCountingLayer::Create();
+ grandchild2_ = PushPropertiesCountingLayer::Create();
+ grandchild3_ = PushPropertiesCountingLayer::Create();
root_->AddChild(child_);
- root_->AddChild(child2_);
- child_->AddChild(grandchild_);
- child2_->AddChild(leaf_always_pushing_layer_);
-
- other_root_ = PushPropertiesCountingLayer::Create();
+ child_->AddChild(grandchild1_);
+ child_->AddChild(grandchild2_);
+ child_->AddChild(grandchild3_);
// Don't set the root layer here.
LayerTreeHostTest::SetupTree();
}
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- ++num_commits_;
-
- EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count());
- EXPECT_EQ(expected_push_properties_child_, child_->push_properties_count());
- EXPECT_EQ(expected_push_properties_grandchild_,
- grandchild_->push_properties_count());
- EXPECT_EQ(expected_push_properties_child2_,
- child2_->push_properties_count());
- EXPECT_EQ(expected_push_properties_other_root_,
- other_root_->push_properties_count());
- EXPECT_EQ(expected_push_properties_leaf_layer_,
- leaf_always_pushing_layer_->push_properties_count());
-
- // The scrollbar layer always needs to be pushed.
- if (root_->layer_tree_host()) {
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(root_->needs_push_properties());
- }
- if (child2_->layer_tree_host()) {
- EXPECT_TRUE(child2_->descendant_needs_push_properties());
- EXPECT_FALSE(child2_->needs_push_properties());
- }
- if (leaf_always_pushing_layer_->layer_tree_host()) {
- EXPECT_FALSE(
- leaf_always_pushing_layer_->descendant_needs_push_properties());
- EXPECT_TRUE(leaf_always_pushing_layer_->needs_push_properties());
- }
-
- // child_ and grandchild_ don't persist their need to push properties.
- if (child_->layer_tree_host()) {
- EXPECT_FALSE(child_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- }
- if (grandchild_->layer_tree_host()) {
- EXPECT_FALSE(grandchild_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild_->needs_push_properties());
- }
+ virtual void AfterTest() OVERRIDE {}
- if (other_root_->layer_tree_host()) {
- EXPECT_FALSE(other_root_->descendant_needs_push_properties());
- EXPECT_FALSE(other_root_->needs_push_properties());
- }
+ FakeContentLayerClient client_;
+ scoped_refptr<PushPropertiesCountingLayer> root_;
+ scoped_refptr<PushPropertiesCountingLayer> child_;
+ scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
+ scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
+ scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
+ size_t expected_push_properties_root_;
+ size_t expected_push_properties_child_;
+ size_t expected_push_properties_grandchild1_;
+ size_t expected_push_properties_grandchild2_;
+ size_t expected_push_properties_grandchild3_;
+};
- switch (num_commits_) {
- case 1:
- layer_tree_host()->SetRootLayer(root_);
- // Layers added to the tree get committed.
- ++expected_push_properties_root_;
- ++expected_push_properties_child_;
- ++expected_push_properties_grandchild_;
- ++expected_push_properties_child2_;
- break;
- case 2:
- layer_tree_host()->SetNeedsCommit();
- // No layers need commit.
- break;
- case 3:
- layer_tree_host()->SetRootLayer(other_root_);
- // Layers added to the tree get committed.
- ++expected_push_properties_other_root_;
- break;
- case 4:
- layer_tree_host()->SetRootLayer(root_);
- // Layers added to the tree get committed.
- ++expected_push_properties_root_;
- ++expected_push_properties_child_;
- ++expected_push_properties_grandchild_;
- ++expected_push_properties_child2_;
- break;
- case 5:
- layer_tree_host()->SetNeedsCommit();
- // No layers need commit.
- break;
- case 6:
- child_->RemoveFromParent();
- // No layers need commit.
- break;
- case 7:
- root_->AddChild(child_);
- // Layers added to the tree get committed.
- ++expected_push_properties_child_;
- ++expected_push_properties_grandchild_;
- break;
- case 8:
- grandchild_->RemoveFromParent();
- // No layers need commit.
- break;
- case 9:
- child_->AddChild(grandchild_);
- // Layers added to the tree get committed.
- ++expected_push_properties_grandchild_;
- break;
- case 10:
- layer_tree_host()->SetViewportSize(gfx::Size(20, 20));
- // No layers need commit.
- break;
- case 11:
- layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.8f, 1.1f);
- // No layers need commit.
- break;
- case 12:
- child_->SetPosition(gfx::Point(1, 1));
- // The modified layer needs commit
- ++expected_push_properties_child_;
- break;
- case 13:
- child2_->SetPosition(gfx::Point(1, 1));
- // The modified layer needs commit
- ++expected_push_properties_child2_;
- break;
- case 14:
- child_->RemoveFromParent();
- root_->AddChild(child_);
- // Layers added to the tree get committed.
- ++expected_push_properties_child_;
- ++expected_push_properties_grandchild_;
- break;
- case 15:
- grandchild_->SetPosition(gfx::Point(1, 1));
- // The modified layer needs commit
- ++expected_push_properties_grandchild_;
- break;
- case 16:
- // SetNeedsDisplay does not always set needs commit (so call it
- // explicitly), but is a property change.
- child_->SetNeedsDisplay();
- ++expected_push_properties_child_;
- layer_tree_host()->SetNeedsCommit();
+class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
+ : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
+ protected:
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
+ switch (last_source_frame_number) {
+ case 0:
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+
+ layer_tree_host()->SetRootLayer(root_);
+
+ EXPECT_TRUE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
break;
- case 17:
+ case 1:
EndTest();
break;
}
-
- // The leaf layer always pushes.
- if (leaf_always_pushing_layer_->layer_tree_host())
- ++expected_push_properties_leaf_layer_;
}
-
- virtual void AfterTest() OVERRIDE {}
-
- int num_commits_;
- FakeContentLayerClient client_;
- scoped_refptr<PushPropertiesCountingLayer> root_;
- scoped_refptr<PushPropertiesCountingLayer> child_;
- scoped_refptr<PushPropertiesCountingLayer> child2_;
- scoped_refptr<PushPropertiesCountingLayer> grandchild_;
- scoped_refptr<PushPropertiesCountingLayer> other_root_;
- scoped_refptr<PushPropertiesCountingLayer> leaf_always_pushing_layer_;
- size_t expected_push_properties_root_;
- size_t expected_push_properties_child_;
- size_t expected_push_properties_child2_;
- size_t expected_push_properties_grandchild_;
- size_t expected_push_properties_other_root_;
- size_t expected_push_properties_leaf_layer_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties);
+MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
-class LayerTreeHostTestPropertyChangesDuringUpdateArePushed
- : public LayerTreeHostTest {
+class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
+ : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
protected:
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
+ switch (last_source_frame_number) {
+ case 0:
+ layer_tree_host()->SetRootLayer(root_);
+ break;
+ case 1:
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- virtual void SetupTree() OVERRIDE {
- root_ = Layer::Create();
- root_->SetBounds(gfx::Size(1, 1));
+ grandchild1_->RemoveFromParent();
+ grandchild1_->SetPosition(gfx::Point(1, 1));
- bool paint_scrollbar = true;
- bool has_thumb = false;
- scrollbar_layer_ = FakePaintedScrollbarLayer::Create(
- paint_scrollbar, has_thumb, root_->id());
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- root_->AddChild(scrollbar_layer_);
+ child_->AddChild(grandchild1_);
- layer_tree_host()->SetRootLayer(root_);
- LayerTreeHostTest::SetupTree();
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+
+ grandchild2_->SetPosition(gfx::Point(1, 1));
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+
+ // grandchild2_ will still need a push properties.
+ grandchild1_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+
+ // grandchild3_ does not need a push properties, so recursing should
+ // no longer be needed.
+ grandchild2_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+ EndTest();
+ break;
+ }
}
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
+class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
+ : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
+ protected:
virtual void DidCommitAndDrawFrame() OVERRIDE {
- switch (layer_tree_host()->source_frame_number()) {
+ int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
+ switch (last_source_frame_number) {
case 0:
+ layer_tree_host()->SetRootLayer(root_);
+ grandchild1_->set_persist_needs_push_properties(true);
+ grandchild2_->set_persist_needs_push_properties(true);
break;
- case 1: {
- // During update, the ignore_set_needs_commit_ bit is set to true to
- // avoid causing a second commit to be scheduled. If a property change
- // is made during this, however, it needs to be pushed in the upcoming
- // commit.
- scoped_ptr<base::AutoReset<bool> > ignore =
- scrollbar_layer_->IgnoreSetNeedsCommit();
+ case 1:
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- scrollbar_layer_->SetBounds(gfx::Size(30, 30));
+ // grandchild2_ will still need a push properties.
+ grandchild1_->RemoveFromParent();
- EXPECT_TRUE(scrollbar_layer_->needs_push_properties());
+ EXPECT_FALSE(root_->needs_push_properties());
EXPECT_TRUE(root_->descendant_needs_push_properties());
- layer_tree_host()->SetNeedsCommit();
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
- scrollbar_layer_->reset_push_properties_count();
- EXPECT_EQ(0u, scrollbar_layer_->push_properties_count());
- break;
- }
- case 2:
- EXPECT_EQ(1u, scrollbar_layer_->push_properties_count());
+ // grandchild3_ does not need a push properties, so recursing should
+ // no longer be needed.
+ grandchild2_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
EndTest();
break;
}
}
-
- virtual void AfterTest() OVERRIDE {}
-
- scoped_refptr<Layer> root_;
- scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed);
+MULTI_THREAD_TEST_F(
+ LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
-class LayerTreeHostTestCasePushPropertiesThreeGrandChildren
- : public LayerTreeHostTest {
+class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
+ : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
protected:
- virtual void BeginTest() OVERRIDE {
- expected_push_properties_root_ = 0;
- expected_push_properties_child_ = 0;
- expected_push_properties_grandchild1_ = 0;
- expected_push_properties_grandchild2_ = 0;
- expected_push_properties_grandchild3_ = 0;
- PostSetNeedsCommitToMainThread();
- }
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
+ switch (last_source_frame_number) {
+ case 0:
+ layer_tree_host()->SetRootLayer(root_);
+ break;
+ case 1:
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+ EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- virtual void SetupTree() OVERRIDE {
- root_ = PushPropertiesCountingLayer::Create();
- child_ = PushPropertiesCountingLayer::Create();
- grandchild1_ = PushPropertiesCountingLayer::Create();
- grandchild2_ = PushPropertiesCountingLayer::Create();
- grandchild3_ = PushPropertiesCountingLayer::Create();
+ // Change grandchildren while their parent is not in the tree.
+ child_->RemoveFromParent();
+ grandchild1_->SetPosition(gfx::Point(1, 1));
+ grandchild2_->SetPosition(gfx::Point(1, 1));
+ root_->AddChild(child_);
- root_->AddChild(child_);
- child_->AddChild(grandchild1_);
- child_->AddChild(grandchild2_);
- child_->AddChild(grandchild3_);
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild1_->needs_push_properties());
+ EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild2_->needs_push_properties());
+ EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
+ EXPECT_TRUE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+
+ grandchild1_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+
+ grandchild2_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
- // Don't set the root layer here.
- LayerTreeHostTest::SetupTree();
- }
+ grandchild3_->RemoveFromParent();
- virtual void AfterTest() OVERRIDE {}
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
- FakeContentLayerClient client_;
- scoped_refptr<PushPropertiesCountingLayer> root_;
- scoped_refptr<PushPropertiesCountingLayer> child_;
- scoped_refptr<PushPropertiesCountingLayer> grandchild1_;
- scoped_refptr<PushPropertiesCountingLayer> grandchild2_;
- scoped_refptr<PushPropertiesCountingLayer> grandchild3_;
- size_t expected_push_properties_root_;
- size_t expected_push_properties_child_;
- size_t expected_push_properties_grandchild1_;
- size_t expected_push_properties_grandchild2_;
- size_t expected_push_properties_grandchild3_;
+ EndTest();
+ break;
+ }
+ }
};
-class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush
+MULTI_THREAD_TEST_F(
+ LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
+
+class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
: public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
protected:
virtual void DidCommitAndDrawFrame() OVERRIDE {
int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
switch (last_source_frame_number) {
case 0:
+ layer_tree_host()->SetRootLayer(root_);
+ break;
+ case 1:
EXPECT_FALSE(root_->needs_push_properties());
EXPECT_FALSE(root_->descendant_needs_push_properties());
EXPECT_FALSE(child_->needs_push_properties());
EXPECT_FALSE(grandchild3_->needs_push_properties());
EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- layer_tree_host()->SetRootLayer(root_);
+ child_->SetPosition(gfx::Point(1, 1));
+ grandchild1_->SetPosition(gfx::Point(1, 1));
+ grandchild2_->SetPosition(gfx::Point(1, 1));
- EXPECT_TRUE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->needs_push_properties());
EXPECT_TRUE(root_->descendant_needs_push_properties());
EXPECT_TRUE(child_->needs_push_properties());
EXPECT_TRUE(child_->descendant_needs_push_properties());
EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
EXPECT_TRUE(grandchild2_->needs_push_properties());
EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild3_->needs_push_properties());
+ EXPECT_FALSE(grandchild3_->needs_push_properties());
EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- break;
- case 1:
+
+ grandchild1_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->descendant_needs_push_properties());
+
+ grandchild2_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+
+ child_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+
EndTest();
break;
}
}
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush);
+MULTI_THREAD_TEST_F(
+ LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
-class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion
+class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
: public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
protected:
virtual void DidCommitAndDrawFrame() OVERRIDE {
EXPECT_FALSE(grandchild3_->needs_push_properties());
EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- grandchild1_->RemoveFromParent();
grandchild1_->SetPosition(gfx::Point(1, 1));
-
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
-
- child_->AddChild(grandchild1_);
+ grandchild2_->SetPosition(gfx::Point(1, 1));
+ child_->SetPosition(gfx::Point(1, 1));
EXPECT_FALSE(root_->needs_push_properties());
EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
EXPECT_TRUE(child_->descendant_needs_push_properties());
EXPECT_TRUE(grandchild1_->needs_push_properties());
EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild2_->needs_push_properties());
+ EXPECT_TRUE(grandchild2_->needs_push_properties());
EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
EXPECT_FALSE(grandchild3_->needs_push_properties());
EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- grandchild2_->SetPosition(gfx::Point(1, 1));
+ grandchild1_->RemoveFromParent();
EXPECT_FALSE(root_->needs_push_properties());
EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
EXPECT_TRUE(child_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
- // grandchild2_ will still need a push properties.
- grandchild1_->RemoveFromParent();
+ grandchild2_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_TRUE(root_->descendant_needs_push_properties());
+ EXPECT_TRUE(child_->needs_push_properties());
+ EXPECT_FALSE(child_->descendant_needs_push_properties());
+
+ child_->RemoveFromParent();
+
+ EXPECT_FALSE(root_->needs_push_properties());
+ EXPECT_FALSE(root_->descendant_needs_push_properties());
+
+ EndTest();
+ break;
+ }
+ }
+};
+
+MULTI_THREAD_TEST_F(
+ LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
+
+// This test verifies that the tree activation callback is invoked correctly.
+class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestTreeActivationCallback()
+ : num_commits_(0), callback_count_(0) {}
+
+ virtual void BeginTest() OVERRIDE {
+ EXPECT_TRUE(HasImplThread());
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
+ ++num_commits_;
+ switch (num_commits_) {
+ case 1:
+ EXPECT_EQ(0, callback_count_);
+ callback_count_ = 0;
+ SetCallback(true);
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 2:
+ EXPECT_EQ(1, callback_count_);
+ callback_count_ = 0;
+ SetCallback(false);
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 3:
+ EXPECT_EQ(0, callback_count_);
+ callback_count_ = 0;
+ EndTest();
+ break;
+ default:
+ ADD_FAILURE() << num_commits_;
+ EndTest();
+ break;
+ }
+ return LayerTreeHostTest::PrepareToDrawOnThread(
+ host_impl, frame_data, draw_result);
+ }
+
+ virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); }
+
+ void SetCallback(bool enable) {
+ output_surface()->SetTreeActivationCallback(
+ enable
+ ? base::Bind(
+ &LayerTreeHostTestTreeActivationCallback::ActivationCallback,
+ base::Unretained(this))
+ : base::Closure());
+ }
+
+ void ActivationCallback() { ++callback_count_; }
+
+ int num_commits_;
+ int callback_count_;
+};
+
+TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
+ RunTest(true, true, true);
+}
+
+class LayerInvalidateCausesDraw : public LayerTreeHostTest {
+ public:
+ LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
+
+ virtual void BeginTest() OVERRIDE {
+ ASSERT_TRUE(!!invalidate_layer_)
+ << "Derived tests must set this in SetupTree";
+
+ // One initial commit.
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ // After commit, invalidate the layer. This should cause a commit.
+ if (layer_tree_host()->source_frame_number() == 1)
+ invalidate_layer_->SetNeedsDisplay();
+ }
+
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ num_draws_++;
+ if (impl->active_tree()->source_frame_number() == 1)
+ EndTest();
+ }
+
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ num_commits_++;
+ }
+
+ virtual void AfterTest() OVERRIDE {
+ EXPECT_GE(2, num_commits_);
+ EXPECT_GE(2, num_draws_);
+ }
+
+ protected:
+ scoped_refptr<Layer> invalidate_layer_;
+
+ private:
+ int num_commits_;
+ int num_draws_;
+};
+
+// VideoLayer must support being invalidated and then passing that along
+// to the compositor thread, even though no resources are updated in
+// response to that invalidation.
+class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
+ public:
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostTest::SetupTree();
+ scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
+ video_layer->SetBounds(gfx::Size(10, 10));
+ video_layer->SetIsDrawable(true);
+ layer_tree_host()->root_layer()->AddChild(video_layer);
+
+ invalidate_layer_ = video_layer;
+ }
+
+ private:
+ FakeVideoFrameProvider provider_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
+
+// IOSurfaceLayer must support being invalidated and then passing that along
+// to the compositor thread, even though no resources are updated in
+// response to that invalidation.
+class LayerTreeHostTestIOSurfaceLayerInvalidate
+ : public LayerInvalidateCausesDraw {
+ public:
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostTest::SetupTree();
+ scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
+ layer->SetBounds(gfx::Size(10, 10));
+ uint32_t fake_io_surface_id = 7;
+ layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
+ layer->SetIsDrawable(true);
+ layer_tree_host()->root_layer()->AddChild(layer);
+
+ invalidate_layer_ = layer;
+ }
+};
+
+// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
+SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
+ LayerTreeHostTestIOSurfaceLayerInvalidate);
+
+class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
+ protected:
+ virtual void SetupTree() OVERRIDE {
+ root_layer_ = Layer::Create();
+ root_layer_->SetAnchorPoint(gfx::PointF());
+ root_layer_->SetPosition(gfx::Point());
+ root_layer_->SetBounds(gfx::Size(10, 10));
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
+ parent_layer_ = SolidColorLayer::Create();
+ parent_layer_->SetAnchorPoint(gfx::PointF());
+ parent_layer_->SetPosition(gfx::Point());
+ parent_layer_->SetBounds(gfx::Size(10, 10));
+ parent_layer_->SetIsDrawable(true);
+ root_layer_->AddChild(parent_layer_);
- // grandchild3_ does not need a push properties, so recursing should
- // no longer be needed.
- grandchild2_->RemoveFromParent();
+ child_layer_ = SolidColorLayer::Create();
+ child_layer_->SetAnchorPoint(gfx::PointF());
+ child_layer_->SetPosition(gfx::Point());
+ child_layer_->SetBounds(gfx::Size(10, 10));
+ child_layer_->SetIsDrawable(true);
+ parent_layer_->AddChild(child_layer_);
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
- EndTest();
- break;
- }
+ layer_tree_host()->SetRootLayer(root_layer_);
+ LayerTreeHostTest::SetupTree();
}
-};
-MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion);
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
-class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
- protected:
virtual void DidCommitAndDrawFrame() OVERRIDE {
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
- switch (last_source_frame_number) {
- case 0:
- layer_tree_host()->SetRootLayer(root_);
- grandchild1_->set_persist_needs_push_properties(true);
- grandchild2_->set_persist_needs_push_properties(true);
- break;
+ switch (layer_tree_host()->source_frame_number()) {
case 1:
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
-
- // grandchild2_ will still need a push properties.
- grandchild1_->RemoveFromParent();
-
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
+ // The layer type used does not need to push properties every frame.
+ EXPECT_FALSE(child_layer_->needs_push_properties());
- // grandchild3_ does not need a push properties, so recursing should
- // no longer be needed.
- grandchild2_->RemoveFromParent();
+ // Change the bounds of the child layer, but make it skipped
+ // by CalculateDrawProperties.
+ parent_layer_->SetOpacity(0.f);
+ child_layer_->SetBounds(gfx::Size(5, 5));
+ break;
+ case 2:
+ // The bounds of the child layer were pushed to the impl side.
+ EXPECT_FALSE(child_layer_->needs_push_properties());
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
EndTest();
break;
}
}
-};
-MULTI_THREAD_TEST_F(
- LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence);
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ LayerImpl* root = impl->active_tree()->root_layer();
+ LayerImpl* parent = root->children()[0];
+ LayerImpl* child = parent->children()[0];
-class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
- protected:
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
- switch (last_source_frame_number) {
- case 0:
- layer_tree_host()->SetRootLayer(root_);
- break;
+ switch (impl->active_tree()->source_frame_number()) {
case 1:
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
-
- // Change grandchildren while their parent is not in the tree.
- child_->RemoveFromParent();
- grandchild1_->SetPosition(gfx::Point(1, 1));
- grandchild2_->SetPosition(gfx::Point(1, 1));
- root_->AddChild(child_);
-
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+ EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
+ break;
+ }
+ }
- grandchild1_->RemoveFromParent();
+ virtual void AfterTest() OVERRIDE {}
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
+ scoped_refptr<Layer> root_layer_;
+ scoped_refptr<SolidColorLayer> parent_layer_;
+ scoped_refptr<SolidColorLayer> child_layer_;
+};
- grandchild2_->RemoveFromParent();
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
+class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
+ protected:
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->impl_side_painting = true;
+ }
- grandchild3_->RemoveFromParent();
+ virtual void SetupTree() OVERRIDE {
+ root_layer_ = FakePictureLayer::Create(&client_);
+ root_layer_->SetAnchorPoint(gfx::PointF());
+ root_layer_->SetBounds(gfx::Size(10, 10));
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
+ layer_tree_host()->SetRootLayer(root_layer_);
+ LayerTreeHostTest::SetupTree();
+ }
- EndTest();
- break;
- }
+ virtual void BeginTest() OVERRIDE {
+ // The viewport is empty, but we still need to update layers on the main
+ // thread.
+ layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
+ PostSetNeedsCommitToMainThread();
}
-};
-MULTI_THREAD_TEST_F(
- LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree);
+ virtual void DidCommit() OVERRIDE {
+ // The layer should be updated even though the viewport is empty, so we
+ // are capable of drawing it on the impl tree.
+ EXPECT_GT(root_layer_->update_count(), 0u);
+ EndTest();
+ }
-class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
- protected:
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
- switch (last_source_frame_number) {
- case 0:
- layer_tree_host()->SetRootLayer(root_);
- break;
- case 1:
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+ virtual void AfterTest() OVERRIDE {}
- child_->SetPosition(gfx::Point(1, 1));
- grandchild1_->SetPosition(gfx::Point(1, 1));
- grandchild2_->SetPosition(gfx::Point(1, 1));
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> root_layer_;
+};
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
- grandchild1_->RemoveFromParent();
+class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestAbortEvictedTextures()
+ : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
+ protected:
+ virtual void SetupTree() OVERRIDE {
+ scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
+ root_layer->SetBounds(gfx::Size(200, 200));
+ root_layer->SetIsDrawable(true);
- grandchild2_->RemoveFromParent();
+ layer_tree_host()->SetRootLayer(root_layer);
+ LayerTreeHostTest::SetupTree();
+ }
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- child_->RemoveFromParent();
+ virtual void WillBeginMainFrame() OVERRIDE {
+ num_will_begin_main_frames_++;
+ switch (num_will_begin_main_frames_) {
+ case 2:
+ // Send a redraw to the compositor thread. This will (wrongly) be
+ // ignored unless aborting resets the texture state.
+ layer_tree_host()->SetNeedsRedraw();
+ break;
+ }
+ }
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
+ virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ num_impl_commits_++;
+ }
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ switch (impl->SourceAnimationFrameNumber()) {
+ case 1:
+ // Prevent draws until commit.
+ impl->active_tree()->SetContentsTexturesPurged();
+ EXPECT_FALSE(impl->CanDraw());
+ // Trigger an abortable commit.
+ impl->SetNeedsCommit();
+ break;
+ case 2:
EndTest();
break;
}
}
+
+ virtual void AfterTest() OVERRIDE {
+ // Ensure that the commit was truly aborted.
+ EXPECT_EQ(2, num_will_begin_main_frames_);
+ EXPECT_EQ(1, num_impl_commits_);
+ }
+
+ private:
+ int num_will_begin_main_frames_;
+ int num_impl_commits_;
};
-MULTI_THREAD_TEST_F(
- LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild);
+// Commits can only be aborted when using the thread proxy.
+MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
-class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent
- : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren {
+class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
protected:
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- int last_source_frame_number = layer_tree_host()->source_frame_number() - 1;
- switch (last_source_frame_number) {
- case 0:
- layer_tree_host()->SetRootLayer(root_);
- break;
- case 1:
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
- EXPECT_FALSE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
-
- grandchild1_->SetPosition(gfx::Point(1, 1));
- grandchild2_->SetPosition(gfx::Point(1, 1));
- child_->SetPosition(gfx::Point(1, 1));
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->impl_side_painting = true;
+ }
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild1_->needs_push_properties());
- EXPECT_FALSE(grandchild1_->descendant_needs_push_properties());
- EXPECT_TRUE(grandchild2_->needs_push_properties());
- EXPECT_FALSE(grandchild2_->descendant_needs_push_properties());
- EXPECT_FALSE(grandchild3_->needs_push_properties());
- EXPECT_FALSE(grandchild3_->descendant_needs_push_properties());
+ virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
+ OVERRIDE {
+ scoped_refptr<TestContextProvider> context_provider =
+ TestContextProvider::Create();
+ context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
+ if (delegating_renderer())
+ return FakeOutputSurface::CreateDelegating3d(context_provider);
+ else
+ return FakeOutputSurface::Create3d(context_provider);
+ }
- grandchild1_->RemoveFromParent();
+ virtual void SetupTree() OVERRIDE {
+ scoped_refptr<FakePictureLayer> root_layer =
+ FakePictureLayer::Create(&client_);
+ root_layer->SetBounds(gfx::Size(6000, 6000));
+ root_layer->SetIsDrawable(true);
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_TRUE(child_->descendant_needs_push_properties());
+ layer_tree_host()->SetRootLayer(root_layer);
+ LayerTreeHostTest::SetupTree();
+ }
- grandchild2_->RemoveFromParent();
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_TRUE(root_->descendant_needs_push_properties());
- EXPECT_TRUE(child_->needs_push_properties());
- EXPECT_FALSE(child_->descendant_needs_push_properties());
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ TestWebGraphicsContext3D* context = TestContext();
- child_->RemoveFromParent();
+ // Expect that the transfer buffer memory used is equal to the
+ // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
+ EXPECT_EQ(1024 * 1024u, context->GetTransferBufferMemoryUsedBytes());
+ EndTest();
+ }
- EXPECT_FALSE(root_->needs_push_properties());
- EXPECT_FALSE(root_->descendant_needs_push_properties());
+ virtual void AfterTest() OVERRIDE {}
- EndTest();
- break;
- }
- }
+ private:
+ FakeContentLayerClient client_;
};
-MULTI_THREAD_TEST_F(
- LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent);
+// Impl-side painting is a multi-threaded compositor feature.
+MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
-// This test verifies that the tree activation callback is invoked correctly.
-class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest {
+// Test ensuring that memory limits are sent to the prioritized resource
+// manager.
+class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
public:
- LayerTreeHostTestTreeActivationCallback()
- : num_commits_(0), callback_count_(0) {}
+ LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
- virtual void BeginTest() OVERRIDE {
- EXPECT_TRUE(HasImplThread());
- PostSetNeedsCommitToMainThread();
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void WillCommit() OVERRIDE {
+ // Some commits are aborted, so increment number of attempted commits here.
+ num_commits_++;
}
- virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- bool result) OVERRIDE {
- ++num_commits_;
+ virtual void DidCommit() OVERRIDE {
switch (num_commits_) {
case 1:
- EXPECT_EQ(0, callback_count_);
- callback_count_ = 0;
- SetCallback(true);
+ // Verify default values.
+ EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
+ layer_tree_host()
+ ->contents_texture_manager()
+ ->MaxMemoryLimitBytes());
+ EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
+ layer_tree_host()
+ ->contents_texture_manager()
+ ->ExternalPriorityCutoff());
PostSetNeedsCommitToMainThread();
break;
case 2:
- EXPECT_EQ(1, callback_count_);
- callback_count_ = 0;
- SetCallback(false);
- PostSetNeedsCommitToMainThread();
+ // The values should remain the same until the commit after the policy
+ // is changed.
+ EXPECT_EQ(PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
+ layer_tree_host()
+ ->contents_texture_manager()
+ ->MaxMemoryLimitBytes());
+ EXPECT_EQ(PriorityCalculator::AllowEverythingCutoff(),
+ layer_tree_host()
+ ->contents_texture_manager()
+ ->ExternalPriorityCutoff());
break;
case 3:
- EXPECT_EQ(0, callback_count_);
- callback_count_ = 0;
+ // Verify values were correctly passed.
+ EXPECT_EQ(16u * 1024u * 1024u,
+ layer_tree_host()
+ ->contents_texture_manager()
+ ->MaxMemoryLimitBytes());
+ EXPECT_EQ(PriorityCalculator::AllowVisibleAndNearbyCutoff(),
+ layer_tree_host()
+ ->contents_texture_manager()
+ ->ExternalPriorityCutoff());
EndTest();
break;
- default:
- ADD_FAILURE() << num_commits_;
- EndTest();
+ case 4:
+ // Make sure no extra commits happen.
+ NOTREACHED();
+ break;
+ }
+ }
+
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ switch (num_commits_) {
+ case 1:
+ break;
+ case 2:
+ // This will trigger a commit because the priority cutoff has changed.
+ impl->SetMemoryPolicy(ManagedMemoryPolicy(
+ 16u * 1024u * 1024u,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+ 1000));
+ break;
+ case 3:
+ // This will not trigger a commit because the priority cutoff has not
+ // changed, and there is already enough memory for all allocations.
+ impl->SetMemoryPolicy(ManagedMemoryPolicy(
+ 32u * 1024u * 1024u,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+ 1000));
break;
+ case 4:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ int num_commits_;
+};
+
+SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
+
+class LayerTreeHostTestNoQuadsForEmptyLayer : public LayerTreeHostTest {
+ protected:
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostTest::SetupTree();
+ root_layer_ = FakeContentLayer::Create(&client_);
+ root_layer_->SetBounds(gfx::Size(10, 10));
+ root_layer_->SetIsDrawable(false);
+ root_layer_->SetHaveWheelEventHandlers(true);
+ layer_tree_host()->SetRootLayer(root_layer_);
+ LayerTreeHostTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ FakeContentLayerImpl* layer_impl =
+ static_cast<FakeContentLayerImpl*>(impl->RootLayer());
+ EXPECT_FALSE(layer_impl->DrawsContent());
+ EXPECT_EQ(0u, layer_impl->append_quads_count());
+ }
+
+ virtual void DidCommit() OVERRIDE {
+ // The layer is not drawable, so it should not be updated.
+ EXPECT_EQ(0u, root_layer_->update_count());
+ EndTest();
+ }
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> root_layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoQuadsForEmptyLayer);
+
+} // namespace
+
+class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
+ : public LayerTreeHostTest {
+ protected:
+ LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
+ : first_output_surface_memory_limit_(4321234),
+ second_output_surface_memory_limit_(1234321) {}
+
+ virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
+ OVERRIDE {
+ if (!first_context_provider_) {
+ first_context_provider_ = TestContextProvider::Create();
+ } else {
+ EXPECT_FALSE(second_context_provider_);
+ second_context_provider_ = TestContextProvider::Create();
+ }
+
+ scoped_refptr<TestContextProvider> provider(second_context_provider_
+ ? second_context_provider_
+ : first_context_provider_);
+ scoped_ptr<FakeOutputSurface> output_surface;
+ if (delegating_renderer())
+ output_surface = FakeOutputSurface::CreateDelegating3d(provider);
+ else
+ output_surface = FakeOutputSurface::Create3d(provider);
+ output_surface->SetMemoryPolicyToSetAtBind(
+ make_scoped_ptr(new ManagedMemoryPolicy(
+ second_context_provider_ ? second_output_surface_memory_limit_
+ : first_output_surface_memory_limit_,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+ ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
+ return output_surface.Pass();
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ root_ = FakeContentLayer::Create(&client_);
+ root_->SetBounds(gfx::Size(20, 20));
+ layer_tree_host()->SetRootLayer(root_);
+ LayerTreeHostTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ // Lost context sometimes takes two frames to recreate. The third frame
+ // is sometimes aborted, so wait until the fourth frame to verify that
+ // the memory has been set, and the fifth frame to end the test.
+ if (layer_tree_host()->source_frame_number() < 5) {
+ layer_tree_host()->SetNeedsCommit();
+ } else if (layer_tree_host()->source_frame_number() == 5) {
+ EndTest();
}
- return LayerTreeHostTest::PrepareToDrawOnThread(host_impl, frame_data,
- result);
- }
-
- virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(3, num_commits_);
}
- void SetCallback(bool enable) {
- output_surface()->SetTreeActivationCallback(enable ?
- base::Bind(&LayerTreeHostTestTreeActivationCallback::ActivationCallback,
- base::Unretained(this)) :
- base::Closure());
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl,
+ bool result) OVERRIDE {
+ switch (impl->active_tree()->source_frame_number()) {
+ case 1:
+ EXPECT_EQ(first_output_surface_memory_limit_,
+ impl->memory_allocation_limit_bytes());
+ // Lose the output surface.
+ first_context_provider_->TestContext3d()->loseContextCHROMIUM(
+ GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
+ break;
+ case 4:
+ EXPECT_EQ(second_output_surface_memory_limit_,
+ impl->memory_allocation_limit_bytes());
+ break;
+ }
}
- void ActivationCallback() {
- ++callback_count_;
- }
+ virtual void AfterTest() OVERRIDE {}
- int num_commits_;
- int callback_count_;
+ scoped_refptr<TestContextProvider> first_context_provider_;
+ scoped_refptr<TestContextProvider> second_context_provider_;
+ size_t first_output_surface_memory_limit_;
+ size_t second_output_surface_memory_limit_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> root_;
};
-TEST_F(LayerTreeHostTestTreeActivationCallback, DirectRenderer) {
- RunTest(true, false, true);
-}
+// No output to copy for delegated renderers.
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
-TEST_F(LayerTreeHostTestTreeActivationCallback, DelegatingRenderer) {
- RunTest(true, true, true);
-}
+struct TestSwapPromiseResult {
+ TestSwapPromiseResult()
+ : did_swap_called(false),
+ did_not_swap_called(false),
+ dtor_called(false),
+ reason(SwapPromise::DID_NOT_SWAP_UNKNOWN) {}
+
+ bool did_swap_called;
+ bool did_not_swap_called;
+ bool dtor_called;
+ SwapPromise::DidNotSwapReason reason;
+ base::Lock lock;
+};
-class LayerInvalidateCausesDraw : public LayerTreeHostTest {
+class TestSwapPromise : public SwapPromise {
public:
- LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {}
-
- virtual void BeginTest() OVERRIDE {
- ASSERT_TRUE(!!invalidate_layer_)
- << "Derived tests must set this in SetupTree";
-
- // One initial commit.
- PostSetNeedsCommitToMainThread();
- }
+ explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {}
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- // After commit, invalidate the layer. This should cause a commit.
- if (layer_tree_host()->source_frame_number() == 1)
- invalidate_layer_->SetNeedsDisplay();
- }
-
- virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_draws_++;
- if (impl->active_tree()->source_frame_number() == 1)
- EndTest();
+ virtual ~TestSwapPromise() {
+ base::AutoLock lock(result_->lock);
+ result_->dtor_called = true;
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_commits_++;
+ virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE {
+ base::AutoLock lock(result_->lock);
+ EXPECT_FALSE(result_->did_swap_called);
+ EXPECT_FALSE(result_->did_not_swap_called);
+ result_->did_swap_called = true;
}
- virtual void AfterTest() OVERRIDE {
- EXPECT_GE(2, num_commits_);
- EXPECT_GE(2, num_draws_);
+ virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
+ base::AutoLock lock(result_->lock);
+ EXPECT_FALSE(result_->did_swap_called);
+ EXPECT_FALSE(result_->did_not_swap_called);
+ result_->did_not_swap_called = true;
+ result_->reason = reason;
}
- protected:
- scoped_refptr<Layer> invalidate_layer_;
-
private:
- int num_commits_;
- int num_draws_;
+ // Not owned.
+ TestSwapPromiseResult* result_;
};
-// VideoLayer must support being invalidated and then passing that along
-// to the compositor thread, even though no resources are updated in
-// response to that invalidation.
-class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw {
- public:
- virtual void SetupTree() OVERRIDE {
- LayerTreeHostTest::SetupTree();
- scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_);
- video_layer->SetBounds(gfx::Size(10, 10));
- video_layer->SetIsDrawable(true);
- layer_tree_host()->root_layer()->AddChild(video_layer);
+class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
+ protected:
+ LayerTreeHostTestBreakSwapPromise()
+ : commit_count_(0), commit_complete_count_(0) {}
- invalidate_layer_ = video_layer;
+ virtual void WillBeginMainFrame() OVERRIDE {
+ ASSERT_LE(commit_count_, 2);
+ scoped_ptr<SwapPromise> swap_promise(
+ new TestSwapPromise(&swap_promise_result_[commit_count_]));
+ layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
}
- private:
- FakeVideoFrameProvider provider_;
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate);
-
-// IOSurfaceLayer must support being invalidated and then passing that along
-// to the compositor thread, even though no resources are updated in
-// response to that invalidation.
-class LayerTreeHostTestIOSurfaceLayerInvalidate
- : public LayerInvalidateCausesDraw {
- public:
- virtual void SetupTree() OVERRIDE {
- LayerTreeHostTest::SetupTree();
- scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create();
- layer->SetBounds(gfx::Size(10, 10));
- uint32_t fake_io_surface_id = 7;
- layer->SetIOSurfaceProperties(fake_io_surface_id, layer->bounds());
- layer->SetIsDrawable(true);
- layer_tree_host()->root_layer()->AddChild(layer);
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- invalidate_layer_ = layer;
+ virtual void DidCommit() OVERRIDE {
+ commit_count_++;
+ if (commit_count_ == 2) {
+ // This commit will finish.
+ layer_tree_host()->SetNeedsCommit();
+ }
}
-};
-// TODO(danakj): IOSurface layer can not be transported. crbug.com/239335
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- LayerTreeHostTestIOSurfaceLayerInvalidate);
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ commit_complete_count_++;
+ if (commit_complete_count_ == 1) {
+ // This commit will be aborted because no actual update.
+ PostSetNeedsUpdateLayersToMainThread();
+ } else {
+ EndTest();
+ }
+ }
-class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- root_layer_ = Layer::Create();
- root_layer_->SetAnchorPoint(gfx::PointF());
- root_layer_->SetPosition(gfx::Point());
- root_layer_->SetBounds(gfx::Size(10, 10));
+ virtual void AfterTest() OVERRIDE {
+ // 3 commits are scheduled. 2 completes. 1 is aborted.
+ EXPECT_EQ(commit_count_, 3);
+ EXPECT_EQ(commit_complete_count_, 2);
- parent_layer_ = SolidColorLayer::Create();
- parent_layer_->SetAnchorPoint(gfx::PointF());
- parent_layer_->SetPosition(gfx::Point());
- parent_layer_->SetBounds(gfx::Size(10, 10));
- parent_layer_->SetIsDrawable(true);
- root_layer_->AddChild(parent_layer_);
+ {
+ // The first commit completes and causes swap buffer which finishes
+ // the promise.
+ base::AutoLock lock(swap_promise_result_[0].lock);
+ EXPECT_TRUE(swap_promise_result_[0].did_swap_called);
+ EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called);
+ EXPECT_TRUE(swap_promise_result_[0].dtor_called);
+ }
- child_layer_ = SolidColorLayer::Create();
- child_layer_->SetAnchorPoint(gfx::PointF());
- child_layer_->SetPosition(gfx::Point());
- child_layer_->SetBounds(gfx::Size(10, 10));
- child_layer_->SetIsDrawable(true);
- parent_layer_->AddChild(child_layer_);
+ {
+ // The second commit aborts.
+ base::AutoLock lock(swap_promise_result_[1].lock);
+ EXPECT_FALSE(swap_promise_result_[1].did_swap_called);
+ EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called);
+ EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_[1].reason);
+ EXPECT_TRUE(swap_promise_result_[1].dtor_called);
+ }
- layer_tree_host()->SetRootLayer(root_layer_);
- LayerTreeHostTest::SetupTree();
+ {
+ // The last commit completes but it does not cause swap buffer because
+ // there is no damage in the frame data.
+ base::AutoLock lock(swap_promise_result_[2].lock);
+ EXPECT_FALSE(swap_promise_result_[2].did_swap_called);
+ EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called);
+ EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason);
+ EXPECT_TRUE(swap_promise_result_[2].dtor_called);
+ }
}
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
-
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- switch (layer_tree_host()->source_frame_number()) {
- case 1:
- // The layer type used does not need to push properties every frame.
- EXPECT_FALSE(child_layer_->needs_push_properties());
+ int commit_count_;
+ int commit_complete_count_;
+ TestSwapPromiseResult swap_promise_result_[3];
+};
- // Change the bounds of the child layer, but make it skipped
- // by CalculateDrawProperties.
- parent_layer_->SetOpacity(0.f);
- child_layer_->SetBounds(gfx::Size(5, 5));
- break;
- case 2:
- // The bounds of the child layer were pushed to the impl side.
- EXPECT_FALSE(child_layer_->needs_push_properties());
+MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
- EndTest();
- break;
- }
- }
+class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
+ public:
+ SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl,
+ int* set_needs_commit_count,
+ int* set_needs_redraw_count)
+ : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
+ set_needs_commit_count_(set_needs_commit_count),
+ set_needs_redraw_count_(set_needs_redraw_count) {}
- virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- LayerImpl* root = impl->active_tree()->root_layer();
- LayerImpl* parent = root->children()[0];
- LayerImpl* child = parent->children()[0];
+ virtual ~SimpleSwapPromiseMonitor() {}
- switch (impl->active_tree()->source_frame_number()) {
- case 1:
- EXPECT_EQ(gfx::Size(5, 5).ToString(), child->bounds().ToString());
- break;
- }
+ virtual void OnSetNeedsCommitOnMain() OVERRIDE {
+ (*set_needs_commit_count_)++;
}
- virtual void AfterTest() OVERRIDE {}
+ virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
+ (*set_needs_redraw_count_)++;
+ }
- scoped_refptr<Layer> root_layer_;
- scoped_refptr<SolidColorLayer> parent_layer_;
- scoped_refptr<SolidColorLayer> child_layer_;
+ private:
+ int* set_needs_commit_count_;
+ int* set_needs_redraw_count_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer);
+class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
+ public:
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
-class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest {
- protected:
- virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->impl_side_painting = true;
- }
+ virtual void WillBeginMainFrame() OVERRIDE {
+ int set_needs_commit_count = 0;
+ int set_needs_redraw_count = 0;
- virtual void SetupTree() OVERRIDE {
- root_layer_ = FakePictureLayer::Create(&client_);
- root_layer_->SetAnchorPoint(gfx::PointF());
- root_layer_->SetBounds(gfx::Size(10, 10));
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(layer_tree_host(),
+ NULL,
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ layer_tree_host()->SetNeedsCommit();
+ EXPECT_EQ(1, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+ }
- layer_tree_host()->SetRootLayer(root_layer_);
- LayerTreeHostTest::SetupTree();
- }
+ // Now the monitor is destroyed, SetNeedsCommit() is no longer being
+ // monitored.
+ layer_tree_host()->SetNeedsCommit();
+ EXPECT_EQ(1, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
- virtual void BeginTest() OVERRIDE {
- // The viewport is empty, but we still need to update layers on the main
- // thread.
- layer_tree_host()->SetViewportSize(gfx::Size(0, 0));
- PostSetNeedsCommitToMainThread();
- }
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(layer_tree_host(),
+ NULL,
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ layer_tree_host()->SetNeedsUpdateLayers();
+ EXPECT_EQ(2, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+ }
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(layer_tree_host(),
+ NULL,
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ layer_tree_host()->SetNeedsAnimate();
+ EXPECT_EQ(3, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+ }
- virtual void DidCommit() OVERRIDE {
- // The layer should be updated even though the viewport is empty, so we
- // are capable of drawing it on the impl tree.
- EXPECT_GT(root_layer_->update_count(), 0u);
EndTest();
}
virtual void AfterTest() OVERRIDE {}
-
- FakeContentLayerClient client_;
- scoped_refptr<FakePictureLayer> root_layer_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
-
-class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
- public:
- LayerTreeHostTestAbortEvictedTextures()
- : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
+MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
+class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
+ : public LayerTreeHostTest {
protected:
- virtual void SetupTree() OVERRIDE {
- scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create();
- root_layer->SetBounds(gfx::Size(200, 200));
- root_layer->SetIsDrawable(true);
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->impl_side_painting = true;
+ }
- layer_tree_host()->SetRootLayer(root_layer);
+ virtual void SetupTree() OVERRIDE {
LayerTreeHostTest::SetupTree();
+ ui_resource_ = FakeScopedUIResource::Create(layer_tree_host());
}
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual void WillBeginMainFrame() OVERRIDE {
- num_will_begin_main_frames_++;
- switch (num_will_begin_main_frames_) {
- case 2:
- // Send a redraw to the compositor thread. This will (wrongly) be
- // ignored unless aborting resets the texture state.
- layer_tree_host()->SetNeedsRedraw();
- break;
- }
- }
-
- virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_impl_commits_++;
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ 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->active_tree()->RequiresHighResToDraw());
}
- virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- switch (impl->SourceAnimationFrameNumber()) {
+ virtual void DidCommit() OVERRIDE {
+ int frame = layer_tree_host()->source_frame_number();
+ switch (frame) {
case 1:
- // Prevent draws until commit.
- impl->active_tree()->SetContentsTexturesPurged();
- EXPECT_FALSE(impl->CanDraw());
- // Trigger an abortable commit.
- impl->SetNeedsCommit();
+ PostSetNeedsCommitToMainThread();
break;
case 2:
+ ui_resource_.reset();
EndTest();
break;
}
}
- virtual void AfterTest() OVERRIDE {
- // Ensure that the commit was truly aborted.
- EXPECT_EQ(2, num_will_begin_main_frames_);
- EXPECT_EQ(1, num_impl_commits_);
- }
+ virtual void AfterTest() OVERRIDE {}
- private:
- int num_will_begin_main_frames_;
- int num_impl_commits_;
+ FakeContentLayerClient client_;
+ scoped_ptr<FakeScopedUIResource> ui_resource_;
};
-// Commits can only be aborted when using the thread proxy.
-MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures);
+MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources);
-class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest {
+class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
protected:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
settings->impl_side_painting = true;
- }
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
- OVERRIDE {
- scoped_refptr<TestContextProvider> context_provider =
- TestContextProvider::Create();
- context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024);
- return FakeOutputSurface::Create3d(context_provider)
- .PassAs<OutputSurface>();
+ EXPECT_FALSE(settings->gpu_rasterization_enabled);
+ EXPECT_FALSE(settings->gpu_rasterization_forced);
}
virtual void SetupTree() OVERRIDE {
- scoped_refptr<FakePictureLayer> root_layer =
- FakePictureLayer::Create(&client_);
- root_layer->SetBounds(gfx::Size(6000, 6000));
- root_layer->SetIsDrawable(true);
-
- layer_tree_host()->SetRootLayer(root_layer);
LayerTreeHostTest::SetupTree();
+
+ scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+ layer->SetBounds(gfx::Size(10, 10));
+ layer->SetIsDrawable(true);
+ layer_tree_host()->root_layer()->AddChild(layer);
}
virtual void BeginTest() OVERRIDE {
+ Layer* root = layer_tree_host()->root_layer();
+ PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
+ PicturePile* pile = layer->GetPicturePileForTesting();
+
+ // Verify default values.
+ EXPECT_TRUE(root->IsSuitableForGpuRasterization());
+ EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
+ EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
+ EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
+ EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
+
+ // Setting gpu rasterization trigger does not enable gpu rasterization.
+ layer_tree_host()->set_has_gpu_rasterization_trigger(true);
+ EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
+ EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
+
PostSetNeedsCommitToMainThread();
}
- virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
- impl->output_surface()->context_provider()->Context3d());
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->pending_tree()->root_layer();
+ PictureLayerImpl* layer_impl =
+ static_cast<PictureLayerImpl*>(root->children()[0]);
- // Expect that the transfer buffer memory used is equal to the
- // MaxTransferBufferUsageBytes value set in CreateOutputSurface.
- EXPECT_EQ(1024 * 1024u,
- context->GetTransferBufferMemoryUsedBytes());
+ EXPECT_FALSE(layer_impl->use_gpu_rasterization());
+ }
+
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->active_tree()->root_layer();
+ PictureLayerImpl* layer_impl =
+ static_cast<PictureLayerImpl*>(root->children()[0]);
+
+ EXPECT_FALSE(layer_impl->use_gpu_rasterization());
EndTest();
}
virtual void AfterTest() OVERRIDE {}
- private:
- FakeContentLayerClient client_;
+ FakeContentLayerClient layer_client_;
};
-// Impl-side painting is a multi-threaded compositor feature.
-MULTI_THREAD_TEST_F(LayerTreeHostTestMaxTransferBufferUsageBytes);
-
-// Test ensuring that memory limits are sent to the prioritized resource
-// manager.
-class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
- public:
- LayerTreeHostTestMemoryLimits() : num_commits_(0) {}
-
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
-
- virtual void DidCommit() OVERRIDE {
- int frame = num_commits_;
- switch (frame) {
- case 0:
- // Verify default values.
- EXPECT_EQ(
- PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
- layer_tree_host()->contents_texture_manager()->
- MaxMemoryLimitBytes());
- EXPECT_EQ(
- PriorityCalculator::AllowEverythingCutoff(),
- layer_tree_host()->contents_texture_manager()->
- ExternalPriorityCutoff());
- PostSetNeedsCommitToMainThread();
- break;
- case 1:
- // The values should remain the same until the commit after the policy
- // is changed.
- EXPECT_EQ(
- PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
- layer_tree_host()->contents_texture_manager()->
- MaxMemoryLimitBytes());
- EXPECT_EQ(
- PriorityCalculator::AllowEverythingCutoff(),
- layer_tree_host()->contents_texture_manager()->
- ExternalPriorityCutoff());
- break;
- case 2:
- // Verify values were correctly passed.
- EXPECT_EQ(
- 16u*1024u*1024u,
- layer_tree_host()->contents_texture_manager()->
- MaxMemoryLimitBytes());
- EXPECT_EQ(
- PriorityCalculator::AllowVisibleAndNearbyCutoff(),
- layer_tree_host()->contents_texture_manager()->
- ExternalPriorityCutoff());
- EndTest();
- break;
- case 3:
- // Make sure no extra commits happen.
- NOTREACHED();
- break;
- }
+MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault);
- ++num_commits_;
- }
+class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest {
+ protected:
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->impl_side_painting = true;
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- int frame = num_commits_;
- switch (frame) {
- case 0:
- break;
- case 1:
- // This will trigger a commit because the priority cutoff has changed.
- impl->SetMemoryPolicy(ManagedMemoryPolicy(
- 16u*1024u*1024u,
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- 1000));
- break;
- case 2:
- // This will not trigger a commit because the priority cutoff has not
- // changed, and there is already enough memory for all allocations.
- impl->SetMemoryPolicy(ManagedMemoryPolicy(
- 32u*1024u*1024u,
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- 1000));
- break;
- case 3:
- NOTREACHED();
- break;
- }
+ EXPECT_FALSE(settings->gpu_rasterization_enabled);
+ settings->gpu_rasterization_enabled = true;
}
- virtual void AfterTest() OVERRIDE {}
-
- private:
- int num_commits_;
-};
-
-SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestMemoryLimits);
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostTest::SetupTree();
-class LayerSetsNeedsFilterContext : public Layer {
- public:
- static scoped_refptr<LayerSetsNeedsFilterContext> Create() {
- return make_scoped_refptr(new LayerSetsNeedsFilterContext());
+ scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+ layer->SetBounds(gfx::Size(10, 10));
+ layer->SetIsDrawable(true);
+ layer_tree_host()->root_layer()->AddChild(layer);
}
- virtual bool Update(ResourceUpdateQueue* queue,
- const OcclusionTracker* occlusion) OVERRIDE {
- bool updated = Layer::Update(queue, occlusion);
- if (needs_context_) {
- layer_tree_host()->set_needs_filter_context();
- return true;
- }
- return updated;
+ virtual void BeginTest() OVERRIDE {
+ Layer* root = layer_tree_host()->root_layer();
+ PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
+ PicturePile* pile = layer->GetPicturePileForTesting();
+
+ // Verify default values.
+ EXPECT_TRUE(root->IsSuitableForGpuRasterization());
+ EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
+ EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
+ EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
+ EXPECT_FALSE(layer_tree_host()->UseGpuRasterization());
+
+ // Gpu rasterization trigger is relevant.
+ layer_tree_host()->set_has_gpu_rasterization_trigger(true);
+ EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
+ EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
+
+ // Content-based veto is relevant as well.
+ pile->SetUnsuitableForGpuRasterizationForTesting();
+ EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
+ EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
+ // Veto will take effect when layers are updated.
+ // The results will be verified after commit is completed below.
+ // Since we are manually marking picture pile as unsuitable,
+ // make sure that the layer gets a chance to update.
+ layer->SetNeedsDisplay();
+ PostSetNeedsCommitToMainThread();
}
- void set_needs_context(bool need) { needs_context_ = need; }
-
- private:
- LayerSetsNeedsFilterContext() : needs_context_(false) {}
- virtual ~LayerSetsNeedsFilterContext() {}
-
- bool needs_context_;
-};
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->pending_tree()->root_layer();
+ PictureLayerImpl* layer_impl =
+ static_cast<PictureLayerImpl*>(root->children()[0]);
-class LayerTreeHostTestOffscreenContext : public LayerTreeHostTest {
- protected:
- virtual void SetupTree() OVERRIDE {
- scoped_refptr<LayerSetsNeedsFilterContext> root =
- LayerSetsNeedsFilterContext::Create();
- root->SetIsDrawable(true);
- root->SetAnchorPoint(gfx::PointF());
- root->SetBounds(gfx::Size(10, 10));
- root->set_needs_context(with_context_);
- layer_tree_host()->SetRootLayer(root);
- LayerTreeHostTest::SetupTree();
+ EXPECT_FALSE(layer_impl->use_gpu_rasterization());
}
- virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->active_tree()->root_layer();
+ PictureLayerImpl* layer_impl =
+ static_cast<PictureLayerImpl*>(root->children()[0]);
- virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- bool expect_context = with_context_;
- if (delegating_renderer())
- expect_context = false;
- EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
+ EXPECT_FALSE(layer_impl->use_gpu_rasterization());
EndTest();
}
virtual void AfterTest() OVERRIDE {}
- bool with_context_;
-};
-
-class LayerTreeHostTestOffscreenContext_NoContext
- : public LayerTreeHostTestOffscreenContext {
- protected:
- LayerTreeHostTestOffscreenContext_NoContext() { with_context_ = false; }
+ FakeContentLayerClient layer_client_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_NoContext);
+MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled);
-class LayerTreeHostTestOffscreenContext_WithContext
- : public LayerTreeHostTestOffscreenContext {
+class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
protected:
- LayerTreeHostTestOffscreenContext_WithContext() { with_context_ = true; }
-};
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->impl_side_painting = true;
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_WithContext);
+ EXPECT_FALSE(settings->gpu_rasterization_forced);
+ settings->gpu_rasterization_forced = true;
+ }
-class LayerTreeHostTestNoQuadsForEmptyLayer : public LayerTreeHostTest {
- protected:
virtual void SetupTree() OVERRIDE {
LayerTreeHostTest::SetupTree();
- root_layer_ = FakeContentLayer::Create(&client_);
- root_layer_->SetBounds(gfx::Size(10, 10));
- root_layer_->SetIsDrawable(false);
- root_layer_->SetHaveWheelEventHandlers(true);
- layer_tree_host()->SetRootLayer(root_layer_);
- LayerTreeHostTest::SetupTree();
+
+ scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_);
+ layer->SetBounds(gfx::Size(10, 10));
+ layer->SetIsDrawable(true);
+ layer_tree_host()->root_layer()->AddChild(layer);
}
virtual void BeginTest() OVERRIDE {
+ Layer* root = layer_tree_host()->root_layer();
+ PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0));
+ PicturePile* pile = layer->GetPicturePileForTesting();
+
+ // Verify default values.
+ EXPECT_TRUE(root->IsSuitableForGpuRasterization());
+ EXPECT_TRUE(layer->IsSuitableForGpuRasterization());
+ EXPECT_TRUE(pile->is_suitable_for_gpu_rasterization());
+ EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger());
+
+ // With gpu rasterization forced, gpu rasterization trigger is irrelevant.
+ EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
+ layer_tree_host()->set_has_gpu_rasterization_trigger(true);
+ EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger());
+ EXPECT_TRUE(layer_tree_host()->UseGpuRasterization());
+
+ // Content-based veto is irrelevant as well.
+ pile->SetUnsuitableForGpuRasterizationForTesting();
+ EXPECT_FALSE(pile->is_suitable_for_gpu_rasterization());
+ EXPECT_FALSE(layer->IsSuitableForGpuRasterization());
+ // Veto will take effect when layers are updated.
+ // The results will be verified after commit is completed below.
+ // Since we are manually marking picture pile as unsuitable,
+ // make sure that the layer gets a chance to update.
+ layer->SetNeedsDisplay();
PostSetNeedsCommitToMainThread();
}
- virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- FakeContentLayerImpl* layer_impl =
- static_cast<FakeContentLayerImpl*>(impl->RootLayer());
- EXPECT_FALSE(layer_impl->DrawsContent());
- EXPECT_EQ(0u, layer_impl->append_quads_count());
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->pending_tree()->root_layer();
+ PictureLayerImpl* layer_impl =
+ static_cast<PictureLayerImpl*>(root->children()[0]);
+
+ EXPECT_TRUE(layer_impl->use_gpu_rasterization());
}
- virtual void DidCommit() OVERRIDE {
- // The layer is not drawable, so it should not be updated.
- EXPECT_EQ(0u, root_layer_->update_count());
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->active_tree()->root_layer();
+ PictureLayerImpl* layer_impl =
+ static_cast<PictureLayerImpl*>(root->children()[0]);
+
+ EXPECT_TRUE(layer_impl->use_gpu_rasterization());
EndTest();
}
+
virtual void AfterTest() OVERRIDE {}
- private:
- FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_layer_;
+ FakeContentLayerClient layer_client_;
};
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoQuadsForEmptyLayer);
-
+MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced);
-} // namespace
+class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestContinuousPainting()
+ : num_commits_(0), num_draws_(0), bounds_(20, 20), child_layer_(NULL) {}
-class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
- : public LayerTreeHostTest {
protected:
- LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface()
- : first_output_surface_memory_limit_(4321234),
- second_output_surface_memory_limit_(1234321) {}
+ enum { kExpectedNumCommits = 10 };
- virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback)
- OVERRIDE {
- if (!first_context_provider_) {
- first_context_provider_ = TestContextProvider::Create();
+ virtual void SetupTree() OVERRIDE {
+ scoped_refptr<Layer> root_layer = Layer::Create();
+ root_layer->SetBounds(bounds_);
+
+ if (layer_tree_host()->settings().impl_side_painting) {
+ picture_layer_ = FakePictureLayer::Create(&client_);
+ child_layer_ = picture_layer_.get();
} else {
- EXPECT_FALSE(second_context_provider_);
- second_context_provider_ = TestContextProvider::Create();
+ content_layer_ = ContentLayerWithUpdateTracking::Create(&client_);
+ child_layer_ = content_layer_.get();
}
+ child_layer_->SetBounds(bounds_);
+ child_layer_->SetIsDrawable(true);
+ root_layer->AddChild(child_layer_);
- scoped_ptr<FakeOutputSurface> output_surface(
- FakeOutputSurface::Create3d(
- second_context_provider_ ?
- second_context_provider_ :
- first_context_provider_));
- output_surface->SetMemoryPolicyToSetAtBind(make_scoped_ptr(
- new ManagedMemoryPolicy(
- second_context_provider_ ?
- second_output_surface_memory_limit_ :
- first_output_surface_memory_limit_,
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
- return output_surface.PassAs<OutputSurface>();
- }
-
- virtual void SetupTree() OVERRIDE {
- root_ = FakeContentLayer::Create(&client_);
- root_->SetBounds(gfx::Size(20, 20));
- layer_tree_host()->SetRootLayer(root_);
+ layer_tree_host()->SetRootLayer(root_layer);
+ layer_tree_host()->SetViewportSize(bounds_);
LayerTreeHostTest::SetupTree();
}
virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
+ // Wait 50x longer than expected.
+ double milliseconds_per_frame =
+ 1000 / layer_tree_host()->settings().refresh_rate;
+ EndTestAfterDelay(50 * kExpectedNumCommits * milliseconds_per_frame);
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &LayerTreeHostTestContinuousPainting::EnableContinuousPainting,
+ base::Unretained(this)));
}
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- // Lost context sometimes takes two frames to recreate. The third frame
- // is sometimes aborted, so wait until the fourth frame to verify that
- // the memory has been set, and the fifth frame to end the test.
- if (layer_tree_host()->source_frame_number() < 5) {
- layer_tree_host()->SetNeedsCommit();
- } else if (layer_tree_host()->source_frame_number() == 5) {
+ virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE {
+ child_layer_->SetNeedsDisplay();
+ }
+
+ virtual void AfterTest() OVERRIDE {
+ EXPECT_LE(kExpectedNumCommits, num_commits_);
+ EXPECT_LE(kExpectedNumCommits, num_draws_);
+ int update_count = content_layer_ ? content_layer_->PaintContentsCount()
+ : picture_layer_->update_count();
+ EXPECT_LE(kExpectedNumCommits, update_count);
+ }
+
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ if (++num_draws_ == kExpectedNumCommits)
EndTest();
- }
}
- virtual void SwapBuffersOnThread(LayerTreeHostImpl *impl, bool result)
- OVERRIDE {
- switch (impl->active_tree()->source_frame_number()) {
- case 1:
- EXPECT_EQ(first_output_surface_memory_limit_,
- impl->memory_allocation_limit_bytes());
- // Lose the output surface.
- first_context_provider_->TestContext3d()->loseContextCHROMIUM(
- GL_GUILTY_CONTEXT_RESET_ARB,
- GL_INNOCENT_CONTEXT_RESET_ARB);
- break;
- case 4:
- EXPECT_EQ(second_output_surface_memory_limit_,
- impl->memory_allocation_limit_bytes());
- break;
- }
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ ++num_commits_;
}
- virtual void AfterTest() OVERRIDE {}
+ private:
+ void EnableContinuousPainting() {
+ LayerTreeDebugState debug_state = layer_tree_host()->debug_state();
+ debug_state.continuous_painting = true;
+ layer_tree_host()->SetDebugState(debug_state);
+ }
- scoped_refptr<TestContextProvider> first_context_provider_;
- scoped_refptr<TestContextProvider> second_context_provider_;
- size_t first_output_surface_memory_limit_;
- size_t second_output_surface_memory_limit_;
+ int num_commits_;
+ int num_draws_;
+ const gfx::Size bounds_;
FakeContentLayerClient client_;
- scoped_refptr<FakeContentLayer> root_;
+ scoped_refptr<ContentLayerWithUpdateTracking> content_layer_;
+ scoped_refptr<FakePictureLayer> picture_layer_;
+ Layer* child_layer_;
};
-// No output to copy for delegated renderers.
-SINGLE_AND_MULTI_THREAD_TEST_F(
- LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface);
+MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting);
} // namespace cc