summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 21:03:45 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 21:03:45 +0000
commit09f6738713c25d6ab583ed0f94722495ee78b05d (patch)
treee72922013ccaaa1ebf513f6933a40da10362a29d
parentad87c674c4bb4200b6c25dec05ac25f3eceba24c (diff)
downloadchromium_src-09f6738713c25d6ab583ed0f94722495ee78b05d.zip
chromium_src-09f6738713c25d6ab583ed0f94722495ee78b05d.tar.gz
chromium_src-09f6738713c25d6ab583ed0f94722495ee78b05d.tar.bz2
aura: Allow delegated frames to be used by more than one impl layer.
Delegated frames can be used by multiple impl layers within a single compositor if they are given to different DelegatedRendererLayers which each send the frame to their impl layer. Also, they can be given to different DelegatedRendererLayers that live in different compositors. So we need something that outlives any DelegatedRendererLayer and will receive returned resources from the impl side of multiple compositors and know when to release resoures back to the child compositor, and how many resources to release. This patch introduces two new classes: DelegatedFrameProvider. This class holds a delegated frame and notifies a single DelegatedRendererLayer (the latest one to attach to it) about new frames so that it can grab them and display them. If a new DelegatedRendererLayer steals a DelegatedFrameProvider it will receive notifications in the future and the first layer will stop updating. DelegatedFrameResourceCollection. This class holds resources and ref counts on them to keep track of how many refs are being used by compositor instances, and how many refs have been received from the child compositor. Once a resource is not in use anymore by any compositors, all references passed from the child compositor will be made available via TakeUnusedResourcesForChildCompositor(). Tests: LayerTreeHostDelegatedTestTwoImplLayers LayerTreeHostDelegatedTestRemoveAndAddToTree LayerTreeHostDelegatedTestRemoveAndChangeResources R=piman,alexst@chromium.org BUG=263069 Review URL: https://codereview.chromium.org/26023004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227807 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/cc.gyp4
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/layers/delegated_frame_provider.cc110
-rw-r--r--cc/layers/delegated_frame_provider.h75
-rw-r--r--cc/layers/delegated_frame_provider_unittest.cc334
-rw-r--r--cc/layers/delegated_frame_resource_collection.cc94
-rw-r--r--cc/layers/delegated_frame_resource_collection.h68
-rw-r--r--cc/layers/delegated_renderer_layer.cc134
-rw-r--r--cc/layers/delegated_renderer_layer.h42
-rw-r--r--cc/layers/delegated_renderer_layer_impl.cc39
-rw-r--r--cc/layers/delegated_renderer_layer_impl.h2
-rw-r--r--cc/resources/resource_provider.cc5
-rw-r--r--cc/resources/resource_provider.h1
-rw-r--r--cc/test/fake_delegated_renderer_layer.cc5
-rw-r--r--cc/test/fake_delegated_renderer_layer.h9
-rw-r--r--cc/test/fake_delegated_renderer_layer_impl.cc11
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc20
-rw-r--r--cc/trees/layer_tree_host_unittest_delegated.cc822
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc122
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h10
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc44
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h25
-rw-r--r--content/renderer/browser_plugin/browser_plugin_compositing_helper.cc37
-rw-r--r--content/renderer/browser_plugin/browser_plugin_compositing_helper.h5
-rw-r--r--ui/compositor/layer.cc25
-rw-r--r--ui/compositor/layer.h16
-rw-r--r--ui/compositor/layer_unittest.cc33
27 files changed, 1678 insertions, 415 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 354889e..40dc34f 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -114,6 +114,10 @@
'layers/content_layer_client.h',
'layers/contents_scaling_layer.cc',
'layers/contents_scaling_layer.h',
+ 'layers/delegated_frame_provider.cc',
+ 'layers/delegated_frame_provider.h',
+ 'layers/delegated_frame_resource_collection.cc',
+ 'layers/delegated_frame_resource_collection.h',
'layers/delegated_renderer_layer.cc',
'layers/delegated_renderer_layer.h',
'layers/delegated_renderer_layer_client.h',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index db8bc62..a5e60dd 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -22,6 +22,7 @@
'input/top_controls_manager_unittest.cc',
'layers/content_layer_unittest.cc',
'layers/contents_scaling_layer_unittest.cc',
+ 'layers/delegated_frame_provider_unittest.cc',
'layers/delegated_renderer_layer_impl_unittest.cc',
'layers/heads_up_display_unittest.cc',
'layers/layer_impl_unittest.cc',
diff --git a/cc/layers/delegated_frame_provider.cc b/cc/layers/delegated_frame_provider.cc
new file mode 100644
index 0000000..c97f231
--- /dev/null
+++ b/cc/layers/delegated_frame_provider.cc
@@ -0,0 +1,110 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/delegated_frame_provider.h"
+
+#include "cc/layers/delegated_frame_resource_collection.h"
+#include "cc/layers/delegated_renderer_layer.h"
+#include "cc/output/delegated_frame_data.h"
+#include "cc/quads/render_pass_draw_quad.h"
+
+namespace cc {
+
+DelegatedFrameProvider::DelegatedFrameProvider(
+ const scoped_refptr<DelegatedFrameResourceCollection>& resource_collection,
+ scoped_ptr<DelegatedFrameData> frame)
+ : resource_collection_(resource_collection) {
+ RenderPass* root_pass = frame->render_pass_list.back();
+ frame_size_ = root_pass->output_rect.size();
+ DCHECK(!frame_size_.IsEmpty());
+ SetFrameData(frame.Pass());
+}
+
+DelegatedFrameProvider::~DelegatedFrameProvider() {
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(frame_->resource_list, &returned);
+ resource_collection_->UnrefResources(returned);
+}
+
+void DelegatedFrameProvider::AddObserver(DelegatedRendererLayer* layer) {
+ if (DCHECK_IS_ON()) {
+ for (size_t i = 0; i < observers_.size(); ++i)
+ DCHECK(observers_[i].layer != layer);
+ }
+
+ observers_.push_back(Observer(layer, gfx::RectF(frame_size_)));
+
+ DCHECK(frame_) << "Must have a frame when given to a DelegatedRendererLayer.";
+}
+
+void DelegatedFrameProvider::RemoveObserver(DelegatedRendererLayer* layer) {
+ bool found_observer = false;
+ for (size_t i = 0; i < observers_.size(); ++i) {
+ if (observers_[i].layer != layer)
+ continue;
+ observers_.erase(observers_.begin() + i);
+ found_observer = true;
+ break;
+ }
+ DCHECK(found_observer);
+}
+
+void DelegatedFrameProvider::SetFrameData(
+ scoped_ptr<DelegatedFrameData> frame) {
+ DCHECK(frame);
+ DCHECK_NE(0u, frame->render_pass_list.size());
+
+ if (frame_) {
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(frame_->resource_list, &returned);
+ resource_collection_->UnrefResources(returned);
+ }
+
+ frame_ = frame.Pass();
+
+ resource_collection_->ReceivedResources(frame_->resource_list);
+ resource_collection_->RefResources(frame_->resource_list);
+
+ RenderPass* root_pass = frame_->render_pass_list.back();
+ DCHECK_EQ(frame_size_.ToString(), root_pass->output_rect.size().ToString())
+ << "All frames in a single DelegatedFrameProvider must have the same "
+ << "size. Use a new frame provider for frames of a different size.";
+
+ for (size_t i = 0; i < observers_.size(); ++i) {
+ observers_[i].damage =
+ gfx::UnionRects(observers_[i].damage, root_pass->damage_rect);
+ observers_[i].layer->ProviderHasNewFrame();
+ }
+}
+
+DelegatedFrameData* DelegatedFrameProvider::GetFrameDataAndRefResources(
+ DelegatedRendererLayer* observer,
+ gfx::RectF* damage) {
+
+ bool found_observer = false;
+ for (size_t i = 0; i < observers_.size(); ++i) {
+ if (observers_[i].layer != observer)
+ continue;
+ *damage = observers_[i].damage;
+ // The observer is now responsible for the damage.
+ observers_[i].damage = gfx::RectF();
+ found_observer = true;
+ }
+ DCHECK(found_observer);
+
+ resource_collection_->RefResources(frame_->resource_list);
+ return frame_.get();
+}
+
+ReturnCallback
+DelegatedFrameProvider::GetReturnResourcesCallbackForImplThread() {
+ return resource_collection_->GetReturnResourcesCallbackForImplThread();
+}
+
+void DelegatedFrameProvider::UnrefResourcesOnMainThread(
+ const ReturnedResourceArray& returned) {
+ resource_collection_->UnrefResources(returned);
+}
+
+} // namespace cc
diff --git a/cc/layers/delegated_frame_provider.h b/cc/layers/delegated_frame_provider.h
new file mode 100644
index 0000000..b71c748
--- /dev/null
+++ b/cc/layers/delegated_frame_provider.h
@@ -0,0 +1,75 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_LAYERS_DELEGATED_FRAME_PROVIDER_H_
+#define CC_LAYERS_DELEGATED_FRAME_PROVIDER_H_
+
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+#include "cc/resources/return_callback.h"
+#include "cc/resources/returned_resource.h"
+#include "ui/gfx/rect_f.h"
+#include "ui/gfx/size.h"
+
+namespace cc {
+class DelegatedFrameData;
+class DelegatedFrameResourceCollection;
+class DelegatedRendererLayer;
+
+// Only one observing layer has ownership of the DelegatedFrameProvider. Only
+// the active observer should call GetFrameDataAndRefResources(). All frames
+// provided by a single DelegatedFrameProvider must have the same size. A new
+// provider must be used for frames of a different size.
+class CC_EXPORT DelegatedFrameProvider
+ : public base::RefCounted<DelegatedFrameProvider> {
+ public:
+ explicit DelegatedFrameProvider(
+ const scoped_refptr<DelegatedFrameResourceCollection>&
+ resource_collection,
+ scoped_ptr<DelegatedFrameData> frame);
+
+ void AddObserver(DelegatedRendererLayer* layer);
+ void RemoveObserver(DelegatedRendererLayer* layer);
+
+ void SetFrameData(scoped_ptr<DelegatedFrameData> frame);
+
+ // The DelegatedFrameData returned here must be displayed in order to not
+ // lose track of damage.
+ DelegatedFrameData* GetFrameDataAndRefResources(
+ DelegatedRendererLayer* observer,
+ gfx::RectF* damage);
+
+ ReturnCallback GetReturnResourcesCallbackForImplThread();
+ void UnrefResourcesOnMainThread(const ReturnedResourceArray& unused);
+
+ gfx::Size frame_size() const { return frame_size_; }
+
+ private:
+ friend class base::RefCounted<DelegatedFrameProvider>;
+ ~DelegatedFrameProvider();
+
+ scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
+
+ scoped_ptr<DelegatedFrameData> frame_;
+
+ struct Observer {
+ DelegatedRendererLayer* layer;
+ gfx::RectF damage;
+
+ Observer(DelegatedRendererLayer* layer, const gfx::RectF& damage)
+ : layer(layer), damage(damage) {}
+ };
+ std::vector<Observer> observers_;
+
+ gfx::Size frame_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(DelegatedFrameProvider);
+};
+
+} // namespace cc
+
+#endif // CC_LAYERS_DELEGATED_FRAME_PROVIDER_H_
diff --git a/cc/layers/delegated_frame_provider_unittest.cc b/cc/layers/delegated_frame_provider_unittest.cc
new file mode 100644
index 0000000..b4ae1d9
--- /dev/null
+++ b/cc/layers/delegated_frame_provider_unittest.cc
@@ -0,0 +1,334 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/delegated_frame_provider.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
+#include "cc/layers/delegated_renderer_layer.h"
+#include "cc/output/delegated_frame_data.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/resources/returned_resource.h"
+#include "cc/resources/transferable_resource.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class DelegatedFrameProviderTest
+ : public testing::Test,
+ public DelegatedFrameResourceCollectionClient {
+ protected:
+ DelegatedFrameProviderTest() : resources_available_(false) {}
+
+ scoped_ptr<DelegatedFrameData> CreateFrameData(gfx::Rect root_output_rect,
+ 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();
+ }
+
+ void AddTransferableResource(DelegatedFrameData* frame,
+ ResourceProvider::ResourceId resource_id) {
+ TransferableResource resource;
+ resource.id = resource_id;
+ resource.target = GL_TEXTURE_2D;
+ 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),
+ 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>());
+ }
+
+ virtual void SetUp() OVERRIDE {
+ resource_collection_ = new DelegatedFrameResourceCollection;
+ resource_collection_->SetClient(this);
+ }
+
+ virtual void TearDown() OVERRIDE { resource_collection_->SetClient(NULL); }
+
+ virtual void UnusedResourcesAreAvailable() OVERRIDE {
+ resources_available_ = true;
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources_);
+ }
+
+ bool ReturnAndResetResourcesAvailable() {
+ bool r = resources_available_;
+ resources_available_ = false;
+ return r;
+ }
+
+ void SetFrameProvider(scoped_ptr<DelegatedFrameData> frame_data) {
+ frame_provider_ =
+ new DelegatedFrameProvider(resource_collection_, frame_data.Pass());
+ }
+
+ scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
+ scoped_refptr<DelegatedFrameProvider> frame_provider_;
+ bool resources_available_;
+ ReturnedResourceArray resources_;
+};
+
+TEST_F(DelegatedFrameProviderTest, SameResources) {
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+ SetFrameProvider(frame.Pass());
+
+ frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+ SetFrameProvider(frame.Pass());
+
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(0u, resources_.size());
+
+ frame_provider_ = NULL;
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, resources_.size());
+ EXPECT_EQ(444u, resources_[0].id);
+}
+
+TEST_F(DelegatedFrameProviderTest, ReplaceResources) {
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+ SetFrameProvider(frame.Pass());
+
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ frame = CreateFrameData(gfx::Rect(1, 1), gfx::Rect(1, 1));
+ AddTextureQuad(frame.get(), 555);
+ AddTransferableResource(frame.get(), 555);
+ SetFrameProvider(frame.Pass());
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, resources_.size());
+ EXPECT_EQ(444u, resources_[0].id);
+ resources_.clear();
+
+ frame_provider_ = NULL;
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, resources_.size());
+ EXPECT_EQ(555u, resources_[0].id);
+}
+
+TEST_F(DelegatedFrameProviderTest, RefResources) {
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+
+ TransferableResourceArray reffed = frame->resource_list;
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(reffed, &returned);
+
+ SetFrameProvider(frame.Pass());
+
+ scoped_refptr<DelegatedRendererLayer> observer1 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+ scoped_refptr<DelegatedRendererLayer> observer2 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+
+ gfx::RectF damage;
+
+ // Both observers get a full frame of damage on the first request.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+ EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
+
+ // And both get no damage on the 2nd request. This adds a second ref to the
+ // resources.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+ EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
+
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 555);
+ AddTransferableResource(frame.get(), 555);
+ frame_provider_->SetFrameData(frame.Pass());
+
+ // The resources from the first frame are still reffed by the observers.
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ // There are 4 refs taken.
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ // The 4th unref will release them.
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, resources_.size());
+ EXPECT_EQ(444u, resources_[0].id);
+}
+
+TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProvider) {
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+
+ TransferableResourceArray reffed = frame->resource_list;
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(reffed, &returned);
+
+ SetFrameProvider(frame.Pass());
+
+ scoped_refptr<DelegatedRendererLayer> observer1 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+ scoped_refptr<DelegatedRendererLayer> observer2 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+
+ gfx::RectF damage;
+
+ // Take a ref on each observer.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ // Release both refs. But there's still a ref held in the frame
+ // provider itself.
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ // Setting a new frame will release it.
+ frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 555);
+ AddTransferableResource(frame.get(), 555);
+ frame_provider_->SetFrameData(frame.Pass());
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, resources_.size());
+ EXPECT_EQ(444u, resources_[0].id);
+}
+
+TEST_F(DelegatedFrameProviderTest, RefResourcesInFrameProviderUntilDestroy) {
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+
+ TransferableResourceArray reffed = frame->resource_list;
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(reffed, &returned);
+
+ SetFrameProvider(frame.Pass());
+
+ scoped_refptr<DelegatedRendererLayer> observer1 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+ scoped_refptr<DelegatedRendererLayer> observer2 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+
+ gfx::RectF damage;
+
+ // Take a ref on each observer.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ // Release both refs. But there's still a ref held in the frame
+ // provider itself.
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ frame_provider_->UnrefResourcesOnMainThread(returned);
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ // Releasing all references to the frame provider will release
+ // the frame.
+ observer1 = NULL;
+ observer2 = NULL;
+ EXPECT_FALSE(ReturnAndResetResourcesAvailable());
+
+ frame_provider_ = NULL;
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, resources_.size());
+ EXPECT_EQ(444u, resources_[0].id);
+}
+
+TEST_F(DelegatedFrameProviderTest, Damage) {
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 444);
+ AddTransferableResource(frame.get(), 444);
+
+ TransferableResourceArray reffed = frame->resource_list;
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(reffed, &returned);
+
+ SetFrameProvider(frame.Pass());
+
+ scoped_refptr<DelegatedRendererLayer> observer1 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+ scoped_refptr<DelegatedRendererLayer> observer2 =
+ DelegatedRendererLayer::Create(NULL, frame_provider_.get());
+
+ gfx::RectF damage;
+
+ // Both observers get a full frame of damage on the first request.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+ EXPECT_EQ(gfx::RectF(5.f, 5.f).ToString(), damage.ToString());
+
+ // And both get no damage on the 2nd request.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+ EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
+
+ frame = CreateFrameData(gfx::Rect(5, 5), gfx::Rect(2, 2));
+ AddTextureQuad(frame.get(), 555);
+ AddTransferableResource(frame.get(), 555);
+ frame_provider_->SetFrameData(frame.Pass());
+
+ // Both observers get the damage for the new frame.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString());
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+ EXPECT_EQ(gfx::RectF(2.f, 2.f).ToString(), damage.ToString());
+
+ // And both get no damage on the 2nd request.
+ frame_provider_->GetFrameDataAndRefResources(observer1, &damage);
+ EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
+ frame_provider_->GetFrameDataAndRefResources(observer2, &damage);
+ EXPECT_EQ(gfx::RectF().ToString(), damage.ToString());
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/layers/delegated_frame_resource_collection.cc b/cc/layers/delegated_frame_resource_collection.cc
new file mode 100644
index 0000000..ee679fa
--- /dev/null
+++ b/cc/layers/delegated_frame_resource_collection.cc
@@ -0,0 +1,94 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/delegated_frame_resource_collection.h"
+
+#include "base/bind.h"
+#include "cc/trees/blocking_task_runner.h"
+
+namespace cc {
+
+DelegatedFrameResourceCollection::DelegatedFrameResourceCollection()
+ : client_(NULL), main_thread_runner_(BlockingTaskRunner::current()) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+}
+
+DelegatedFrameResourceCollection::~DelegatedFrameResourceCollection() {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+}
+
+void DelegatedFrameResourceCollection::SetClient(
+ DelegatedFrameResourceCollectionClient* client) {
+ client_ = client;
+}
+
+void DelegatedFrameResourceCollection::TakeUnusedResourcesForChildCompositor(
+ ReturnedResourceArray* array) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ DCHECK(array->empty());
+ array->swap(returned_resources_for_child_compositor_);
+}
+
+void DelegatedFrameResourceCollection::ReceivedResources(
+ const TransferableResourceArray& resources) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ for (size_t i = 0; i < resources.size(); ++i)
+ resource_id_ref_count_map_[resources[i].id].refs_to_return++;
+}
+
+void DelegatedFrameResourceCollection::UnrefResources(
+ const ReturnedResourceArray& returned) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+
+ ReturnedResourceArray to_return;
+
+ for (size_t i = 0; i < returned.size(); ++i) {
+ ResourceIdRefCountMap::iterator it =
+ resource_id_ref_count_map_.find(returned[i].id);
+ DCHECK(it != resource_id_ref_count_map_.end());
+ DCHECK_GE(it->second.refs_to_wait_for, returned[i].count);
+ it->second.refs_to_wait_for -= returned[i].count;
+ if (it->second.refs_to_wait_for == 0) {
+ to_return.push_back(returned[i]);
+ to_return.back().count = it->second.refs_to_return;
+ resource_id_ref_count_map_.erase(it);
+ }
+ }
+
+ if (to_return.empty())
+ return;
+
+ returned_resources_for_child_compositor_.insert(
+ returned_resources_for_child_compositor_.end(),
+ to_return.begin(),
+ to_return.end());
+ if (client_)
+ client_->UnusedResourcesAreAvailable();
+}
+
+void DelegatedFrameResourceCollection::RefResources(
+ const TransferableResourceArray& resources) {
+ DCHECK(main_thread_checker_.CalledOnValidThread());
+ for (size_t i = 0; i < resources.size(); ++i)
+ resource_id_ref_count_map_[resources[i].id].refs_to_wait_for++;
+}
+
+ReturnCallback
+DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() {
+ return base::Bind(
+ &DelegatedFrameResourceCollection::UnrefResourcesOnImplThread,
+ this,
+ main_thread_runner_);
+}
+
+void DelegatedFrameResourceCollection::UnrefResourcesOnImplThread(
+ scoped_refptr<BlockingTaskRunner> main_thread_runner,
+ const ReturnedResourceArray& returned) {
+ main_thread_runner->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &DelegatedFrameResourceCollection::UnrefResources, this, returned));
+}
+
+} // namespace cc
diff --git a/cc/layers/delegated_frame_resource_collection.h b/cc/layers/delegated_frame_resource_collection.h
new file mode 100644
index 0000000..f5d4a4d
--- /dev/null
+++ b/cc/layers/delegated_frame_resource_collection.h
@@ -0,0 +1,68 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_LAYERS_DELEGATED_FRAME_RESOURCE_COLLECTION_H_
+#define CC_LAYERS_DELEGATED_FRAME_RESOURCE_COLLECTION_H_
+
+#include "base/containers/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
+#include "cc/base/cc_export.h"
+#include "cc/resources/return_callback.h"
+#include "cc/resources/returned_resource.h"
+#include "cc/resources/transferable_resource.h"
+
+namespace cc {
+class BlockingTaskRunner;
+
+class CC_EXPORT DelegatedFrameResourceCollectionClient {
+ public:
+ // Called to inform the client that returned resources can be
+ // grabbed off the DelegatedFrameResourceCollection.
+ virtual void UnusedResourcesAreAvailable() = 0;
+};
+
+class CC_EXPORT DelegatedFrameResourceCollection
+ : public base::RefCounted<DelegatedFrameResourceCollection> {
+ public:
+ DelegatedFrameResourceCollection();
+
+ void SetClient(DelegatedFrameResourceCollectionClient* client);
+
+ void TakeUnusedResourcesForChildCompositor(ReturnedResourceArray* array);
+
+ // Methods for DelegatedFrameProvider.
+ void RefResources(const TransferableResourceArray& resources);
+ void UnrefResources(const ReturnedResourceArray& returned);
+ void ReceivedResources(const TransferableResourceArray& resources);
+ ReturnCallback GetReturnResourcesCallbackForImplThread();
+
+ private:
+ friend class base::RefCounted<DelegatedFrameResourceCollection>;
+ ~DelegatedFrameResourceCollection();
+
+ void UnrefResourcesOnImplThread(
+ scoped_refptr<BlockingTaskRunner> main_thread_runner,
+ const ReturnedResourceArray& returned);
+
+ DelegatedFrameResourceCollectionClient* client_;
+ scoped_refptr<BlockingTaskRunner> main_thread_runner_;
+
+ ReturnedResourceArray returned_resources_for_child_compositor_;
+
+ struct RefCount {
+ int refs_to_return;
+ int refs_to_wait_for;
+ };
+ typedef base::hash_map<unsigned, RefCount> ResourceIdRefCountMap;
+ ResourceIdRefCountMap resource_id_ref_count_map_;
+
+ base::ThreadChecker main_thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(DelegatedFrameResourceCollection);
+};
+
+} // namespace cc
+
+#endif // CC_LAYERS_DELEGATED_FRAME_RESOURCE_COLLECTION_H_
diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc
index edc2e846..a92b701 100644
--- a/cc/layers/delegated_renderer_layer.cc
+++ b/cc/layers/delegated_renderer_layer.cc
@@ -14,20 +14,28 @@
namespace cc {
scoped_refptr<DelegatedRendererLayer> DelegatedRendererLayer::Create(
- DelegatedRendererLayerClient* client) {
+ DelegatedRendererLayerClient* client,
+ const scoped_refptr<DelegatedFrameProvider>& frame_provider) {
return scoped_refptr<DelegatedRendererLayer>(
- new DelegatedRendererLayer(client));
+ new DelegatedRendererLayer(client, frame_provider));
}
DelegatedRendererLayer::DelegatedRendererLayer(
- DelegatedRendererLayerClient* client)
+ DelegatedRendererLayerClient* client,
+ const scoped_refptr<DelegatedFrameProvider>& frame_provider)
: Layer(),
client_(client),
- needs_filter_context_(false),
+ frame_provider_(frame_provider),
+ should_collect_new_frame_(true),
+ frame_data_(NULL),
main_thread_runner_(BlockingTaskRunner::current()),
- weak_ptrs_(this) {}
+ weak_ptrs_(this) {
+ frame_provider_->AddObserver(this);
+}
-DelegatedRendererLayer::~DelegatedRendererLayer() {}
+DelegatedRendererLayer::~DelegatedRendererLayer() {
+ frame_provider_->RemoveObserver(this);
+}
scoped_ptr<LayerImpl> DelegatedRendererLayer::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
@@ -48,17 +56,15 @@ void DelegatedRendererLayer::SetLayerTreeHost(LayerTreeHost* host) {
// or we never commited a frame with resources.
SetNextCommitWaitsForActivation();
} else {
- if (needs_filter_context_)
- host->set_needs_filter_context();
+ // There is no active frame in the new layer tree host to wait for so no
+ // need to call SetNextCommitWaitsForActivation().
+ should_collect_new_frame_ = true;
+ SetNeedsUpdate();
}
Layer::SetLayerTreeHost(host);
}
-bool DelegatedRendererLayer::DrawsContent() const {
- return Layer::DrawsContent() && !frame_size_.IsEmpty();
-}
-
void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) {
Layer::PushPropertiesTo(impl);
@@ -68,26 +74,32 @@ void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) {
delegated_impl->SetDisplaySize(display_size_);
delegated_impl->CreateChildIdIfNeeded(
- base::Bind(&DelegatedRendererLayer::ReceiveUnusedResourcesOnImplThread,
- main_thread_runner_,
- weak_ptrs_.GetWeakPtr()));
+ frame_provider_->GetReturnResourcesCallbackForImplThread());
if (frame_data_)
- delegated_impl->SetFrameData(frame_data_.Pass(), damage_in_frame_);
- frame_data_.reset();
- damage_in_frame_ = gfx::RectF();
+ delegated_impl->SetFrameData(frame_data_, frame_damage_);
+ frame_data_ = NULL;
+ frame_damage_ = gfx::RectF();
// The ResourceProvider will have the new frame as soon as we push it to the
- // pending tree. So unused resources will be returned as well.
+ // pending tree. So resources no longer in use will be returned as well.
if (client_)
client_->DidCommitFrameData();
// TODO(danakj): The DidCommitFrameData() notification requires a push
- // properties to happen in order to notify about unused resources returned
- // from the parent compositor. crbug.com/259090
+ // properties to happen in order to notify about resources returned
+ // from the parent compositor that are no longer in use. crbug.com/259090
needs_push_properties_ = true;
}
+void DelegatedRendererLayer::ProviderHasNewFrame() {
+ should_collect_new_frame_ = true;
+ SetNeedsUpdate();
+ // The active frame needs to be replaced and resources returned before the
+ // commit is called complete.
+ SetNextCommitWaitsForActivation();
+}
+
void DelegatedRendererLayer::SetDisplaySize(gfx::Size size) {
if (display_size_ == size)
return;
@@ -95,80 +107,38 @@ void DelegatedRendererLayer::SetDisplaySize(gfx::Size size) {
SetNeedsCommit();
}
-void DelegatedRendererLayer::SetFrameData(
- scoped_ptr<DelegatedFrameData> new_frame_data) {
- DCHECK(new_frame_data);
-
- if (frame_data_) {
- // Copy the resources from the last provided frame into the unused resources
- // list, as the new frame will provide its own resources.
- TransferableResource::ReturnResources(
- frame_data_->resource_list,
- &unused_resources_for_child_compositor_);
- if (client_)
- client_->UnusedResourcesAreAvailable();
- }
- frame_data_ = new_frame_data.Pass();
- if (!frame_data_->render_pass_list.empty()) {
- RenderPass* root_pass = frame_data_->render_pass_list.back();
- damage_in_frame_.Union(root_pass->damage_rect);
- frame_size_ = root_pass->output_rect.size();
- } else {
- frame_size_ = gfx::Size();
- }
-
- // If any RenderPassDrawQuad has a filter operation, then we need a filter
- // context to draw this layer's content.
- for (size_t i = 0;
- !needs_filter_context_ && i < frame_data_->render_pass_list.size();
- ++i) {
- const QuadList& quad_list = frame_data_->render_pass_list[i]->quad_list;
- for (size_t j = 0; !needs_filter_context_ && j < quad_list.size(); ++j) {
+static bool FrameDataHasFilter(DelegatedFrameData* frame) {
+ for (size_t i = 0; i < frame->render_pass_list.size(); ++i) {
+ const QuadList& quad_list = frame->render_pass_list[i]->quad_list;
+ for (size_t j = 0; j < quad_list.size(); ++j) {
if (quad_list[j]->material != DrawQuad::RENDER_PASS)
continue;
const RenderPassDrawQuad* render_pass_quad =
RenderPassDrawQuad::MaterialCast(quad_list[j]);
if (!render_pass_quad->filters.IsEmpty() ||
!render_pass_quad->background_filters.IsEmpty())
- needs_filter_context_ = true;
+ return true;
}
}
- if (needs_filter_context_ && layer_tree_host())
- layer_tree_host()->set_needs_filter_context();
-
- SetNeedsCommit();
- // The active frame needs to be replaced and resources returned before the
- // commit is called complete.
- SetNextCommitWaitsForActivation();
+ return false;
}
-void DelegatedRendererLayer::TakeUnusedResourcesForChildCompositor(
- ReturnedResourceArray* array) {
- DCHECK(array->empty());
- array->clear();
+bool DelegatedRendererLayer::Update(ResourceUpdateQueue* queue,
+ const OcclusionTracker* occlusion) {
+ bool updated = Layer::Update(queue, occlusion);
+ if (!should_collect_new_frame_)
+ return updated;
- array->swap(unused_resources_for_child_compositor_);
-}
+ frame_data_ =
+ frame_provider_->GetFrameDataAndRefResources(this, &frame_damage_);
+ should_collect_new_frame_ = false;
-void DelegatedRendererLayer::ReceiveUnusedResources(
- const ReturnedResourceArray& unused) {
- unused_resources_for_child_compositor_.insert(
- unused_resources_for_child_compositor_.end(),
- unused.begin(),
- unused.end());
- if (client_)
- client_->UnusedResourcesAreAvailable();
-}
+ // If any quad has a filter operation, then we need a filter context to draw
+ // this layer's content.
+ if (FrameDataHasFilter(frame_data_) && layer_tree_host())
+ layer_tree_host()->set_needs_filter_context();
-// static
-void DelegatedRendererLayer::ReceiveUnusedResourcesOnImplThread(
- scoped_refptr<BlockingTaskRunner> task_runner,
- base::WeakPtr<DelegatedRendererLayer> self,
- const ReturnedResourceArray& unused) {
- task_runner->PostTask(
- FROM_HERE,
- base::Bind(
- &DelegatedRendererLayer::ReceiveUnusedResources, self, unused));
+ return true;
}
} // namespace cc
diff --git a/cc/layers/delegated_renderer_layer.h b/cc/layers/delegated_renderer_layer.h
index 60e9c3c..6cae121 100644
--- a/cc/layers/delegated_renderer_layer.h
+++ b/cc/layers/delegated_renderer_layer.h
@@ -5,28 +5,31 @@
#ifndef CC_LAYERS_DELEGATED_RENDERER_LAYER_H_
#define CC_LAYERS_DELEGATED_RENDERER_LAYER_H_
+#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "cc/base/cc_export.h"
+#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/layer.h"
#include "cc/resources/returned_resource.h"
namespace cc {
class BlockingTaskRunner;
-class DelegatedFrameData;
class DelegatedRendererLayerClient;
class CC_EXPORT DelegatedRendererLayer : public Layer {
public:
static scoped_refptr<DelegatedRendererLayer> Create(
- DelegatedRendererLayerClient* client);
+ DelegatedRendererLayerClient* client,
+ const scoped_refptr<DelegatedFrameProvider>& frame_provider);
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
OVERRIDE;
virtual void SetLayerTreeHost(LayerTreeHost* host) OVERRIDE;
+ virtual bool Update(ResourceUpdateQueue* queue,
+ const OcclusionTracker* occlusion) OVERRIDE;
virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE;
- virtual bool DrawsContent() const OVERRIDE;
// Set the size at which the frame should be displayed, with the origin at the
// layer's origin. This must always contain at least the layer's bounds. A
@@ -34,32 +37,27 @@ class CC_EXPORT DelegatedRendererLayer : public Layer {
// in the layer's bounds.
void SetDisplaySize(gfx::Size size);
- void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data);
-
- // Passes ownership of any unused resources that had been given by the child
- // compositor to the given array, so they can be given back to the child.
- void TakeUnusedResourcesForChildCompositor(ReturnedResourceArray* array);
+ // Called by the DelegatedFrameProvider when a new frame is available to be
+ // picked up.
+ void ProviderHasNewFrame();
protected:
- explicit DelegatedRendererLayer(DelegatedRendererLayerClient* client);
+ DelegatedRendererLayer(
+ DelegatedRendererLayerClient* client,
+ const scoped_refptr<DelegatedFrameProvider>& frame_provider);
virtual ~DelegatedRendererLayer();
private:
- void ReceiveUnusedResources(const ReturnedResourceArray& unused);
- static void ReceiveUnusedResourcesOnImplThread(
- scoped_refptr<BlockingTaskRunner> task_runner,
- base::WeakPtr<DelegatedRendererLayer> self,
- const ReturnedResourceArray& unused);
-
- scoped_ptr<DelegatedFrameData> frame_data_;
- gfx::RectF damage_in_frame_;
- gfx::Size frame_size_;
- gfx::Size display_size_;
-
DelegatedRendererLayerClient* client_;
- bool needs_filter_context_;
+ scoped_refptr<DelegatedFrameProvider> frame_provider_;
+
+ bool should_collect_new_frame_;
+
+ DelegatedFrameData* frame_data_;
+ gfx::RectF frame_damage_;
+
+ gfx::Size display_size_;
- ReturnedResourceArray unused_resources_for_child_compositor_;
scoped_refptr<BlockingTaskRunner> main_thread_runner_;
base::WeakPtrFactory<DelegatedRendererLayer> weak_ptrs_;
diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc
index 34a1cd8..35bd0b7 100644
--- a/cc/layers/delegated_renderer_layer_impl.cc
+++ b/cc/layers/delegated_renderer_layer_impl.cc
@@ -33,9 +33,7 @@ DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl() {
ClearChildId();
}
-bool DelegatedRendererLayerImpl::HasDelegatedContent() const {
- return !render_passes_in_draw_order_.empty();
-}
+bool DelegatedRendererLayerImpl::HasDelegatedContent() const { return true; }
bool DelegatedRendererLayerImpl::HasContributingDelegatedRenderPasses() const {
// The root RenderPass for the layer is merged with its target
@@ -101,14 +99,13 @@ void DelegatedRendererLayerImpl::CreateChildIdIfNeeded(
}
void DelegatedRendererLayerImpl::SetFrameData(
- scoped_ptr<DelegatedFrameData> frame_data,
+ const DelegatedFrameData* frame_data,
gfx::RectF damage_in_frame) {
- DCHECK(frame_data);
DCHECK(child_id_) << "CreateChildIdIfNeeded must be called first.";
-
+ DCHECK(frame_data);
+ DCHECK(!frame_data->render_pass_list.empty());
// A frame with an empty root render pass is invalid.
- DCHECK(frame_data->render_pass_list.empty() ||
- !frame_data->render_pass_list.back()->output_rect.IsEmpty());
+ DCHECK(!frame_data->render_pass_list.back()->output_rect.IsEmpty());
ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
const ResourceProvider::ResourceIdMap& resource_map =
@@ -116,6 +113,9 @@ void DelegatedRendererLayerImpl::SetFrameData(
resource_provider->ReceiveFromChild(child_id_, frame_data->resource_list);
+ ScopedPtrVector<RenderPass> render_pass_list;
+ RenderPass::CopyAll(frame_data->render_pass_list, &render_pass_list);
+
bool invalid_frame = false;
ResourceProvider::ResourceIdArray resources_in_frame;
DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback =
@@ -123,8 +123,8 @@ void DelegatedRendererLayerImpl::SetFrameData(
&invalid_frame,
resource_map,
&resources_in_frame);
- for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) {
- RenderPass* pass = frame_data->render_pass_list[i];
+ for (size_t i = 0; i < render_pass_list.size(); ++i) {
+ RenderPass* pass = render_pass_list[i];
for (size_t j = 0; j < pass->quad_list.size(); ++j) {
DrawQuad* quad = pass->quad_list[j];
quad->IterateResources(remap_resources_to_parent_callback);
@@ -143,18 +143,13 @@ void DelegatedRendererLayerImpl::SetFrameData(
// Display size is already set so we can compute what the damage rect
// will be in layer space.
- if (!frame_data->render_pass_list.empty()) {
- RenderPass* new_root_pass = frame_data->render_pass_list.back();
- gfx::RectF damage_in_layer = MathUtil::MapClippedRect(
- DelegatedFrameToLayerSpaceTransform(
- new_root_pass->output_rect.size()),
- damage_in_frame);
- set_update_rect(gfx::UnionRects(update_rect(), damage_in_layer));
- }
+ RenderPass* new_root_pass = render_pass_list.back();
+ gfx::Size frame_size = new_root_pass->output_rect.size();
+ gfx::RectF damage_in_layer = MathUtil::MapClippedRect(
+ DelegatedFrameToLayerSpaceTransform(frame_size), damage_in_frame);
+ set_update_rect(gfx::UnionRects(update_rect(), damage_in_layer));
- // Save the remapped quads on the layer. This steals the quads and render
- // passes from the frame_data.
- SetRenderPasses(&frame_data->render_pass_list);
+ SetRenderPasses(&render_pass_list);
have_render_passes_to_push_ = true;
}
@@ -184,7 +179,6 @@ void DelegatedRendererLayerImpl::SetRenderPasses(
}
void DelegatedRendererLayerImpl::ClearRenderPasses() {
- // TODO(danakj): Release the resources back to the nested compositor.
render_passes_index_by_id_.clear();
render_passes_in_draw_order_.clear();
}
@@ -271,6 +265,7 @@ void DelegatedRendererLayerImpl::AppendQuads(
AppendQuadsData* append_quads_data) {
AppendRainbowDebugBorder(quad_sink, append_quads_data);
+ // This list will be empty after a lost context until a new frame arrives.
if (render_passes_in_draw_order_.empty())
return;
diff --git a/cc/layers/delegated_renderer_layer_impl.h b/cc/layers/delegated_renderer_layer_impl.h
index 7d774f1..358b7b9 100644
--- a/cc/layers/delegated_renderer_layer_impl.h
+++ b/cc/layers/delegated_renderer_layer_impl.h
@@ -45,7 +45,7 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl {
// inform when resources are no longer in use.
void CreateChildIdIfNeeded(const ReturnCallback& return_callback);
- void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data,
+ void SetFrameData(const DelegatedFrameData* frame_data,
gfx::RectF damage_in_frame);
void SetDisplaySize(gfx::Size size);
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 3d4554c..fbc577f 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1479,6 +1479,11 @@ GLint ResourceProvider::WrapModeForTesting(ResourceId id) {
return resource->wrap_mode;
}
+GLenum ResourceProvider::TargetForTesting(ResourceId id) {
+ Resource* resource = GetResource(id);
+ return resource->target;
+}
+
void ResourceProvider::LazyCreate(Resource* resource) {
if (resource->type != GLTexture || resource->gl_id != 0)
return;
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 034bb7a..95f18ad 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -327,6 +327,7 @@ class CC_EXPORT ResourceProvider {
void CreateForTesting(ResourceId id);
GLint WrapModeForTesting(ResourceId id);
+ GLenum TargetForTesting(ResourceId id);
// Sets the current read fence. If a resource is locked for read
// and has read fences enabled, the resource will not allow writes
diff --git a/cc/test/fake_delegated_renderer_layer.cc b/cc/test/fake_delegated_renderer_layer.cc
index 5b625a9..45518b3 100644
--- a/cc/test/fake_delegated_renderer_layer.cc
+++ b/cc/test/fake_delegated_renderer_layer.cc
@@ -9,8 +9,9 @@
namespace cc {
FakeDelegatedRendererLayer::FakeDelegatedRendererLayer(
- DelegatedRendererLayerClient* client)
- : DelegatedRendererLayer(client) {}
+ DelegatedRendererLayerClient* client,
+ DelegatedFrameProvider* frame_provider)
+ : DelegatedRendererLayer(client, frame_provider) {}
FakeDelegatedRendererLayer::~FakeDelegatedRendererLayer() {}
diff --git a/cc/test/fake_delegated_renderer_layer.h b/cc/test/fake_delegated_renderer_layer.h
index d90d25f..e1ff6d5 100644
--- a/cc/test/fake_delegated_renderer_layer.h
+++ b/cc/test/fake_delegated_renderer_layer.h
@@ -12,15 +12,18 @@ namespace cc {
class FakeDelegatedRendererLayer : public DelegatedRendererLayer {
public:
static scoped_refptr<FakeDelegatedRendererLayer> Create(
- DelegatedRendererLayerClient* client) {
- return make_scoped_refptr(new FakeDelegatedRendererLayer(client));
+ DelegatedRendererLayerClient* client,
+ DelegatedFrameProvider* frame_provider) {
+ return make_scoped_refptr(
+ new FakeDelegatedRendererLayer(client, frame_provider));
}
virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
OVERRIDE;
protected:
- explicit FakeDelegatedRendererLayer(DelegatedRendererLayerClient* client);
+ explicit FakeDelegatedRendererLayer(DelegatedRendererLayerClient* client,
+ DelegatedFrameProvider* frame_provider);
virtual ~FakeDelegatedRendererLayer();
};
diff --git a/cc/test/fake_delegated_renderer_layer_impl.cc b/cc/test/fake_delegated_renderer_layer_impl.cc
index 14d8062..4057736 100644
--- a/cc/test/fake_delegated_renderer_layer_impl.cc
+++ b/cc/test/fake_delegated_renderer_layer_impl.cc
@@ -8,6 +8,7 @@
#include "cc/output/delegated_frame_data.h"
#include "cc/quads/draw_quad.h"
#include "cc/resources/returned_resource.h"
+#include "cc/trees/layer_tree_impl.h"
namespace cc {
@@ -24,11 +25,12 @@ scoped_ptr<LayerImpl> FakeDelegatedRendererLayerImpl::CreateLayerImpl(
}
static ResourceProvider::ResourceId AddResourceToFrame(
+ ResourceProvider* resource_provider,
DelegatedFrameData* frame,
ResourceProvider::ResourceId resource_id) {
TransferableResource resource;
resource.id = resource_id;
- resource.target = GL_TEXTURE_2D;
+ resource.target = resource_provider->TargetForTesting(resource_id);
frame->resource_list.push_back(resource);
return resource_id;
}
@@ -50,9 +52,10 @@ void FakeDelegatedRendererLayerImpl::SetFrameDataForRenderPasses(
scoped_ptr<DelegatedFrameData> delegated_frame(new DelegatedFrameData);
delegated_frame->render_pass_list.swap(*pass_list);
+ ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
+
DrawQuad::ResourceIteratorCallback add_resource_to_frame_callback =
- base::Bind(&AddResourceToFrame,
- delegated_frame.get());
+ base::Bind(&AddResourceToFrame, resource_provider, delegated_frame.get());
for (size_t i = 0; i < delegated_frame->render_pass_list.size(); ++i) {
RenderPass* pass = delegated_frame->render_pass_list[i];
for (size_t j = 0; j < pass->quad_list.size(); ++j)
@@ -60,7 +63,7 @@ void FakeDelegatedRendererLayerImpl::SetFrameDataForRenderPasses(
}
CreateChildIdIfNeeded(base::Bind(&NoopReturnCallback));
- SetFrameData(delegated_frame.Pass(), gfx::RectF());
+ SetFrameData(delegated_frame.get(), gfx::RectF());
}
} // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index f2785a6..0c0a8de 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -8,6 +8,8 @@
#include "cc/debug/test_context_provider.h"
#include "cc/debug/test_web_graphics_context_3d.h"
#include "cc/layers/content_layer.h"
+#include "cc/layers/delegated_frame_provider.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/io_surface_layer.h"
#include "cc/layers/layer_impl.h"
@@ -1113,8 +1115,20 @@ class LayerTreeHostContextTestDontUseLostResources
root->SetAnchorPoint(gfx::PointF());
root->SetIsDrawable(true);
+ scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
+ frame_data->render_pass_list.push_back(RenderPass::Create());
+ frame_data->render_pass_list.back()->SetNew(RenderPass::Id(1, 0),
+ gfx::Rect(10, 10),
+ gfx::Rect(10, 10),
+ gfx::Transform());
+
+ delegated_resource_collection_ = new DelegatedFrameResourceCollection;
+ delegated_frame_provider_ = new DelegatedFrameProvider(
+ delegated_resource_collection_.get(), frame_data.Pass());
+
scoped_refptr<FakeDelegatedRendererLayer> delegated =
- FakeDelegatedRendererLayer::Create(NULL);
+ FakeDelegatedRendererLayer::Create(NULL,
+ delegated_frame_provider_.get());
delegated->SetBounds(gfx::Size(10, 10));
delegated->SetAnchorPoint(gfx::PointF());
delegated->SetIsDrawable(true);
@@ -1327,6 +1341,10 @@ class LayerTreeHostContextTestDontUseLostResources
FakeContentLayerClient client_;
bool lost_context_;
+ scoped_refptr<DelegatedFrameResourceCollection>
+ delegated_resource_collection_;
+ scoped_refptr<DelegatedFrameProvider> delegated_frame_provider_;
+
scoped_refptr<VideoFrame> color_video_frame_;
scoped_refptr<VideoFrame> hw_video_frame_;
scoped_refptr<VideoFrame> scaled_hw_video_frame_;
diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc
index 34a2b94..ae7e47f 100644
--- a/cc/trees/layer_tree_host_unittest_delegated.cc
+++ b/cc/trees/layer_tree_host_unittest_delegated.cc
@@ -11,6 +11,8 @@
#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_client.h"
#include "cc/layers/delegated_renderer_layer_impl.h"
@@ -189,12 +191,6 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>());
}
- scoped_ptr<DelegatedFrameData> CreateEmptyFrameData() {
- scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData);
- return frame.Pass();
- }
-
-
static ResourceProvider::ResourceId AppendResourceId(
std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame,
ResourceProvider::ResourceId resource_id) {
@@ -209,13 +205,9 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
return;
std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame;
- for (size_t i = 0; i < delegated_frame_data->render_pass_list.size(); ++i) {
- RenderPass* pass = delegated_frame_data->render_pass_list.at(i);
- for (size_t j = 0; j < pass->quad_list.size(); ++j) {
- DrawQuad* quad = pass->quad_list[j];
- quad->IterateResources(base::Bind(&AppendResourceId,
- &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;
@@ -246,33 +238,68 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest {
class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
: public LayerTreeHostDelegatedTest,
- public DelegatedRendererLayerClient {
+ public DelegatedRendererLayerClient,
+ public DelegatedFrameResourceCollectionClient {
public:
- LayerTreeHostDelegatedTestCaseSingleDelegatedLayer() : available_(false) {}
+ 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));
- delegated_ = FakeDelegatedRendererLayer::Create(this);
- delegated_->SetAnchorPoint(gfx::PointF());
- delegated_->SetBounds(gfx::Size(10, 10));
- delegated_->SetIsDrawable(true);
-
- root_->AddChild(delegated_);
layer_tree_host()->SetRootLayer(root_);
LayerTreeHostDelegatedTest::SetupTree();
}
virtual void BeginTest() OVERRIDE {
+ resource_collection_->SetClient(this);
PostSetNeedsCommitToMainThread();
}
- virtual void AfterTest() OVERRIDE {}
+ 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(this, 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); }
// DelegatedRendererLayerClient implementation.
virtual void DidCommitFrameData() OVERRIDE {}
+
+ // DelegatedFrameProviderClient implementation.
virtual void UnusedResourcesAreAvailable() OVERRIDE { available_ = true; }
bool TestAndResetAvailable() {
@@ -282,6 +309,8 @@ class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer
}
protected:
+ scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
+ scoped_refptr<DelegatedFrameProvider> frame_provider_;
scoped_refptr<Layer> root_;
scoped_refptr<DelegatedRendererLayer> delegated_;
bool available_;
@@ -303,8 +332,7 @@ class LayerTreeHostDelegatedTestClientDidCommitCallback
}
virtual void BeginTest() OVERRIDE {
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1),
- gfx::Rect(0, 0, 1, 1)));
+ SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
PostSetNeedsCommitToMainThread();
}
@@ -330,11 +358,13 @@ class LayerTreeHostDelegatedTestCreateChildId
virtual void DidCommit() OVERRIDE {
if (TestEnded())
return;
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1),
- gfx::Rect(0, 0, 1, 1)));
+ 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]);
@@ -376,8 +406,6 @@ class LayerTreeHostDelegatedTestCreateChildId
did_reset_child_id_ = true;
}
- virtual void AfterTest() OVERRIDE {}
-
protected:
int num_activates_;
bool did_reset_child_id_;
@@ -392,7 +420,7 @@ class LayerTreeHostDelegatedTestOffscreenContext_NoFilters
scoped_ptr<DelegatedFrameData> frame =
CreateFrameData(gfx::Rect(0, 0, 1, 1),
gfx::Rect(0, 0, 1, 1));
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
@@ -401,8 +429,6 @@ class LayerTreeHostDelegatedTestOffscreenContext_NoFilters
EXPECT_FALSE(host_impl->offscreen_context_provider());
EndTest();
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -424,7 +450,7 @@ class LayerTreeHostDelegatedTestOffscreenContext_Filters
gfx::Rect(0, 0, 1, 1),
filters,
FilterOperations());
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
@@ -434,8 +460,6 @@ class LayerTreeHostDelegatedTestOffscreenContext_Filters
EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
EndTest();
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -457,7 +481,7 @@ class LayerTreeHostDelegatedTestOffscreenContext_BackgroundFilters
gfx::Rect(0, 0, 1, 1),
FilterOperations(),
filters);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
@@ -467,8 +491,6 @@ class LayerTreeHostDelegatedTestOffscreenContext_BackgroundFilters
EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
EndTest();
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -478,21 +500,24 @@ class LayerTreeHostDelegatedTestOffscreenContext_Filters_AddedToTree
: public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer {
protected:
virtual void BeginTest() OVERRIDE {
- scoped_ptr<DelegatedFrameData> frame =
- CreateFrameData(gfx::Rect(0, 0, 1, 1),
- gfx::Rect(0, 0, 1, 1));
+ 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.get(),
+ 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();
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame_with_filters.Pass());
layer_tree_host()->root_layer()->AddChild(delegated_);
PostSetNeedsCommitToMainThread();
@@ -503,8 +528,6 @@ class LayerTreeHostDelegatedTestOffscreenContext_Filters_AddedToTree
EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider());
EndTest();
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -523,101 +546,112 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage
case 1:
// The first time the layer gets a frame the whole layer should be
// damaged.
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1),
- gfx::Rect(0, 0, 1, 1)));
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)));
break;
case 2:
+ // A different frame size will damage the whole layer.
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(0, 0, 0, 0)));
+ break;
+ case 3:
// Should create a total amount of gfx::Rect(2, 2, 10, 6) damage.
// The frame size is 20x20 while the layer is 10x10, so this should
// produce a gfx::Rect(1, 1, 5, 3) damage rect.
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 20, 20),
- gfx::Rect(2, 2, 5, 5)));
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 20, 20),
- gfx::Rect(7, 2, 5, 6)));
+ 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 3:
+ case 4:
// Should create zero damage.
layer_tree_host()->SetNeedsCommit();
break;
- case 4:
+ case 5:
// Should damage the full viewport.
delegated_->SetBounds(gfx::Size(2, 2));
break;
- case 5:
+ case 6:
// Should create zero damage.
layer_tree_host()->SetNeedsCommit();
break;
- case 6:
- // Should damage the full layer.
+ case 7:
+ // Should damage the full layer, tho the frame size is not changing.
delegated_->SetBounds(gfx::Size(6, 6));
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 5, 5),
- gfx::Rect(1, 1, 2, 2)));
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 20, 20), gfx::Rect(1, 1, 2, 2)));
break;
- case 7:
+ case 8:
// Should create zero damage.
layer_tree_host()->SetNeedsCommit();
break;
- case 8:
+ case 9:
// Should damage the full layer.
delegated_->SetDisplaySize(gfx::Size(10, 10));
break;
- case 9:
+ case 10:
// Should create zero damage.
layer_tree_host()->SetNeedsCommit();
break;
- case 10:
- // Setting an empty frame should damage the whole layer the
- // first time.
- delegated_->SetFrameData(CreateEmptyFrameData());
- break;
case 11:
- // Setting an empty frame shouldn't damage anything after the
- // first time.
- delegated_->SetFrameData(CreateEmptyFrameData());
+ // Changing the frame size damages the full layer.
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(4, 4, 1, 1)));
break;
case 12:
- // Having valid content to display agains should damage the whole layer.
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 10, 10),
- gfx::Rect(5, 5, 1, 1)));
- break;
- case 13:
// An invalid frame isn't used, so it should not cause damage.
- delegated_->SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 10, 10),
- gfx::Rect(5, 5, 1, 1)));
+ SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 5, 5),
+ gfx::Rect(4, 4, 1, 1)));
break;
- case 14:
+ case 13:
// Should create gfx::Rect(1, 1, 2, 2) of damage. The frame size is
// 5x5 and the display size is now set to 10x10, so this should result
// in a gfx::Rect(2, 2, 4, 4) damage rect.
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 5, 5),
- gfx::Rect(1, 1, 2, 2)));
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2)));
break;
- case 15:
+ case 14:
// Should create zero damage.
layer_tree_host()->SetNeedsCommit();
break;
- case 16:
+ case 15:
// Moving the layer out of the tree and back in will damage the whole
// impl layer.
delegated_->RemoveFromParent();
layer_tree_host()->root_layer()->AddChild(delegated_);
break;
- case 17:
+ case 16:
// Make a larger frame with lots of damage. Then a frame smaller than
// the first frame's damage. The entire layer should be damaged, but
// nothing more.
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 10, 10),
- gfx::Rect(0, 0, 10, 10)));
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 5, 5),
- gfx::Rect(1, 1, 2, 2)));
+ 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 18:
- // Make a frame with lots of damage. Then replace it with an empty
- // frame. The entire layer should be damaged, but nothing more.
- delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 10, 10),
- gfx::Rect(0, 0, 10, 10)));
- delegated_->SetFrameData(CreateEmptyFrameData());
+ case 17:
+ // Make a frame with lots of damage. Then replace it with a frame with
+ // no damage. The entire layer should be damaged, but nothing more.
+ 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:
+ // Make another layer that uses the same frame provider. The new layer
+ // should be damaged.
+ delegated_copy_ = CreateDelegatedLayer(frame_provider_);
+ delegated_copy_->SetPosition(gfx::Point(5, 0));
+
+ // Also set a new frame.
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(4, 0, 1, 1)));
+ break;
+ case 19:
+ // Set another new frame, both layers should be damaged in the same
+ // ways.
+ SetFrameData(
+ CreateFrameData(gfx::Rect(0, 0, 10, 10), gfx::Rect(3, 3, 1, 1)));
}
first_draw_for_source_frame_ = true;
}
@@ -649,71 +683,76 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage
damage_rect.ToString());
break;
case 2:
- EXPECT_EQ(gfx::RectF(1.f, 1.f, 5.f, 3.f).ToString(),
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 3:
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
+ 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, 10.f, 10.f).ToString(),
+ 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, 0.f, 0.f).ToString(),
+ 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, 6.f, 6.f).ToString(),
+ 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, 0.f, 0.f).ToString(),
+ 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, 6.f, 6.f).ToString(),
+ 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, 0.f, 0.f).ToString(),
+ 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, 6.f, 6.f).ToString(),
+ 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, 0.f, 0.f).ToString(),
+ 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, 6.f, 6.f).ToString(),
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
damage_rect.ToString());
break;
case 13:
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(),
+ EXPECT_EQ(gfx::RectF(2.f, 2.f, 4.f, 4.f).ToString(),
damage_rect.ToString());
break;
case 14:
- EXPECT_EQ(gfx::RectF(2.f, 2.f, 4.f, 4.f).ToString(),
+ 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, 0.f, 0.f).ToString(),
+ 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, 6.f, 6.f).ToString(),
+ 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, 6.f, 6.f).ToString(),
+ EXPECT_EQ(gfx::RectF(0.f, 0.f, 10.f, 10.f).ToString(),
damage_rect.ToString());
break;
case 18:
- EXPECT_EQ(gfx::RectF(0.f, 0.f, 6.f, 6.f).ToString(),
+ 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;
@@ -723,6 +762,7 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage
}
protected:
+ scoped_refptr<DelegatedRendererLayer> delegated_copy_;
bool first_draw_for_source_frame_;
};
@@ -739,7 +779,7 @@ class LayerTreeHostDelegatedTestMergeResources
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame1.get(), 999);
AddTransferableResource(frame1.get(), 999);
- delegated_->SetFrameData(frame1.Pass());
+ SetFrameData(frame1.Pass());
// The second frame uses resource 999 still, but also adds 555.
scoped_ptr<DelegatedFrameData> frame2 =
@@ -748,12 +788,13 @@ class LayerTreeHostDelegatedTestMergeResources
AddTransferableResource(frame2.get(), 999);
AddTextureQuad(frame2.get(), 555);
AddTransferableResource(frame2.get(), 555);
- delegated_->SetFrameData(frame2.Pass());
+ SetFrameData(frame2.Pass());
// The resource 999 from frame1 is returned since it is still on the main
// thread.
ReturnedResourceArray returned_resources;
- delegated_->TakeUnusedResourcesForChildCompositor(&returned_resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(
+ &returned_resources);
{
unsigned expected[] = {999};
EXPECT_RESOURCES(expected, returned_resources);
@@ -783,8 +824,6 @@ class LayerTreeHostDelegatedTestMergeResources
EndTest();
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources);
@@ -800,7 +839,7 @@ class LayerTreeHostDelegatedTestRemapResourcesInQuads
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
@@ -834,8 +873,6 @@ class LayerTreeHostDelegatedTestRemapResourcesInQuads
EndTest();
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads);
@@ -860,11 +897,11 @@ class LayerTreeHostDelegatedTestReturnUnusedResources
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
// All of the resources are in use.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -874,11 +911,11 @@ class LayerTreeHostDelegatedTestReturnUnusedResources
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 3:
// 555 is no longer in use.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555};
EXPECT_RESOURCES(expected, resources);
@@ -887,7 +924,7 @@ class LayerTreeHostDelegatedTestReturnUnusedResources
// Stop using any resources.
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 4:
// Postpone collecting resources for a frame. They should still be there
@@ -897,7 +934,7 @@ class LayerTreeHostDelegatedTestReturnUnusedResources
case 5:
// 444 and 999 are no longer in use. We sent two refs to 999, so we
// should get two back.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 999, 999};
EXPECT_RESOURCES(expected, resources);
@@ -909,7 +946,8 @@ class LayerTreeHostDelegatedTestReturnUnusedResources
// Resources are never immediately released.
ReturnedResourceArray empty_resources;
- delegated_->TakeUnusedResourcesForChildCompositor(&empty_resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(
+ &empty_resources);
EXPECT_EQ(0u, empty_resources.size());
EXPECT_FALSE(TestAndResetAvailable());
}
@@ -918,8 +956,6 @@ class LayerTreeHostDelegatedTestReturnUnusedResources
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -947,11 +983,11 @@ class LayerTreeHostDelegatedTestReusedResources
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
// All of the resources are in use.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -959,10 +995,10 @@ class LayerTreeHostDelegatedTestReusedResources
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// Resource are not immediately released.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -972,12 +1008,12 @@ class LayerTreeHostDelegatedTestReusedResources
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 3:
// The 999 resource is the only unused one. Two references were sent, so
// two should be returned.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {999, 999};
EXPECT_RESOURCES(expected, resources);
@@ -992,8 +1028,6 @@ class LayerTreeHostDelegatedTestReusedResources
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources);
@@ -1020,11 +1054,11 @@ class LayerTreeHostDelegatedTestFrameBeforeAck
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
// All of the resources are in use.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1032,17 +1066,17 @@ class LayerTreeHostDelegatedTestFrameBeforeAck
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// Resource are not immediately released.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
// The parent compositor (this one) does a commit.
break;
case 3:
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 555};
EXPECT_RESOURCES(expected, resources);
@@ -1055,7 +1089,7 @@ class LayerTreeHostDelegatedTestFrameBeforeAck
AddTextureQuad(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
}
}
@@ -1094,8 +1128,6 @@ class LayerTreeHostDelegatedTestFrameBeforeAck
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck);
@@ -1122,11 +1154,11 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
// All of the resources are in use.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1134,10 +1166,10 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// Resource are not immediately released.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1154,11 +1186,11 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// The resources are used by the new frame but are returned anyway since
// we passed them again.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 555};
EXPECT_RESOURCES(expected, resources);
@@ -1166,7 +1198,7 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources
}
break;
case 4:
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
EndTest();
@@ -1215,8 +1247,6 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -1242,11 +1272,11 @@ class LayerTreeHostDelegatedTestBadFrame
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
// All of the resources are in use.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1260,27 +1290,31 @@ class LayerTreeHostDelegatedTestBadFrame
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
AddTextureQuad(frame.get(), 775);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// The parent compositor (this one) does a commit.
break;
case 3:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Now send a good frame with 999 again.
+ frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
+ AddTextureQuad(frame.get(), 999);
+ SetFrameData(frame.Pass());
+
// The bad frame's resource is given back to the child compositor.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444};
EXPECT_RESOURCES(expected, resources);
EXPECT_TRUE(TestAndResetAvailable());
}
-
- // Now send a good frame with 999 again.
- frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
- AddTextureQuad(frame.get(), 999);
- delegated_->SetFrameData(frame.Pass());
break;
case 4:
// The unused 555 from the last good frame is now released.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555};
EXPECT_RESOURCES(expected, resources);
@@ -1368,8 +1402,6 @@ class LayerTreeHostDelegatedTestBadFrame
}
}
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame);
@@ -1393,11 +1425,19 @@ class LayerTreeHostDelegatedTestUnnamedResource
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Now send an empty frame.
+ frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
+ SetFrameData(frame.Pass());
+
// The unused resource should be returned.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {999};
EXPECT_RESOURCES(expected, resources);
@@ -1428,8 +1468,6 @@ class LayerTreeHostDelegatedTestUnnamedResource
EXPECT_EQ(1u, delegated_impl->Resources().size());
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource);
@@ -1454,18 +1492,18 @@ class LayerTreeHostDelegatedTestDontLeakResource
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// But then we immediately stop using 999.
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
// The unused resources should be returned. 555 is still used, but it's
// returned once to account for the first frame.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 999};
EXPECT_RESOURCES(expected, resources);
@@ -1473,12 +1511,12 @@ class LayerTreeHostDelegatedTestDontLeakResource
}
// Send a frame with no resources in it.
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 3:
// The now unused resource 555 should be returned.
resources.clear();
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555};
EXPECT_RESOURCES(expected, resources);
@@ -1513,8 +1551,6 @@ class LayerTreeHostDelegatedTestDontLeakResource
bool result) OVERRIDE {
ReturnUnusedResourcesFromParent(host_impl);
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource);
@@ -1535,10 +1571,10 @@ class LayerTreeHostDelegatedTestResourceSentToParent
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1547,11 +1583,11 @@ class LayerTreeHostDelegatedTestResourceSentToParent
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 3:
// Since 999 is in the grandparent it is not returned.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1584,7 +1620,7 @@ class LayerTreeHostDelegatedTestResourceSentToParent
ReturnedResourceArray resources;
// 999 was returned from the grandparent and could be released.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {999};
EXPECT_RESOURCES(expected, resources);
@@ -1645,8 +1681,6 @@ class LayerTreeHostDelegatedTestResourceSentToParent
}
}
- virtual void AfterTest() OVERRIDE {}
-
base::Closure receive_resource_on_thread_;
};
@@ -1676,10 +1710,10 @@ class LayerTreeHostDelegatedTestCommitWithoutTake
AddTransferableResource(frame.get(), 555);
AddTextureQuad(frame.get(), 444);
AddTransferableResource(frame.get(), 444);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 2:
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
EXPECT_EQ(0u, resources.size());
EXPECT_FALSE(TestAndResetAvailable());
@@ -1687,7 +1721,7 @@ class LayerTreeHostDelegatedTestCommitWithoutTake
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// 999 and 444 will be returned for frame 1, but not 555 since it's in
// the current frame.
break;
@@ -1698,12 +1732,12 @@ class LayerTreeHostDelegatedTestCommitWithoutTake
AddTransferableResource(frame.get(), 999);
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
break;
case 4:
// 555 from frame 1 and 2 isn't returned since it's still in use. 999
// from frame 1 is returned though.
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {444, 999};
EXPECT_RESOURCES(expected, resources);
@@ -1711,12 +1745,12 @@ class LayerTreeHostDelegatedTestCommitWithoutTake
}
frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// 555 will be returned 3 times for frames 1 2 and 3, and 999 will be
// returned once for frame 3.
break;
case 5:
- delegated_->TakeUnusedResourcesForChildCompositor(&resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
{
unsigned expected[] = {555, 555, 555, 999};
EXPECT_RESOURCES(expected, resources);
@@ -1769,8 +1803,6 @@ class LayerTreeHostDelegatedTestCommitWithoutTake
EXPECT_EQ(1u, delegated_impl->Resources().count(555));
}
}
-
- virtual void AfterTest() OVERRIDE {}
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCommitWithoutTake);
@@ -1791,7 +1823,7 @@ class DelegatedFrameIsActivatedDuringCommit
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 999);
AddTransferableResource(frame.get(), 999);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
PostSetNeedsCommitToMainThread();
}
@@ -1829,7 +1861,7 @@ class DelegatedFrameIsActivatedDuringCommit
CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
AddTextureQuad(frame.get(), 555);
AddTransferableResource(frame.get(), 555);
- delegated_->SetFrameData(frame.Pass());
+ SetFrameData(frame.Pass());
// So this commit number should complete after the second activate.
EXPECT_EQ(1, layer_tree_host()->source_frame_number());
break;
@@ -1860,14 +1892,23 @@ class DelegatedFrameIsActivatedDuringCommit
// The activate to remove the layer should have happened before now.
base::AutoLock lock(activate_lock_);
EXPECT_EQ(3, activate_count_);
+
+ scoped_ptr<DelegatedFrameData> frame =
+ CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
+ SetFrameData(frame.Pass());
+
+ ReturnedResourceArray resources;
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ {
+ unsigned expected[] = {999, 555};
+ EXPECT_RESOURCES(expected, resources);
+ EXPECT_TRUE(TestAndResetAvailable());
+ }
break;
}
}
}
-
- virtual void AfterTest() OVERRIDE {}
-
base::Thread wait_thread_;
base::WaitableEvent wait_event_;
base::Lock activate_lock_;
@@ -1877,5 +1918,398 @@ class DelegatedFrameIsActivatedDuringCommit
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());
+
+ // Remove the delegated layer and replace it with a new one. Use the
+ // same frame and resources for it.
+ delegated_->RemoveFromParent();
+ delegated_ = CreateDelegatedLayer(frame_provider_.get());
+ break;
+ case 3:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Use a frame with no resources in it.
+ frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
+ SetFrameData(frame.Pass());
+ break;
+ case 4:
+ // We gave one frame to the frame provider, so we should get one
+ // ref back for each resource.
+ 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);
+
+ // Remove the delegated layer and replace it with a new one. Make a new
+ // frame but with the same resources for it.
+ 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());
+
+ // Use a frame with no resources in it.
+ frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1));
+ SetFrameData(frame.Pass());
+ break;
+ case 4:
+ // We gave two frames to the frame provider, so we should get two
+ // refs back for each resource.
+ 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);
+
+ // Create a DelegatedRendererLayer using the frame.
+ SetFrameData(frame.Pass());
+ break;
+ case 2:
+ // Create a second DelegatedRendererLayer using the same frame provider.
+ delegated_thief_ = CreateDelegatedLayer(frame_provider_.get());
+ root_->AddChild(delegated_thief_);
+
+ // And drop our ref on the frame provider so only the layers keep it
+ // alive.
+ frame_provider_ = NULL;
+ break;
+ case 3:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Remove one delegated layer from the tree. No resources should be
+ // returned yet.
+ delegated_->RemoveFromParent();
+ break;
+ case 4:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Put the first layer back, and remove the other layer and destroy it.
+ // No resources should be returned yet.
+ root_->AddChild(delegated_);
+ delegated_thief_->RemoveFromParent();
+ delegated_thief_ = NULL;
+ break;
+ case 5:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Remove the first layer from the tree again. The resources are still
+ // held by the main thread layer.
+ delegated_->RemoveFromParent();
+ break;
+ case 6:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Destroy the layer and the resources should be returned immediately.
+ 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);
+
+ // Create a DelegatedRendererLayer using the frame.
+ SetFrameData(frame.Pass());
+ break;
+ case 2:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Remove the layer from the tree. The resources should not be returned
+ // since they are still on the main thread layer.
+ delegated_->RemoveFromParent();
+ break;
+ case 3:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Add the layer back to the tree.
+ layer_tree_host()->root_layer()->AddChild(delegated_);
+ break;
+ case 4:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Set a new frame. Resources should be returned.
+ 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());
+ }
+
+ // Destroy the layer.
+ delegated_->RemoveFromParent();
+ delegated_ = NULL;
+ break;
+ case 6:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Destroy the frame provider. Resources should be returned.
+ 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);
+
+ // Create a DelegatedRendererLayer using the frame.
+ SetFrameData(frame.Pass());
+ break;
+ case 2:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Remove the layer from the tree. The resources should not be returned
+ // since they are still on the main thread layer.
+ delegated_->RemoveFromParent();
+ break;
+ case 3:
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Set a new frame. Resources should be returned immediately.
+ 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();
+ }
+
+ // Destroy the frame provider.
+ frame_provider_ = NULL;
+
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&resources);
+ EXPECT_EQ(0u, resources.size());
+ EXPECT_FALSE(TestAndResetAvailable());
+
+ // Destroy the layer. Resources should be returned.
+ 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);
+
} // namespace
} // namespace cc
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index f2a03c1..99aaf4e 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -14,6 +14,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/worker_pool.h"
+#include "cc/layers/delegated_frame_provider.h"
#include "cc/layers/delegated_renderer_layer.h"
#include "cc/layers/layer.h"
#include "cc/layers/texture_layer.h"
@@ -99,6 +100,11 @@ void CopyFromCompositingSurfaceFinished(
callback.Run(result, *bitmap);
}
+bool UsingDelegatedRenderer() {
+ return CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableDelegatedRenderer);
+}
+
} // anonymous namespace
RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
@@ -115,17 +121,11 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
weak_ptr_factory_(this),
overscroll_effect_enabled_(true),
flush_input_requested_(false) {
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableDelegatedRenderer)) {
- delegated_renderer_layer_ = cc::DelegatedRendererLayer::Create(this);
- layer_ = delegated_renderer_layer_;
- } else {
+ if (!UsingDelegatedRenderer()) {
texture_layer_ = cc::TextureLayer::Create(this);
layer_ = texture_layer_;
}
- layer_->SetContentsOpaque(true);
-
overscroll_effect_enabled_ = !CommandLine::ForCurrentProcess()->
HasSwitch(switches::kDisableOverscrollEdgeEffect);
// Don't block the main thread with effect resource loading.
@@ -283,9 +283,20 @@ bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
}
bool RenderWidgetHostViewAndroid::HasValidFrame() const {
- return texture_id_in_layer_ != 0 &&
- content_view_core_ &&
- !texture_size_in_layer_.IsEmpty();
+ if (!content_view_core_)
+ return false;
+ if (texture_size_in_layer_.IsEmpty())
+ return false;
+
+ if (UsingDelegatedRenderer()) {
+ if (!delegated_renderer_layer_.get())
+ return false;
+ } else {
+ if (texture_id_in_layer_ == 0)
+ return false;
+ }
+
+ return true;
}
gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
@@ -638,25 +649,69 @@ void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
uint32 output_surface_id) {
cc::CompositorFrameAck ack;
- delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(
- &ack.resources);
- RenderWidgetHostImpl::SendSwapCompositorFrameAck(
- host_->GetRoutingID(), output_surface_id,
- host_->GetProcess()->GetID(), ack);
+ if (resource_collection_.get())
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
+ output_surface_id,
+ host_->GetProcess()->GetID(),
+ ack);
+}
+
+void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
+ // TODO(danakj): If no ack is pending, collect and send resources now.
+}
+
+void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
+ RemoveLayers();
+ frame_provider_ = NULL;
+ delegated_renderer_layer_ = NULL;
+ layer_ = NULL;
}
void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
uint32 output_surface_id,
scoped_ptr<cc::DelegatedFrameData> frame_data) {
- bool has_frame = frame_data.get() && !frame_data->render_pass_list.empty();
+ bool has_content = !texture_size_in_layer_.IsEmpty();
+
+ if (output_surface_id != current_mailbox_output_surface_id_) {
+ // TODO(danakj): Lose all resources and send them back here, such as:
+ // resource_collection_->LoseAllResources();
+ // SendReturnedDelegatedResources(last_output_surface_id_);
+
+ // Drop the cc::DelegatedFrameResourceCollection so that we will not return
+ // any resources from the old output surface with the new output surface id.
+ resource_collection_ = NULL;
+ DestroyDelegatedContent();
+ }
+
+ if (!has_content) {
+ DestroyDelegatedContent();
+ } else {
+ if (!resource_collection_) {
+ resource_collection_ = new cc::DelegatedFrameResourceCollection;
+ resource_collection_->SetClient(this);
+ }
+ if (!frame_provider_ ||
+ texture_size_in_layer_ != frame_provider_->frame_size()) {
+ RemoveLayers();
+ frame_provider_ = new cc::DelegatedFrameProvider(
+ resource_collection_.get(), frame_data.Pass());
+ delegated_renderer_layer_ =
+ cc::DelegatedRendererLayer::Create(this, frame_provider_);
+ layer_ = delegated_renderer_layer_;
+ AttachLayers();
+ } else {
+ frame_provider_->SetFrameData(frame_data.Pass());
+ }
+ }
- if (has_frame) {
- delegated_renderer_layer_->SetFrameData(frame_data.Pass());
+ if (delegated_renderer_layer_.get()) {
delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
- layer_->SetIsDrawable(true);
+ delegated_renderer_layer_->SetIsDrawable(true);
+ delegated_renderer_layer_->SetContentsOpaque(true);
+ delegated_renderer_layer_->SetBounds(content_size_in_layer_);
+ delegated_renderer_layer_->SetNeedsDisplay();
}
- layer_->SetBounds(content_size_in_layer_);
- layer_->SetNeedsDisplay();
base::Closure ack_callback =
base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
@@ -692,16 +747,22 @@ void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
UpdateContentViewCoreFrameMetadata(frame->metadata);
if (frame->delegated_frame_data) {
- if (!frame->delegated_frame_data->render_pass_list.empty()) {
- texture_size_in_layer_ = frame->delegated_frame_data->render_pass_list
- .back()->output_rect.size();
- }
+ DCHECK(UsingDelegatedRenderer());
+
+ DCHECK(frame->delegated_frame_data);
+ DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
+
+ cc::RenderPass* root_pass =
+ frame->delegated_frame_data->render_pass_list.back();
+ texture_size_in_layer_ = root_pass->output_rect.size();
ComputeContentsSize(frame->metadata);
SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
return;
}
+ DCHECK(!UsingDelegatedRenderer());
+
if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
return;
@@ -798,6 +859,7 @@ void RenderWidgetHostViewAndroid::BuffersSwapped(
if (!texture_id_in_layer_) {
texture_id_in_layer_ = factory->CreateTexture();
texture_layer_->SetIsDrawable(true);
+ texture_layer_->SetContentsOpaque(true);
}
ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
@@ -817,6 +879,8 @@ void RenderWidgetHostViewAndroid::BuffersSwapped(
void RenderWidgetHostViewAndroid::AttachLayers() {
if (!content_view_core_)
return;
+ if (!layer_.get())
+ return;
content_view_core_->AttachLayer(layer_);
}
@@ -824,6 +888,8 @@ void RenderWidgetHostViewAndroid::AttachLayers() {
void RenderWidgetHostViewAndroid::RemoveLayers() {
if (!content_view_core_)
return;
+ if (!layer_.get())
+ return;
if (overscroll_effect_)
content_view_core_->RemoveLayer(overscroll_effect_->root_layer());
@@ -901,6 +967,8 @@ void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
current_mailbox_ = gpu::Mailbox();
current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId;
}
+ if (delegated_renderer_layer_.get())
+ DestroyDelegatedContent();
}
bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
@@ -1212,8 +1280,10 @@ bool RenderWidgetHostViewAndroid::PrepareTextureMailbox(
}
void RenderWidgetHostViewAndroid::OnLostResources() {
- if (texture_layer_)
+ if (texture_layer_.get())
texture_layer_->SetIsDrawable(false);
+ if (delegated_renderer_layer_.get())
+ DestroyDelegatedContent();
texture_id_in_layer_ = 0;
RunAckCallbacks();
}
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index d85c43b..5429e4a 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -14,6 +14,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/layers/delegated_renderer_layer_client.h"
#include "cc/layers/texture_layer_client.h"
#include "cc/output/begin_frame_args.h"
@@ -34,6 +35,7 @@ struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params;
namespace cc {
class CopyOutputResult;
+class DelegatedFrameProvider;
class DelegatedRendererLayer;
class Layer;
class SingleReleaseCallback;
@@ -61,6 +63,7 @@ class RenderWidgetHostViewAndroid
public BrowserAccessibilityDelegate,
public cc::TextureLayerClient,
public cc::DelegatedRendererLayerClient,
+ public cc::DelegatedFrameResourceCollectionClient,
public ImageTransportFactoryAndroidObserver {
public:
RenderWidgetHostViewAndroid(RenderWidgetHostImpl* widget,
@@ -195,7 +198,9 @@ class RenderWidgetHostViewAndroid
// cc::DelegatedRendererLayerClient implementation.
virtual void DidCommitFrameData() OVERRIDE;
- virtual void UnusedResourcesAreAvailable() OVERRIDE {}
+
+ // cc::DelegatedFrameResourceCollectionClient implementation.
+ virtual void UnusedResourcesAreAvailable() OVERRIDE;
// ImageTransportFactoryAndroidObserver implementation.
virtual void OnLostResources() OVERRIDE;
@@ -246,6 +251,7 @@ class RenderWidgetHostViewAndroid
void RunAckCallbacks();
+ void DestroyDelegatedContent();
void SwapDelegatedFrame(uint32 output_surface_id,
scoped_ptr<cc::DelegatedFrameData> frame_data);
void SendDelegatedFrameAck(uint32 output_surface_id);
@@ -297,6 +303,8 @@ class RenderWidgetHostViewAndroid
// The texture layer for this view when using browser-side compositing.
scoped_refptr<cc::TextureLayer> texture_layer_;
+ scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
scoped_refptr<cc::DelegatedRendererLayer> delegated_renderer_layer_;
// The layer used for rendering the contents of this view.
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 2f27455..1c005bf 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "cc/layers/delegated_frame_provider.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/output/copy_output_request.h"
@@ -1470,15 +1471,35 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
// resources from the old one with resources from the new one which would
// have the same id. Changing the layer to showing painted content destroys
// the DelegatedRendererLayer.
- // TODO(danakj): Lose and return all resources in the delegated layer first.
window_->layer()->SetShowPaintedContent();
+ frame_provider_ = NULL;
+
+ // TODO(danakj): Lose all resources and send them back here, such as:
+ // resource_collection_->LoseAllResources();
+ // SendReturnedDelegatedResources(last_output_surface_id_);
+
+ // Drop the cc::DelegatedFrameResourceCollection so that we will not return
+ // any resources from the old output surface with the new output surface id.
+ resource_collection_->SetClient(NULL);
+ resource_collection_ = NULL;
last_output_surface_id_ = output_surface_id;
}
if (frame_size.IsEmpty()) {
- // TODO(danakj): Return all resources in the delegated layer somehow.
+ DCHECK_EQ(0u, frame_data->resource_list.size());
window_->layer()->SetShowPaintedContent();
} else {
- window_->layer()->SetDelegatedFrame(frame_data.Pass(), frame_size_in_dip);
+ if (!resource_collection_) {
+ resource_collection_ = new cc::DelegatedFrameResourceCollection;
+ resource_collection_->SetClient(this);
+ }
+ if (!frame_provider_.get() || frame_size != frame_provider_->frame_size()) {
+ frame_provider_ = new cc::DelegatedFrameProvider(
+ resource_collection_.get(), frame_data.Pass());
+ window_->layer()->SetShowDelegatedContent(frame_provider_.get(),
+ frame_size_in_dip);
+ } else {
+ frame_provider_->SetFrameData(frame_data.Pass());
+ }
}
released_front_lock_ = NULL;
current_frame_size_ = frame_size_in_dip;
@@ -1503,10 +1524,16 @@ void RenderWidgetHostViewAura::SwapDelegatedFrame(
void RenderWidgetHostViewAura::SendDelegatedFrameAck(uint32 output_surface_id) {
cc::CompositorFrameAck ack;
- window_->layer()->TakeUnusedResourcesForChildCompositor(&ack.resources);
- RenderWidgetHostImpl::SendSwapCompositorFrameAck(
- host_->GetRoutingID(), output_surface_id,
- host_->GetProcess()->GetID(), ack);
+ if (resource_collection_)
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
+ output_surface_id,
+ host_->GetProcess()->GetID(),
+ ack);
+}
+
+void RenderWidgetHostViewAura::UnusedResourcesAreAvailable() {
+ // TODO(danakj): If no ack is pending, collect and send resources now.
}
void RenderWidgetHostViewAura::SwapSoftwareFrame(
@@ -3185,6 +3212,9 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
// The destruction of the holder may call back into the RWHVA, so do it
// early.
framebuffer_holder_ = NULL;
+
+ if (resource_collection_.get())
+ resource_collection_->SetClient(NULL);
}
void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index f5939df..bf64c2c 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -15,6 +15,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "cc/layers/delegated_frame_provider.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/resources/texture_mailbox.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/aura/image_transport_factory.h"
@@ -77,7 +79,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
public ImageTransportFactoryObserver,
public BrowserAccessibilityDelegate,
public FrameContainer,
- public base::SupportsWeakPtr<RenderWidgetHostViewAura> {
+ public base::SupportsWeakPtr<RenderWidgetHostViewAura>,
+ public cc::DelegatedFrameResourceCollectionClient {
public:
// Used to notify whenever the paint-content of the view changes.
class PaintObserver {
@@ -516,11 +519,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const ui::LatencyInfo& latency_info);
void SendDelegatedFrameAck(uint32 output_surface_id);
- void SwapSoftwareFrame(
- uint32 output_surface_id,
- scoped_ptr<cc::SoftwareFrameData> frame_data,
- float frame_device_scale_factor,
- const ui::LatencyInfo& latency_info);
+ // cc::DelegatedFrameProviderClient implementation.
+ virtual void UnusedResourcesAreAvailable() OVERRIDE;
+
+ void SwapSoftwareFrame(uint32 output_surface_id,
+ scoped_ptr<cc::SoftwareFrameData> frame_data,
+ float frame_device_scale_factor,
+ const ui::LatencyInfo& latency_info);
void SendSoftwareFrameAck(uint32 output_surface_id);
void SendReclaimSoftwareFrames();
void ReleaseSoftwareFrame(uint32 output_surface_id,
@@ -619,6 +624,14 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// skipped.
bool skipped_frames_;
+ // Holds delegated resources that have been given to a DelegatedFrameProvider,
+ // and gives back resources when they are no longer in use for return to the
+ // renderer.
+ scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
+
+ // Provides delegated frame updates to the cc::DelegatedRendererLayer.
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
+
// The size of the last frame that was swapped (even if we skipped it).
// Used to determine when the skipped_damage_ needs to be reset due to
// size changes between front- and backbuffer.
diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc
index c7a4758..12e5f34 100644
--- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc
+++ b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc
@@ -4,6 +4,8 @@
#include "content/renderer/browser_plugin/browser_plugin_compositing_helper.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/solid_color_layer.h"
#include "cc/layers/texture_layer.h"
@@ -68,11 +70,11 @@ void BrowserPluginCompositingHelper::DidCommitCompositorFrame() {
software_ack_pending_ = false;
}
- if (!delegated_layer_.get() || !ack_pending_)
+ if (!resource_collection_.get() || !ack_pending_)
return;
cc::CompositorFrameAck ack;
- delegated_layer_->TakeUnusedResourcesForChildCompositor(&ack.resources);
+ resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
browser_plugin_manager_->Send(
new BrowserPluginHostMsg_CompositorFrameACK(
@@ -337,24 +339,39 @@ void BrowserPluginCompositingHelper::OnCompositorFrameSwapped(
}
DCHECK(!texture_layer_.get());
- if (!delegated_layer_.get()) {
- delegated_layer_ = cc::DelegatedRendererLayer::Create(NULL);
+
+ cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
+ if (!frame_data)
+ return;
+
+ DCHECK(!frame_data->render_pass_list.empty());
+ cc::RenderPass* root_pass = frame_data->render_pass_list.back();
+ gfx::Size frame_size = root_pass->output_rect.size();
+
+ if (!resource_collection_) {
+ resource_collection_ = new cc::DelegatedFrameResourceCollection;
+ // TODO(danakj): Could return resources sooner if we set a client here and
+ // listened for UnusedResourcesAreAvailable().
+ }
+ if (!frame_provider_.get() || frame_provider_->frame_size() != frame_size) {
+ frame_provider_ = new cc::DelegatedFrameProvider(
+ resource_collection_.get(), frame->delegated_frame_data.Pass());
+ if (delegated_layer_.get())
+ delegated_layer_->RemoveFromParent();
+ delegated_layer_ =
+ cc::DelegatedRendererLayer::Create(NULL, frame_provider_.get());
delegated_layer_->SetIsDrawable(true);
delegated_layer_->SetContentsOpaque(true);
-
background_layer_->AddChild(delegated_layer_);
+ } else {
+ frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
}
- cc::DelegatedFrameData *frame_data = frame->delegated_frame_data.get();
- if (!frame_data)
- return;
-
CheckSizeAndAdjustLayerBounds(
frame_data->render_pass_list.back()->output_rect.size(),
frame->metadata.device_scale_factor,
delegated_layer_.get());
- delegated_layer_->SetFrameData(frame->delegated_frame_data.Pass());
last_route_id_ = route_id;
last_output_surface_id_ = output_surface_id;
last_host_id_ = host_id;
diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.h b/content/renderer/browser_plugin/browser_plugin_compositing_helper.h
index 90adeca..93eba2f 100644
--- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.h
+++ b/content/renderer/browser_plugin/browser_plugin_compositing_helper.h
@@ -23,6 +23,8 @@ class CompositorFrame;
class Layer;
class SolidColorLayer;
class TextureLayer;
+class DelegatedFrameProvider;
+class DelegatedFrameResourceCollection;
class DelegatedRendererLayer;
}
@@ -98,6 +100,9 @@ class CONTENT_EXPORT BrowserPluginCompositingHelper :
gfx::Size buffer_size_;
+ scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection_;
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider_;
+
scoped_refptr<cc::SolidColorLayer> background_layer_;
scoped_refptr<cc::TextureLayer> texture_layer_;
scoped_refptr<cc::DelegatedRendererLayer> delegated_layer_;
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index 2da468a..a1184dd 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -522,29 +522,20 @@ cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) {
return mailbox_;
}
-void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame,
- gfx::Size frame_size_in_dip) {
- DCHECK(frame && !frame->render_pass_list.empty());
-
+void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
+ gfx::Size frame_size_in_dip) {
DCHECK_EQ(type_, LAYER_TEXTURED);
+
+ scoped_refptr<cc::DelegatedRendererLayer> new_layer =
+ cc::DelegatedRendererLayer::Create(NULL, frame_provider);
+ SwitchToLayer(new_layer);
+ delegated_renderer_layer_ = new_layer;
layer_updated_externally_ = true;
+
delegated_frame_size_in_dip_ = frame_size_in_dip;
- if (!delegated_renderer_layer_.get()) {
- scoped_refptr<cc::DelegatedRendererLayer> new_layer =
- cc::DelegatedRendererLayer::Create(NULL);
- SwitchToLayer(new_layer);
- delegated_renderer_layer_ = new_layer;
- }
- delegated_renderer_layer_->SetFrameData(frame.Pass());
RecomputeDrawsContentAndUVRect();
}
-void Layer::TakeUnusedResourcesForChildCompositor(
- cc::ReturnedResourceArray* list) {
- if (delegated_renderer_layer_.get())
- delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(list);
-}
-
void Layer::SetShowPaintedContent() {
if (content_layer_.get())
return;
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index d308f60..2d21b98 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -33,7 +33,7 @@ class SkCanvas;
namespace cc {
class ContentLayer;
class CopyOutputRequest;
-class DelegatedFrameData;
+class DelegatedFrameProvider;
class DelegatedRendererLayer;
class Layer;
class ResourceUpdateQueue;
@@ -261,18 +261,14 @@ class COMPOSITOR_EXPORT Layer
float scale_factor);
cc::TextureMailbox GetTextureMailbox(float* scale_factor);
- // Sets a delegated frame, coming from a child compositor.
- void SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame,
- gfx::Size frame_size_in_dip);
+ // Begins showing delegated frames from the |frame_provider|.
+ void SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
+ gfx::Size frame_size_in_dip);
bool has_external_content() {
return texture_layer_.get() || delegated_renderer_layer_.get();
}
- // Gets unused resources to recycle to the child compositor.
- void TakeUnusedResourcesForChildCompositor(
- cc::ReturnedResourceArray* array);
-
void SetShowPaintedContent();
// Sets the layer's fill color. May only be called for LAYER_SOLID_COLOR.
@@ -494,8 +490,8 @@ class COMPOSITOR_EXPORT Layer
// Device scale factor in which mailbox_ was rendered in.
float mailbox_scale_factor_;
- // The size of the delegated frame in DIP, set when SetDelegatedFrame was
- // called.
+ // The size of the delegated frame in DIP, set when SetShowDelegatedContent
+ // was called.
gfx::Size delegated_frame_size_in_dip_;
DISALLOW_COPY_AND_ASSIGN(Layer);
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index a941d45..31fa9cc 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -12,6 +12,8 @@
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "cc/layers/delegated_frame_provider.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
#include "cc/layers/layer.h"
#include "cc/output/delegated_frame_data.h"
#include "cc/test/pixel_test_utils.h"
@@ -1312,8 +1314,14 @@ TEST_F(LayerWithDelegateTest, DelegatedLayer) {
root->Add(child.get());
DrawTree(root.get());
+ scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
+ new cc::DelegatedFrameResourceCollection;
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider;
+
// Content matches layer size.
- child->SetDelegatedFrame(MakeFrameData(gfx::Size(10, 10)), gfx::Size(10, 10));
+ frame_provider = new cc::DelegatedFrameProvider(
+ resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
+ child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(10, 10).ToString());
@@ -1324,12 +1332,15 @@ TEST_F(LayerWithDelegateTest, DelegatedLayer) {
// Content smaller than layer.
child->SetBounds(gfx::Rect(0, 0, 10, 10));
- child->SetDelegatedFrame(MakeFrameData(gfx::Size(5, 5)), gfx::Size(5, 5));
- EXPECT_EQ(child->cc_layer()->bounds().ToString(),
- gfx::Size(5, 5).ToString());
+ frame_provider = new cc::DelegatedFrameProvider(
+ resource_collection.get(), MakeFrameData(gfx::Size(5, 5)));
+ child->SetShowDelegatedContent(frame_provider, gfx::Size(5, 5));
+ EXPECT_EQ(child->cc_layer()->bounds().ToString(), gfx::Size(5, 5).ToString());
// Hi-DPI content on low-DPI layer.
- child->SetDelegatedFrame(MakeFrameData(gfx::Size(20, 20)), gfx::Size(10, 10));
+ frame_provider = new cc::DelegatedFrameProvider(
+ resource_collection.get(), MakeFrameData(gfx::Size(20, 20)));
+ child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(10, 10).ToString());
@@ -1339,7 +1350,9 @@ TEST_F(LayerWithDelegateTest, DelegatedLayer) {
gfx::Size(20, 20).ToString());
// Low-DPI content on hi-DPI layer.
- child->SetDelegatedFrame(MakeFrameData(gfx::Size(10, 10)), gfx::Size(10, 10));
+ frame_provider = new cc::DelegatedFrameProvider(
+ resource_collection.get(), MakeFrameData(gfx::Size(10, 10)));
+ child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_EQ(child->cc_layer()->bounds().ToString(),
gfx::Size(20, 20).ToString());
}
@@ -1358,9 +1371,15 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
EXPECT_TRUE(child->cc_layer());
EXPECT_EQ(before, child->cc_layer());
+ scoped_refptr<cc::DelegatedFrameResourceCollection> resource_collection =
+ new cc::DelegatedFrameResourceCollection;
+ scoped_refptr<cc::DelegatedFrameProvider> frame_provider =
+ new cc::DelegatedFrameProvider(resource_collection.get(),
+ MakeFrameData(gfx::Size(10, 10)));
+
// Showing delegated content changes the underlying cc layer.
before = child->cc_layer();
- child->SetDelegatedFrame(MakeFrameData(gfx::Size(10, 10)), gfx::Size(10, 10));
+ child->SetShowDelegatedContent(frame_provider, gfx::Size(10, 10));
EXPECT_TRUE(child->cc_layer());
EXPECT_NE(before, child->cc_layer());