summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/surfaces/display.cc13
-rw-r--r--cc/surfaces/display.h10
-rw-r--r--cc/surfaces/display_client.h1
-rw-r--r--cc/surfaces/surface_aggregator.cc7
-rw-r--r--cc/surfaces/surface_aggregator.h7
-rw-r--r--cc/surfaces/surface_aggregator_unittest.cc61
-rw-r--r--cc/surfaces/surface_damage_observer.h19
-rw-r--r--cc/surfaces/surface_factory.cc1
-rw-r--r--cc/surfaces/surface_manager.cc5
-rw-r--r--cc/surfaces/surface_manager.h13
-rw-r--r--cc/surfaces/surfaces_pixeltest.cc9
-rw-r--r--content/browser/compositor/delegated_frame_host.cc14
-rw-r--r--content/browser/compositor/gpu_process_transport_factory.cc7
-rw-r--r--content/browser/compositor/onscreen_display_client.cc28
-rw-r--r--content/browser/compositor/onscreen_display_client.h11
-rw-r--r--content/browser/compositor/surface_display_output_surface.cc3
-rw-r--r--mojo/services/surfaces/surfaces_impl.cc3
-rw-r--r--mojo/services/surfaces/surfaces_impl.h1
-rw-r--r--ui/compositor/compositor.h6
19 files changed, 183 insertions, 36 deletions
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
index b9929ba..df64a6c 100644
--- a/cc/surfaces/display.cc
+++ b/cc/surfaces/display.cc
@@ -14,6 +14,7 @@
#include "cc/surfaces/display_client.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_aggregator.h"
+#include "cc/surfaces/surface_manager.h"
namespace cc {
@@ -21,14 +22,17 @@ Display::Display(DisplayClient* client,
SurfaceManager* manager,
SharedBitmapManager* bitmap_manager)
: client_(client), manager_(manager), bitmap_manager_(bitmap_manager) {
+ manager_->AddObserver(this);
}
Display::~Display() {
+ manager_->RemoveObserver(this);
}
void Display::Resize(SurfaceId id, const gfx::Size& size) {
current_surface_id_ = id;
current_surface_size_ = size;
+ client_->DisplayDamaged();
}
void Display::InitializeOutputSurface() {
@@ -85,8 +89,10 @@ bool Display::Draw() {
if (!output_surface_)
return false;
+ contained_surfaces_.clear();
+
scoped_ptr<CompositorFrame> frame =
- aggregator_->Aggregate(current_surface_id_);
+ aggregator_->Aggregate(current_surface_id_, &contained_surfaces_);
if (!frame)
return false;
@@ -113,6 +119,11 @@ bool Display::Draw() {
return true;
}
+void Display::OnSurfaceDamaged(SurfaceId surface) {
+ if (contained_surfaces_.find(surface) != contained_surfaces_.end())
+ client_->DisplayDamaged();
+}
+
SurfaceId Display::CurrentSurfaceId() {
return current_surface_id_;
}
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h
index 93606ba..8af18b57 100644
--- a/cc/surfaces/display.h
+++ b/cc/surfaces/display.h
@@ -11,6 +11,7 @@
#include "cc/resources/returned_resource.h"
#include "cc/surfaces/surface_aggregator.h"
#include "cc/surfaces/surface_id.h"
+#include "cc/surfaces/surface_manager.h"
#include "cc/surfaces/surfaces_export.h"
namespace gfx {
@@ -28,13 +29,13 @@ class Surface;
class SurfaceAggregator;
class SurfaceIdAllocator;
class SurfaceFactory;
-class SurfaceManager;
// A Display produces a surface that can be used to draw to a physical display
// (OutputSurface). The client is responsible for creating and sizing the
// surface IDs used to draw into the display and deciding when to draw.
class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
- public RendererClient {
+ public RendererClient,
+ public SurfaceDamageObserver {
public:
Display(DisplayClient* client,
SurfaceManager* manager,
@@ -72,6 +73,9 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
virtual void SetFullRootLayerDamage() OVERRIDE {}
virtual void RunOnDemandRasterTask(Task* on_demand_raster_task) OVERRIDE {}
+ // SurfaceDamageObserver implementation.
+ virtual void OnSurfaceDamaged(SurfaceId surface) OVERRIDE;
+
private:
void InitializeOutputSurface();
@@ -86,6 +90,8 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
scoped_ptr<SurfaceAggregator> aggregator_;
scoped_ptr<DirectRenderer> renderer_;
+ std::set<SurfaceId> contained_surfaces_;
+
DISALLOW_COPY_AND_ASSIGN(Display);
};
diff --git a/cc/surfaces/display_client.h b/cc/surfaces/display_client.h
index e5f0b31..6134bf5 100644
--- a/cc/surfaces/display_client.h
+++ b/cc/surfaces/display_client.h
@@ -14,6 +14,7 @@ class OutputSurface;
class DisplayClient {
public:
virtual scoped_ptr<OutputSurface> CreateOutputSurface() = 0;
+ virtual void DisplayDamaged() = 0;
protected:
virtual ~DisplayClient() {}
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
index 7ffa965..e4e77a1 100644
--- a/cc/surfaces/surface_aggregator.cc
+++ b/cc/surfaces/surface_aggregator.cc
@@ -135,6 +135,7 @@ bool SurfaceAggregator::TakeResources(Surface* surface,
void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
RenderPass* dest_pass) {
SurfaceId surface_id = surface_quad->surface_id;
+ contained_surfaces_->insert(surface_id);
// If this surface's id is already in our referenced set then it creates
// a cycle in the graph and should be dropped.
if (referenced_surfaces_.count(surface_id))
@@ -287,7 +288,11 @@ void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list,
}
}
-scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
+scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(
+ SurfaceId surface_id,
+ std::set<SurfaceId>* contained_surfaces) {
+ contained_surfaces_ = contained_surfaces;
+ contained_surfaces_->insert(surface_id);
Surface* surface = manager_->GetSurfaceForId(surface_id);
DCHECK(surface);
const CompositorFrame* root_surface_frame = surface->GetEligibleFrame();
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
index ec36b4b..de9a6d6 100644
--- a/cc/surfaces/surface_aggregator.h
+++ b/cc/surfaces/surface_aggregator.h
@@ -29,7 +29,9 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
SurfaceAggregator(SurfaceManager* manager, ResourceProvider* provider);
~SurfaceAggregator();
- scoped_ptr<CompositorFrame> Aggregate(SurfaceId surface_id);
+ scoped_ptr<CompositorFrame> Aggregate(
+ SurfaceId surface_id,
+ std::set<SurfaceId>* contained_surfaces);
private:
RenderPass::Id RemapPassId(RenderPass::Id surface_local_pass_id,
@@ -72,6 +74,9 @@ class CC_SURFACES_EXPORT SurfaceAggregator {
typedef std::set<SurfaceId> SurfaceSet;
SurfaceSet referenced_surfaces_;
+ // This is the set of surfaces that were used in the last draw.
+ SurfaceSet* contained_surfaces_;
+
// This is the pass list for the aggregated frame.
RenderPassList* dest_pass_list_;
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
index 6525157..07d8185 100644
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ b/cc/surfaces/surface_aggregator_unittest.cc
@@ -61,7 +61,9 @@ class SurfaceAggregatorTest : public testing::Test {
TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) {
SurfaceId one_id(7);
factory_.Create(one_id, SurfaceSize());
- scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id);
+ std::set<SurfaceId> surface_set;
+ scoped_ptr<CompositorFrame> frame =
+ aggregator_.Aggregate(one_id, &surface_set);
EXPECT_FALSE(frame);
factory_.Destroy(one_id);
}
@@ -82,9 +84,12 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
}
void AggregateAndVerify(test::Pass* expected_passes,
- size_t expected_pass_count) {
+ size_t expected_pass_count,
+ SurfaceId* surface_ids,
+ size_t expected_surface_count) {
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator_.Aggregate(root_surface_id_);
+ aggregator_.Aggregate(root_surface_id_, &surface_set);
ASSERT_TRUE(aggregated_frame);
ASSERT_TRUE(aggregated_frame->delegated_frame_data);
@@ -94,6 +99,11 @@ class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
TestPassesMatchExpectations(
expected_passes, expected_pass_count, &frame_data->render_pass_list);
+
+ EXPECT_EQ(expected_surface_count, surface_set.size());
+ for (size_t i = 0; i < expected_surface_count; i++) {
+ EXPECT_TRUE(surface_set.find(surface_ids[i]) != surface_set.end());
+ }
}
void SubmitFrame(test::Pass* passes,
@@ -135,7 +145,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
SubmitFrame(passes, arraysize(passes), root_surface_id_);
- AggregateAndVerify(passes, arraysize(passes));
+ SurfaceId ids[] = {root_surface_id_};
+ AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
}
TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
@@ -148,7 +159,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
SubmitFrame(passes, arraysize(passes), root_surface_id_);
- AggregateAndVerify(passes, arraysize(passes));
+ SurfaceId ids[] = {root_surface_id_};
+ AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
}
// This tests very simple embedding. root_surface has a frame containing a few
@@ -177,7 +189,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
test::Quad::SolidColorQuad(SK_ColorBLACK)};
test::Pass expected_passes[] = {
test::Pass(expected_quads, arraysize(expected_quads))};
- AggregateAndVerify(expected_passes, arraysize(expected_passes));
+ SurfaceId ids[] = {root_surface_id_, embedded_surface_id};
+ AggregateAndVerify(
+ expected_passes, arraysize(expected_passes), ids, arraysize(ids));
factory_.Destroy(embedded_surface_id);
}
@@ -213,8 +227,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
SubmitFrame(root_passes, arraysize(root_passes), root_surface_id_);
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator_.Aggregate(root_surface_id_);
+ aggregator_.Aggregate(root_surface_id_, &surface_set);
ASSERT_TRUE(aggregated_frame);
ASSERT_TRUE(aggregated_frame->delegated_frame_data);
@@ -329,7 +344,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
test::Quad::SolidColorQuad(SK_ColorBLUE)};
test::Pass expected_passes[] = {
test::Pass(expected_quads, arraysize(expected_quads))};
- AggregateAndVerify(expected_passes, arraysize(expected_passes));
+ SurfaceId ids[] = {root_surface_id_, InvalidSurfaceId()};
+ AggregateAndVerify(
+ expected_passes, arraysize(expected_passes), ids, arraysize(ids));
}
// Tests a reference to a valid surface with no submitted frame. This quad
@@ -348,7 +365,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
test::Quad::SolidColorQuad(SK_ColorBLUE)};
test::Pass expected_passes[] = {
test::Pass(expected_quads, arraysize(expected_quads))};
- AggregateAndVerify(expected_passes, arraysize(expected_passes));
+ SurfaceId ids[] = {root_surface_id_, surface_with_no_frame_id};
+ AggregateAndVerify(
+ expected_passes, arraysize(expected_passes), ids, arraysize(ids));
factory_.Destroy(surface_with_no_frame_id);
}
@@ -364,7 +383,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorYELLOW)};
test::Pass expected_passes[] = {
test::Pass(expected_quads, arraysize(expected_quads))};
- AggregateAndVerify(expected_passes, arraysize(expected_passes));
+ SurfaceId ids[] = {root_surface_id_};
+ AggregateAndVerify(
+ expected_passes, arraysize(expected_passes), ids, arraysize(ids));
}
// Tests a more complex cycle with one intermediate surface.
@@ -399,7 +420,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
test::Quad::SolidColorQuad(SK_ColorCYAN)};
test::Pass expected_passes[] = {
test::Pass(expected_quads, arraysize(expected_quads))};
- AggregateAndVerify(expected_passes, arraysize(expected_passes));
+ SurfaceId ids[] = {root_surface_id_, child_surface_id};
+ AggregateAndVerify(
+ expected_passes, arraysize(expected_passes), ids, arraysize(ids));
factory_.Destroy(child_surface_id);
}
@@ -429,8 +452,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
test::Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])};
SubmitFrame(parent_passes, arraysize(parent_passes), root_surface_id_);
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator_.Aggregate(root_surface_id_);
+ aggregator_.Aggregate(root_surface_id_, &surface_set);
ASSERT_TRUE(aggregated_frame);
ASSERT_TRUE(aggregated_frame->delegated_frame_data);
@@ -600,8 +624,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
QueuePassAsFrame(root_pass.Pass(), root_surface_id_);
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator_.Aggregate(root_surface_id_);
+ aggregator_.Aggregate(root_surface_id_, &surface_set);
ASSERT_TRUE(aggregated_frame);
ASSERT_TRUE(aggregated_frame->delegated_frame_data);
@@ -701,8 +726,9 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
factory_.SubmitFrame(root_surface_id_, root_frame.Pass());
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator_.Aggregate(root_surface_id_);
+ aggregator_.Aggregate(root_surface_id_, &surface_set);
ASSERT_TRUE(aggregated_frame);
ASSERT_TRUE(aggregated_frame->delegated_frame_data);
@@ -862,14 +888,17 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
ResourceProvider::ResourceId ids[] = {11, 12, 13};
SubmitFrameWithResources(ids, arraysize(ids), &factory, surface_id);
- scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id);
+ std::set<SurfaceId> surface_set;
+ scoped_ptr<CompositorFrame> frame =
+ aggregator_->Aggregate(surface_id, &surface_set);
// Nothing should be available to be returned yet.
EXPECT_TRUE(client.returned_resources().empty());
SubmitFrameWithResources(NULL, 0u, &factory, surface_id);
- frame = aggregator_->Aggregate(surface_id);
+ surface_set.clear();
+ frame = aggregator_->Aggregate(surface_id, &surface_set);
ASSERT_EQ(3u, client.returned_resources().size());
ResourceProvider::ResourceId returned_ids[3];
diff --git a/cc/surfaces/surface_damage_observer.h b/cc/surfaces/surface_damage_observer.h
new file mode 100644
index 0000000..379c9f7
--- /dev/null
+++ b/cc/surfaces/surface_damage_observer.h
@@ -0,0 +1,19 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_
+#define CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_
+
+#include "cc/surfaces/surface_id.h"
+
+namespace cc {
+
+class SurfaceDamageObserver {
+ public:
+ virtual void OnSurfaceDamaged(SurfaceId surface_id) = 0;
+};
+
+} // namespace cc
+
+#endif // CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc
index 69ee02a..d17e98e 100644
--- a/cc/surfaces/surface_factory.cc
+++ b/cc/surfaces/surface_factory.cc
@@ -40,6 +40,7 @@ void SurfaceFactory::SubmitFrame(SurfaceId surface_id,
DCHECK(it != surface_map_.end());
DCHECK(it->second->factory() == this);
it->second->QueueFrame(frame.Pass());
+ manager_->SurfaceModified(surface_id);
}
void SurfaceFactory::ReceiveFromChild(
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc
index 7027abd..1c3de16 100644
--- a/cc/surfaces/surface_manager.cc
+++ b/cc/surfaces/surface_manager.cc
@@ -35,4 +35,9 @@ Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) {
return it->second;
}
+void SurfaceManager::SurfaceModified(SurfaceId surface_id) {
+ FOR_EACH_OBSERVER(
+ SurfaceDamageObserver, observer_list_, OnSurfaceDamaged(surface_id));
+}
+
} // namespace cc
diff --git a/cc/surfaces/surface_manager.h b/cc/surfaces/surface_manager.h
index 40e55f1..202dfe3 100644
--- a/cc/surfaces/surface_manager.h
+++ b/cc/surfaces/surface_manager.h
@@ -7,6 +7,8 @@
#include "base/containers/hash_tables.h"
#include "base/macros.h"
+#include "base/observer_list.h"
+#include "cc/surfaces/surface_damage_observer.h"
#include "cc/surfaces/surface_id.h"
#include "cc/surfaces/surfaces_export.h"
@@ -24,9 +26,20 @@ class CC_SURFACES_EXPORT SurfaceManager {
Surface* GetSurfaceForId(SurfaceId surface_id);
+ void AddObserver(SurfaceDamageObserver* obs) {
+ observer_list_.AddObserver(obs);
+ }
+
+ void RemoveObserver(SurfaceDamageObserver* obs) {
+ observer_list_.RemoveObserver(obs);
+ }
+
+ void SurfaceModified(SurfaceId surface_id);
+
private:
typedef base::hash_map<SurfaceId, Surface*> SurfaceMap;
SurfaceMap surface_map_;
+ ObserverList<SurfaceDamageObserver> observer_list_;
DISALLOW_COPY_AND_ASSIGN(SurfaceManager);
};
diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc
index c9c7a46..bd9f56c 100644
--- a/cc/surfaces/surfaces_pixeltest.cc
+++ b/cc/surfaces/surfaces_pixeltest.cc
@@ -90,8 +90,9 @@ TEST_F(SurfacesPixelTest, DrawSimpleFrame) {
factory_.SubmitFrame(root_surface_id, root_frame.Pass());
SurfaceAggregator aggregator(&manager_, resource_provider_.get());
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator.Aggregate(root_surface_id);
+ aggregator.Aggregate(root_surface_id, &surface_set);
factory_.Destroy(root_surface_id);
bool discard_alpha = false;
@@ -172,8 +173,9 @@ TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) {
}
SurfaceAggregator aggregator(&manager_, resource_provider_.get());
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator.Aggregate(root_surface_id);
+ aggregator.Aggregate(root_surface_id, &surface_set);
bool discard_alpha = false;
ExactPixelComparator pixel_comparator(discard_alpha);
@@ -312,8 +314,9 @@ TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
}
SurfaceAggregator aggregator(&manager_, resource_provider_.get());
+ std::set<SurfaceId> surface_set;
scoped_ptr<CompositorFrame> aggregated_frame =
- aggregator.Aggregate(root_surface_id);
+ aggregator.Aggregate(root_surface_id, &surface_set);
bool discard_alpha = false;
ExactPixelComparator pixel_comparator(discard_alpha);
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc
index 4f1d43a..7a56f02 100644
--- a/content/browser/compositor/delegated_frame_host.cc
+++ b/content/browser/compositor/delegated_frame_host.cc
@@ -350,9 +350,11 @@ void DelegatedFrameHost::SwapDelegatedFrame(
}
last_output_surface_id_ = output_surface_id;
}
+ bool modified_layers = false;
if (frame_size.IsEmpty()) {
DCHECK(frame_data->resource_list.empty());
EvictDelegatedFrame();
+ modified_layers = true;
} else {
if (use_surfaces_) {
if (!surface_factory_) {
@@ -364,12 +366,15 @@ void DelegatedFrameHost::SwapDelegatedFrame(
}
if (surface_id_.is_null() || frame_size != current_surface_size_ ||
frame_size_in_dip != current_frame_size_in_dip_) {
+ // TODO(jbauman): Wait to destroy this surface until the parent has
+ // finished using it.
if (!surface_id_.is_null())
surface_factory_->Destroy(surface_id_);
surface_id_ = id_allocator_->GenerateId();
surface_factory_->Create(surface_id_, frame_size);
client_->GetLayer()->SetShowSurface(surface_id_, frame_size_in_dip);
current_surface_size_ = frame_size;
+ modified_layers = true;
}
scoped_ptr<cc::CompositorFrame> compositor_frame =
make_scoped_ptr(new cc::CompositorFrame());
@@ -395,18 +400,23 @@ void DelegatedFrameHost::SwapDelegatedFrame(
} else {
frame_provider_->SetFrameData(frame_data.Pass());
}
+ modified_layers = true;
}
}
released_front_lock_ = NULL;
current_frame_size_in_dip_ = frame_size_in_dip;
CheckResizeLock();
- client_->SchedulePaintInRect(damage_rect_in_dip);
+ if (modified_layers) {
+ // TODO(jbauman): Need to always tell the window observer about the
+ // damage.
+ client_->SchedulePaintInRect(damage_rect_in_dip);
+ }
pending_delegated_ack_count_++;
ui::Compositor* compositor = client_->GetCompositor();
- if (!compositor) {
+ if (!compositor || !modified_layers) {
SendDelegatedFrameAck(output_surface_id);
} else {
std::vector<ui::LatencyInfo>::const_iterator it;
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index ab5317b..fcbb00a 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -190,8 +190,11 @@ scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
&output_surface_map_,
compositor->vsync_manager()));
}
- scoped_ptr<OnscreenDisplayClient> display_client(new OnscreenDisplayClient(
- context_provider, software_surface.Pass(), manager));
+ scoped_ptr<OnscreenDisplayClient> display_client(
+ new OnscreenDisplayClient(context_provider,
+ software_surface.Pass(),
+ manager,
+ compositor->task_runner()));
// TODO(jamesr): Need to set up filtering for the
// GpuHostMsg_UpdateVSyncParameters message.
diff --git a/content/browser/compositor/onscreen_display_client.cc b/content/browser/compositor/onscreen_display_client.cc
index a071a21..1f5859d0 100644
--- a/content/browser/compositor/onscreen_display_client.cc
+++ b/content/browser/compositor/onscreen_display_client.cc
@@ -4,6 +4,7 @@
#include "content/browser/compositor/onscreen_display_client.h"
+#include "base/debug/trace_event.h"
#include "cc/output/output_surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
@@ -14,12 +15,15 @@ namespace content {
OnscreenDisplayClient::OnscreenDisplayClient(
const scoped_refptr<cc::ContextProvider>& onscreen_context_provider,
scoped_ptr<cc::OutputSurface> software_surface,
- cc::SurfaceManager* manager)
+ cc::SurfaceManager* manager,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: onscreen_context_provider_(onscreen_context_provider),
software_surface_(software_surface.Pass()),
- display_(new cc::Display(this,
- manager,
- HostSharedBitmapManager::current())) {
+ display_(
+ new cc::Display(this, manager, HostSharedBitmapManager::current())),
+ task_runner_(task_runner),
+ scheduled_draw_(false),
+ weak_ptr_factory_(this) {
}
OnscreenDisplayClient::~OnscreenDisplayClient() {
@@ -32,4 +36,20 @@ scoped_ptr<cc::OutputSurface> OnscreenDisplayClient::CreateOutputSurface() {
.Pass();
}
+void OnscreenDisplayClient::DisplayDamaged() {
+ if (scheduled_draw_)
+ return;
+ TRACE_EVENT0("content", "OnscreenDisplayClient::DisplayDamaged");
+ scheduled_draw_ = true;
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&OnscreenDisplayClient::Draw, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void OnscreenDisplayClient::Draw() {
+ TRACE_EVENT0("content", "OnscreenDisplayClient::Draw");
+ scheduled_draw_ = false;
+ display_->Draw();
+}
+
} // namespace content
diff --git a/content/browser/compositor/onscreen_display_client.h b/content/browser/compositor/onscreen_display_client.h
index afe2b39..58d76e5 100644
--- a/content/browser/compositor/onscreen_display_client.h
+++ b/content/browser/compositor/onscreen_display_client.h
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "cc/surfaces/display.h"
namespace cc {
@@ -25,18 +26,26 @@ class OnscreenDisplayClient : cc::DisplayClient {
OnscreenDisplayClient(
const scoped_refptr<cc::ContextProvider>& onscreen_context_provider,
scoped_ptr<cc::OutputSurface> software_surface,
- cc::SurfaceManager* manager);
+ cc::SurfaceManager* manager,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
virtual ~OnscreenDisplayClient();
cc::Display* display() { return display_.get(); }
// cc::DisplayClient implementation.
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface() OVERRIDE;
+ virtual void DisplayDamaged() OVERRIDE;
private:
+ void Draw();
+
scoped_refptr<cc::ContextProvider> onscreen_context_provider_;
scoped_ptr<cc::OutputSurface> software_surface_;
scoped_ptr<cc::Display> display_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ bool scheduled_draw_;
+
+ base::WeakPtrFactory<OnscreenDisplayClient> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(OnscreenDisplayClient);
};
diff --git a/content/browser/compositor/surface_display_output_surface.cc b/content/browser/compositor/surface_display_output_surface.cc
index 2e20c97..b4697a0 100644
--- a/content/browser/compositor/surface_display_output_surface.cc
+++ b/content/browser/compositor/surface_display_output_surface.cc
@@ -50,9 +50,6 @@ void SurfaceDisplayOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
frame->AssignTo(frame_copy.get());
factory_.SubmitFrame(surface_id_, frame_copy.Pass());
- if (!display_->Draw())
- return;
-
client_->DidSwapBuffers();
client_->DidSwapBuffersComplete();
}
diff --git a/mojo/services/surfaces/surfaces_impl.cc b/mojo/services/surfaces/surfaces_impl.cc
index b05e16a..5d33d49 100644
--- a/mojo/services/surfaces/surfaces_impl.cc
+++ b/mojo/services/surfaces/surfaces_impl.cc
@@ -93,4 +93,7 @@ scoped_ptr<cc::OutputSurface> SurfacesImpl::CreateOutputSurface() {
new ContextProviderMojo(command_buffer_handle_.Pass())));
}
+void SurfacesImpl::DisplayDamaged() {
+}
+
} // namespace mojo
diff --git a/mojo/services/surfaces/surfaces_impl.h b/mojo/services/surfaces/surfaces_impl.h
index b3c719d..ac9a397 100644
--- a/mojo/services/surfaces/surfaces_impl.h
+++ b/mojo/services/surfaces/surfaces_impl.h
@@ -54,6 +54,7 @@ class SurfacesImpl : public InterfaceImpl<Surface>,
// DisplayClient implementation.
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface() OVERRIDE;
+ virtual void DisplayDamaged() OVERRIDE;
cc::SurfaceFactory* factory() { return &factory_; }
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 0e4ac8a..bfc0ce2 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -192,6 +192,12 @@ class COMPOSITOR_EXPORT Compositor
// Returns the vsync manager for this compositor.
scoped_refptr<CompositorVSyncManager> vsync_manager() const;
+ // Returns the main thread task runner this compositor uses. Users of the
+ // compositor generally shouldn't use this.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner() const {
+ return task_runner_;
+ }
+
// Compositor does not own observers. It is the responsibility of the
// observer to remove itself when it is done observing.
void AddObserver(CompositorObserver* observer);