This source file includes following definitions.
- ReturnedResourceLower
- ResourcesMatch
- CreateFrameData
- CreateInvalidFrameData
- AddTransferableResource
- AddTextureQuad
- AddRenderPass
- AppendResourceId
- ReturnUnusedResourcesFromParent
- available_
- SetupTree
- BeginTest
- SetFrameData
- CreateDelegatedLayer
- AfterTest
- UnusedResourcesAreAvailable
- TestAndResetAvailable
- did_reset_child_id_
- DidCommit
- DidActivateTreeOnThread
- InitializedRendererOnThread
- num_output_surfaces_initialized_
- DidCommit
- DidInitializeOutputSurface
- DidActivateTreeOnThread
- InitializedRendererOnThread
- AfterTest
- BeginTest
- DrawLayersOnThread
- BeginTest
- DrawLayersOnThread
- BeginTest
- DrawLayersOnThread
- BeginTest
- DrawLayersOnThread
- first_draw_for_source_frame_
- DidCommit
- PrepareToDrawOnThread
- BeginTest
- DidActivateTreeOnThread
- BeginTest
- DidActivateTreeOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- DidActivateTreeOnThread
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- DidActivateTreeOnThread
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommit
- DidActivateTreeOnThread
- BeginTest
- DidCommitAndDrawFrame
- DidActivateTreeOnThread
- SwapBuffersOnThread
- DidCommitAndDrawFrame
- ReceiveResourceOnThread
- UnusedResourcesAreAvailable
- DidActivateTreeOnThread
- BeginTest
- DidCommit
- DidActivateTreeOnThread
- BeginTest
- WillActivateTreeOnThread
- DidCommit
- CommitCompleteOnThread
- SwapBuffersOnThread
- UnusedResourcesAreAvailable
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
#include "cc/trees/layer_tree_host.h"
#include <algorithm>
#include "base/bind.h"
#include "base/location.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/layers/delegated_renderer_layer.h"
#include "cc/layers/delegated_renderer_layer_impl.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/shared_quad_state.h"
#include "cc/quads/texture_draw_quad.h"
#include "cc/resources/returned_resource.h"
#include "cc/test/fake_delegated_renderer_layer.h"
#include "cc/test/fake_delegated_renderer_layer_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/layer_tree_impl.h"
#include "gpu/GLES2/gl2extchromium.h"
namespace cc {
namespace {
bool ReturnedResourceLower(const ReturnedResource& a,
const ReturnedResource& b) {
return a.id < b.id;
}
bool ResourcesMatch(ReturnedResourceArray actual,
unsigned* expected,
size_t expected_count) {
std::sort(actual.begin(), actual.end(), ReturnedResourceLower);
std::sort(expected, expected + expected_count);
size_t actual_index = 0;
for (size_t expected_index = 0; expected_index < expected_count;
++expected_index) {
EXPECT_LT(actual_index, actual.size());
if (actual_index >= actual.size())
return false;
EXPECT_EQ(actual[actual_index].id, expected[expected_index]);
if (actual[actual_index].id != expected[expected_index])
return false;
EXPECT_GT(actual[actual_index].count, 0);
if (actual[actual_index].count <= 0) {
return false;
} else {
--actual[actual_index].count;
if (actual[actual_index].count == 0)
++actual_index;
}
}
EXPECT_EQ(actual_index, actual.size());
return actual_index == actual.size();
}
#define EXPECT_RESOURCES(expected, actual) \
EXPECT_TRUE(ResourcesMatch(actual, expected, arraysize(expected)));
class LayerTreeHostDelegatedTest : public LayerTreeTest {
protected:
scoped_ptr<DelegatedFrameData> CreateFrameData(
const gfx::Rect& root_output_rect,
const gfx::Rect& root_damage_rect) {
scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
scoped_ptr<RenderPass> root_pass(RenderPass::Create());
root_pass->SetNew(RenderPass::Id(1, 1),
root_output_rect,
root_damage_rect,
gfx::Transform());
frame->render_pass_list.push_back(root_pass.Pass());
return frame.Pass();
}
scoped_ptr<DelegatedFrameData> CreateInvalidFrameData(
const gfx::Rect& root_output_rect,
const gfx::Rect& root_damage_rect) {
scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
scoped_ptr<RenderPass> root_pass(RenderPass::Create());
root_pass->SetNew(RenderPass::Id(1, 1),
root_output_rect,
root_damage_rect,
gfx::Transform());
scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
gfx::Rect rect = root_output_rect;
gfx::Rect opaque_rect = root_output_rect;
gfx::Rect visible_rect = root_output_rect;
unsigned resource_id = 5;
bool premultiplied_alpha = false;
gfx::PointF uv_top_left = gfx::PointF(0.f, 0.f);
gfx::PointF uv_bottom_right = gfx::PointF(1.f, 1.f);
SkColor background_color = 0;
float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
bool flipped = false;
scoped_ptr<TextureDrawQuad> invalid_draw_quad = TextureDrawQuad::Create();
invalid_draw_quad->SetNew(shared_quad_state.get(),
rect,
opaque_rect,
visible_rect,
resource_id,
premultiplied_alpha,
uv_top_left,
uv_bottom_right,
background_color,
vertex_opacity,
flipped);
root_pass->quad_list.push_back(invalid_draw_quad.PassAs<DrawQuad>());
root_pass->shared_quad_state_list.push_back(shared_quad_state.Pass());
frame->render_pass_list.push_back(root_pass.Pass());
return frame.Pass();
}
void AddTransferableResource(DelegatedFrameData* frame,
ResourceProvider::ResourceId resource_id) {
TransferableResource resource;
resource.id = resource_id;
resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
GLbyte arbitrary_mailbox[GL_MAILBOX_SIZE_CHROMIUM] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4};
resource.mailbox_holder.mailbox.SetName(arbitrary_mailbox);
frame->resource_list.push_back(resource);
}
void AddTextureQuad(DelegatedFrameData* frame,
ResourceProvider::ResourceId resource_id) {
scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f };
quad->SetNew(sqs.get(),
gfx::Rect(0, 0, 10, 10),
gfx::Rect(0, 0, 10, 10),
gfx::Rect(0, 0, 10, 10),
resource_id,
false,
gfx::PointF(0.f, 0.f),
gfx::PointF(1.f, 1.f),
SK_ColorTRANSPARENT,
vertex_opacity,
false);
frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
}
void AddRenderPass(DelegatedFrameData* frame,
RenderPass::Id id,
const gfx::Rect& output_rect,
const gfx::Rect& damage_rect,
const FilterOperations& filters,
const FilterOperations& background_filters) {
for (size_t i = 0; i < frame->render_pass_list.size(); ++i)
DCHECK(id != frame->render_pass_list[i]->id);
scoped_ptr<RenderPass> pass(RenderPass::Create());
pass->SetNew(id,
output_rect,
damage_rect,
gfx::Transform());
frame->render_pass_list.push_back(pass.Pass());
scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create();
scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
quad->SetNew(sqs.get(),
output_rect,
output_rect,
id,
false,
0,
damage_rect,
gfx::Rect(0, 0, 1, 1),
filters,
background_filters);
frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass());
frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
}
static ResourceProvider::ResourceId AppendResourceId(
std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame,
ResourceProvider::ResourceId resource_id) {
resources_in_last_sent_frame->push_back(resource_id);
return resource_id;
}
void ReturnUnusedResourcesFromParent(LayerTreeHostImpl* host_impl) {
DelegatedFrameData* delegated_frame_data =
output_surface()->last_sent_frame().delegated_frame_data.get();
if (!delegated_frame_data)
return;
std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame;
for (size_t i = 0; i < delegated_frame_data->resource_list.size(); ++i) {
resources_in_last_sent_frame.push_back(
delegated_frame_data->resource_list[i].id);
}
std::vector<ResourceProvider::ResourceId> resources_to_return;
const TransferableResourceArray& resources_held_by_parent =
output_surface()->resources_held_by_parent();
for (size_t i = 0; i < resources_held_by_parent.size(); ++i) {
ResourceProvider::ResourceId resource_in_parent =
resources_held_by_parent[i].id;
bool resource_in_parent_is_not_part_of_frame =
std::find(resources_in_last_sent_frame.begin(),
resources_in_last_sent_frame.end(),
resource_in_parent) == resources_in_last_sent_frame.end();
if (resource_in_parent_is_not_part_of_frame)
resources_to_return.push_back(resource_in_parent);
}
if (resources_to_return.empty())
return;
CompositorFrameAck ack;
for (size_t i = 0; i < resources_to_return.size(); ++i)
output_surface()->ReturnResource(resources_to_return[i], &ack);
host_impl->ReclaimResources(&ack);
host_impl->OnSwapBuffersComplete();
}
};
class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
: public LayerTreeHostDelegatedTest,
public DelegatedFrameResourceCollectionClient {
public:
LayerTreeHostDelegatedTestCaseSingleDelegatedLayer()
: resource_collection_(new DelegatedFrameResourceCollection),
available_(false) {
resource_collection_->SetClient(this);
}
virtual void SetupTree() OVERRIDE {
root_ = Layer::Create();
root_->SetAnchorPoint(gfx::PointF());
root_->SetBounds(gfx::Size(10, 10));
layer_tree_host()->SetRootLayer(root_);
LayerTreeHostDelegatedTest::SetupTree();
}
virtual void BeginTest() OVERRIDE {
resource_collection_->SetClient(this);
PostSetNeedsCommitToMainThread();
}
void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data) {
RenderPass* root_pass = frame_data->render_pass_list.back();
gfx::Size frame_size = root_pass->output_rect.size();
if (frame_provider_.get() && frame_size == frame_provider_->frame_size()) {
frame_provider_->SetFrameData(frame_data.Pass());
return;
}
if (delegated_.get()) {
delegated_->RemoveFromParent();
delegated_ = NULL;
frame_provider_ = NULL;
}
frame_provider_ = new DelegatedFrameProvider(resource_collection_.get(),
frame_data.Pass());
delegated_ = CreateDelegatedLayer(frame_provider_.get());
}
scoped_refptr<DelegatedRendererLayer> CreateDelegatedLayer(
DelegatedFrameProvider* frame_provider) {
scoped_refptr<DelegatedRendererLayer> delegated =
FakeDelegatedRendererLayer::Create(frame_provider);
delegated->SetAnchorPoint(gfx::PointF());
delegated->SetBounds(gfx::Size(10, 10));
delegated->SetIsDrawable(true);
root_->AddChild(delegated);
return delegated;
}
virtual void AfterTest() OVERRIDE { resource_collection_->SetClient(NULL); }
virtual void UnusedResourcesAreAvailable() OVERRIDE { available_ = true; }
bool TestAndResetAvailable() {
bool available = available_;
available_ = false;
return available;
}
protected:
scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
scoped_refptr<DelegatedFrameProvider> frame_provider_;
scoped_refptr<Layer> root_;
scoped_refptr<DelegatedRendererLayer> delegated_;
bool available_;
};
class LayerTreeHostDelegatedTestCreateChildId
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
LayerTreeHostDelegatedTestCreateChildId()
: LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
num_activates_(0),
did_reset_child_id_(false) {}
virtual void DidCommit() OVERRIDE {
if (TestEnded())
return;
SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() < 1)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
TestContextProvider* context_provider = static_cast<TestContextProvider*>(
host_impl->output_surface()->context_provider().get());
++num_activates_;
switch (num_activates_) {
case 2:
EXPECT_TRUE(delegated_impl->ChildId());
EXPECT_FALSE(did_reset_child_id_);
context_provider->ContextGL()->LoseContextCHROMIUM(
GL_GUILTY_CONTEXT_RESET_ARB,
GL_INNOCENT_CONTEXT_RESET_ARB);
context_provider->ContextGL()->Flush();
break;
case 3:
EXPECT_TRUE(delegated_impl->ChildId());
EXPECT_TRUE(did_reset_child_id_);
EndTest();
break;
}
}
virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
bool success) OVERRIDE {
EXPECT_TRUE(success);
if (num_activates_ < 2)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
EXPECT_EQ(2, num_activates_);
EXPECT_FALSE(delegated_impl->ChildId());
did_reset_child_id_ = true;
}
protected:
int num_activates_;
bool did_reset_child_id_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId);
class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
LayerTreeHostDelegatedTestInvalidFrameAfterContextLost()
: num_activates_(0), num_output_surfaces_initialized_(0) {}
virtual void DidCommit() OVERRIDE {
if (TestEnded())
return;
scoped_ptr<DelegatedFrameData> frame1 =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame1.get(), 999);
AddTransferableResource(frame1.get(), 999);
SetFrameData(frame1.Pass());
}
virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE {
if (!num_output_surfaces_initialized_++)
return;
scoped_refptr<DelegatedRendererLayer> old_delegated = delegated_;
SetFrameData(
CreateInvalidFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
DCHECK(delegated_.get() == old_delegated.get());
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() < 1)
return;
TestContextProvider* context_provider = static_cast<TestContextProvider*>(
host_impl->output_surface()->context_provider().get());
++num_activates_;
switch (num_activates_) {
case 2:
context_provider->ContextGL()->LoseContextCHROMIUM(
GL_GUILTY_CONTEXT_RESET_ARB,
GL_INNOCENT_CONTEXT_RESET_ARB);
break;
case 3:
EndTest();
break;
}
}
virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl,
bool success) OVERRIDE {
EXPECT_TRUE(success);
if (num_activates_ < 2)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
EXPECT_EQ(2, num_activates_);
EXPECT_EQ(0U, delegated_impl->Resources().size());
}
virtual void AfterTest() OVERRIDE {
LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest();
EXPECT_EQ(2, num_output_surfaces_initialized_);
}
protected:
int num_activates_;
int num_output_surfaces_initialized_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestInvalidFrameAfterContextLost);
class LayerTreeHostDelegatedTestOffscreenContext_NoFilters
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
protected:
virtual void BeginTest() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
EXPECT_FALSE(host_impl->offscreen_context_provider());
EndTest();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestOffscreenContext_NoFilters);
class LayerTreeHostDelegatedTestOffscreenContext_Filters
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
protected:
virtual void BeginTest() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1));
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
AddRenderPass(frame.get(),
RenderPass::Id(2, 1),
gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1),
filters,
FilterOperations());
SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
bool expect_context = !delegating_renderer();
EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
EndTest();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestOffscreenContext_Filters);
class LayerTreeHostDelegatedTestOffscreenContext_BackgroundFilters
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
protected:
virtual void BeginTest() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1));
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
AddRenderPass(frame.get(),
RenderPass::Id(2, 1),
gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1),
FilterOperations(),
filters);
SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
bool expect_context = !delegating_renderer();
EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
EndTest();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestOffscreenContext_BackgroundFilters);
class LayerTreeHostDelegatedTestOffscreenContext_Filters_AddedToTree
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
protected:
virtual void BeginTest() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame_no_filters =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
scoped_ptr<DelegatedFrameData> frame_with_filters =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
FilterOperations filters;
filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f));
AddRenderPass(frame_with_filters.get(),
RenderPass::Id(2, 1),
gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1),
filters,
FilterOperations());
SetFrameData(frame_no_filters.Pass());
delegated_->RemoveFromParent();
SetFrameData(frame_with_filters.Pass());
layer_tree_host()->root_layer()->AddChild(delegated_);
PostSetNeedsCommitToMainThread();
}
virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
bool expect_context = !delegating_renderer();
EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
EndTest();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestOffscreenContext_Filters_AddedToTree);
class LayerTreeHostDelegatedTestLayerUsesFrameDamage
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
LayerTreeHostDelegatedTestLayerUsesFrameDamage()
: LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(),
first_draw_for_source_frame_(true) {}
virtual void DidCommit() OVERRIDE {
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
break;
case 2:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0)));
break;
case 3:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(2, 2, 5, 5)));
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(7, 2, 5, 6)));
break;
case 4:
layer_tree_host()->SetNeedsCommit();
break;
case 5:
delegated_->SetBounds(gfx::Size(2, 2));
break;
case 6:
layer_tree_host()->SetNeedsCommit();
break;
case 7:
delegated_->SetBounds(gfx::Size(6, 6));
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2)));
break;
case 8:
layer_tree_host()->SetNeedsCommit();
break;
case 9:
delegated_->SetDisplaySize(gfx::Size(10, 10));
break;
case 10:
layer_tree_host()->SetNeedsCommit();
break;
case 11:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1)));
break;
case 12:
SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5),
gfx::Rect(4, 4, 1, 1)));
break;
case 13:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
break;
case 14:
layer_tree_host()->SetNeedsCommit();
break;
case 15:
delegated_->RemoveFromParent();
layer_tree_host()->root_layer()->AddChild(delegated_);
break;
case 16:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
break;
case 17:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10)));
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 0, 0)));
break;
case 18:
delegated_copy_ = CreateDelegatedLayer(frame_provider_);
delegated_copy_->SetPosition(gfx::Point(5, 0));
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1)));
break;
case 19:
SetFrameData(
CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1)));
}
first_draw_for_source_frame_ = true;
}
virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
LayerTreeHostImpl* host_impl,
LayerTreeHostImpl::FrameData* frame,
DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
EXPECT_EQ(DrawSwapReadbackResult::DRAW_SUCCESS, draw_result);
if (!first_draw_for_source_frame_)
return draw_result;
gfx::RectF damage_rect;
if (!frame->has_no_damage) {
damage_rect = frame->render_passes.back()->damage_rect;
} else {
EXPECT_TRUE(frame->render_passes.empty());
}
switch (host_impl->active_tree()->source_frame_number()) {
case 0:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 1:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 2:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 3:
EXPECT_EQ(gfx::RectF(1.f, 1.f, 5.f, 3.f).ToString(),
damage_rect.ToString());
break;
case 4:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 5:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 6:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 7:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 6.f, 6.f).ToString(),
damage_rect.ToString());
break;
case 8:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 9:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 6.f, 6.f).ToString(),
damage_rect.ToString());
break;
case 10:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 11:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 12:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 13:
EXPECT_EQ(gfx::RectF(2.f, 2.f, 4.f, 4.f).ToString(),
damage_rect.ToString());
break;
case 14:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 15:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 16:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 17:
EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 18:
EXPECT_EQ(gfx::UnionRects(gfx::RectF(5.f, 0.f, 10.f, 10.f),
gfx::RectF(4.f, 0.f, 1.f, 1.f)).ToString(),
damage_rect.ToString());
break;
case 19:
EXPECT_EQ(gfx::RectF(3.f, 3.f, 6.f, 1.f).ToString(),
damage_rect.ToString());
EndTest();
break;
}
return draw_result;
}
protected:
scoped_refptr<DelegatedRendererLayer> delegated_copy_;
bool first_draw_for_source_frame_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage);
class LayerTreeHostDelegatedTestMergeResources
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame1 =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame1.get(), 999);
AddTransferableResource(frame1.get(), 999);
SetFrameData(frame1.Pass());
scoped_ptr<DelegatedFrameData> frame2 =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame2.get(), 999);
AddTransferableResource(frame2.get(), 999);
AddTextureQuad(frame2.get(), 555);
AddTransferableResource(frame2.get(), 555);
SetFrameData(frame2.Pass());
ReturnedResourceArray returned_resources;
resource_collection_->TakeUnusedResourcesForChildCompositor(
&returned_resources);
{
unsigned expected[] = {999};
EXPECT_RESOURCES(expected, returned_resources);
EXPECT_TRUE(TestAndResetAvailable());
}
PostSetNeedsCommitToMainThread();
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(2u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
EndTest();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources);
class LayerTreeHostDelegatedTestRemapResourcesInQuads
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
ResourceProvider::ResourceId parent_resource_id1 = map.find(999)->second;
EXPECT_NE(parent_resource_id1, 999u);
ResourceProvider::ResourceId parent_resource_id2 = map.find(555)->second;
EXPECT_NE(parent_resource_id2, 555u);
const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
delegated_impl->RenderPassesInDrawOrder()[0]->quad_list[0]);
EXPECT_EQ(parent_resource_id1, quad1->resource_id);
const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
delegated_impl->RenderPassesInDrawOrder()[0]->quad_list[1]);
EXPECT_EQ(parent_resource_id2, quad2->resource_id);
EndTest();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads);
class LayerTreeHostDelegatedTestReturnUnusedResources
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
break;
case 4:
layer_tree_host()->SetNeedsCommit();
return;
case 5:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 999, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
ReturnedResourceArray empty_resources;
resource_collection_->TakeUnusedResourcesForChildCompositor(
&empty_resources);
EXPECT_EQ(0u, empty_resources.size());
EXPECT_FALSE(TestAndResetAvailable());
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestReturnUnusedResources);
class LayerTreeHostDelegatedTestReusedResources
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {999, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources);
class LayerTreeHostDelegatedTestFrameBeforeAck
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 555};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
SetFrameData(frame.Pass());
break;
}
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() != 3)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
EXPECT_EQ(1u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
EXPECT_EQ(1u, pass->quad_list.size());
const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(
pass->quad_list[0]);
EXPECT_EQ(map.find(999)->second, quad->resource_id);
EndTest();
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck);
class LayerTreeHostDelegatedTestFrameBeforeTakeResources
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
break;
case 3:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 555};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
EndTest();
break;
}
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() != 3)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
EXPECT_EQ(3u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, map.count(444));
EXPECT_EQ(3u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
EXPECT_EQ(1u, delegated_impl->Resources().count(444));
const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
EXPECT_EQ(3u, pass->quad_list.size());
const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
pass->quad_list[0]);
EXPECT_EQ(map.find(999)->second, quad1->resource_id);
const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
pass->quad_list[1]);
EXPECT_EQ(map.find(555)->second, quad2->resource_id);
const TextureDrawQuad* quad3 = TextureDrawQuad::MaterialCast(
pass->quad_list[2]);
EXPECT_EQ(map.find(444)->second, quad3->resource_id);
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestFrameBeforeTakeResources);
class LayerTreeHostDelegatedTestBadFrame
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 885);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
AddTextureQuad(frame.get(), 775);
SetFrameData(frame.Pass());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() < 1)
return;
ReturnUnusedResourcesFromParent(host_impl);
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
switch (host_impl->active_tree()->source_frame_number()) {
case 1: {
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(2u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
EXPECT_EQ(2u, pass->quad_list.size());
const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
pass->quad_list[0]);
EXPECT_EQ(map.find(999)->second, quad1->resource_id);
const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
pass->quad_list[1]);
EXPECT_EQ(map.find(555)->second, quad2->resource_id);
break;
}
case 2: {
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(2u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
EXPECT_EQ(2u, pass->quad_list.size());
const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
pass->quad_list[0]);
EXPECT_EQ(map.find(999)->second, quad1->resource_id);
const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast(
pass->quad_list[1]);
EXPECT_EQ(map.find(555)->second, quad2->resource_id);
break;
}
case 3: {
EXPECT_EQ(1u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0];
EXPECT_EQ(1u, pass->quad_list.size());
const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast(
pass->quad_list[0]);
EXPECT_EQ(map.find(999)->second, quad1->resource_id);
break;
}
}
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame);
class LayerTreeHostDelegatedTestUnnamedResource
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommit() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() != 1)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
EXPECT_EQ(1u, map.size());
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource);
class LayerTreeHostDelegatedTestDontLeakResource
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
break;
case 3:
resources.clear();
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() != 1)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
EXPECT_EQ(1u, map.size());
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource);
class LayerTreeHostDelegatedTestResourceSentToParent
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
ImplThreadTaskRunner()->PostTask(FROM_HERE,
receive_resource_on_thread_);
break;
}
}
void ReceiveResourceOnThread(LayerTreeHostImpl* host_impl) {
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
CompositorFrameAck ack;
output_surface()->ReturnResource(map.find(999)->second, &ack);
host_impl->ReclaimResources(&ack);
host_impl->OnSwapBuffersComplete();
}
virtual void UnusedResourcesAreAvailable() OVERRIDE {
EXPECT_EQ(3, layer_tree_host()->source_frame_number());
ReturnedResourceArray resources;
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {999};
EXPECT_RESOURCES(expected, resources);
}
EndTest();
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() < 1)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
switch (host_impl->active_tree()->source_frame_number()) {
case 1: {
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(2u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
break;
}
case 2: {
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
receive_resource_on_thread_ =
base::Bind(&LayerTreeHostDelegatedTestResourceSentToParent::
ReceiveResourceOnThread,
base::Unretained(this),
host_impl);
break;
}
case 3:
EXPECT_EQ(1u, map.size());
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second));
break;
}
}
base::Closure receive_resource_on_thread_;
};
SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
LayerTreeHostDelegatedTestResourceSentToParent);
class LayerTreeHostDelegatedTestCommitWithoutTake
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE {
layer_tree_host()->SetViewportSize(gfx::Size());
PostSetNeedsCommitToMainThread();
}
virtual void DidCommit() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 3:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
break;
case 5:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 555, 555, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() < 1)
return;
LayerImpl* root_impl = host_impl->active_tree()->root_layer();
FakeDelegatedRendererLayerImpl* delegated_impl =
static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]);
const ResourceProvider::ResourceIdMap& map =
host_impl->resource_provider()->GetChildToParentMap(
delegated_impl->ChildId());
switch (host_impl->active_tree()->source_frame_number()) {
case 1:
EXPECT_EQ(3u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, map.count(444));
EXPECT_EQ(3u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
EXPECT_EQ(1u, delegated_impl->Resources().count(444));
break;
case 2:
EXPECT_EQ(1u, map.size());
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
break;
case 3:
EXPECT_EQ(2u, map.size());
EXPECT_EQ(1u, map.count(999));
EXPECT_EQ(1u, map.count(555));
EXPECT_EQ(2u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(999));
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
}
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake);
class DelegatedFrameIsActivatedDuringCommit
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
protected:
DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {}
virtual void BeginTest() OVERRIDE {
activate_count_ = 0;
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
++activate_count_;
}
virtual void DidCommit() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
case 1: {
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
}
case 2:
delegated_->RemoveFromParent();
break;
case 3:
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
break;
}
}
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
switch (host_impl->active_tree()->source_frame_number()) {
case 2: {
EXPECT_EQ(2, activate_count_);
break;
}
case 3: {
EXPECT_EQ(3, activate_count_);
break;
}
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
virtual void UnusedResourcesAreAvailable() OVERRIDE {
LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::
UnusedResourcesAreAvailable();
ReturnedResourceArray resources;
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_TRUE(TestAndResetAvailable());
returned_resource_count_ += resources.size();
if (returned_resource_count_ == 2)
EndTest();
}
int activate_count_;
size_t returned_resource_count_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
DelegatedFrameIsActivatedDuringCommit);
class LayerTreeHostDelegatedTestTwoImplLayers
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_->RemoveFromParent();
delegated_ = CreateDelegatedLayer(frame_provider_.get());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers);
class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
delegated_->RemoveFromParent();
delegated_ = NULL;
frame_provider_->SetFrameData(frame.Pass());
delegated_ = CreateDelegatedLayer(frame_provider_.get());
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
SetFrameData(frame.Pass());
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 555, 999, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestTwoImplLayersTwoFrames);
class LayerTreeHostDelegatedTestTwoLayers
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
delegated_thief_ = CreateDelegatedLayer(frame_provider_.get());
root_->AddChild(delegated_thief_);
frame_provider_ = NULL;
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_->RemoveFromParent();
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
root_->AddChild(delegated_);
delegated_thief_->RemoveFromParent();
delegated_thief_ = NULL;
break;
case 5:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_->RemoveFromParent();
break;
case 6:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_ = NULL;
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
scoped_refptr<DelegatedRendererLayer> delegated_thief_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers);
class LayerTreeHostDelegatedTestRemoveAndAddToTree
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_->RemoveFromParent();
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
layer_tree_host()->root_layer()->AddChild(delegated_);
break;
case 4:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 888);
AddTransferableResource(frame.get(), 888);
AddTextureQuad(frame.get(), 777);
AddTransferableResource(frame.get(), 777);
SetFrameData(frame.Pass());
break;
case 5:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
delegated_->RemoveFromParent();
delegated_ = NULL;
break;
case 6:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame_provider_ = NULL;
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {777, 888};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
scoped_refptr<DelegatedRendererLayer> delegated_thief_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree);
class LayerTreeHostDelegatedTestRemoveAndChangeResources
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
public:
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DidCommitAndDrawFrame() OVERRIDE {
scoped_ptr<DelegatedFrameData> frame;
ReturnedResourceArray resources;
int next_source_frame_number = layer_tree_host()->source_frame_number();
switch (next_source_frame_number) {
case 1:
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
SetFrameData(frame.Pass());
break;
case 2:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_->RemoveFromParent();
break;
case 3:
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 888);
AddTransferableResource(frame.get(), 888);
AddTextureQuad(frame.get(), 777);
AddTransferableResource(frame.get(), 777);
SetFrameData(frame.Pass());
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 999};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
resources.clear();
}
frame_provider_ = NULL;
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
delegated_ = NULL;
resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {777, 888};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
EndTest();
break;
}
}
virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
scoped_refptr<DelegatedRendererLayer> delegated_thief_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
LayerTreeHostDelegatedTestRemoveAndChangeResources);
}
}