Commit c90f0d8d authored by jbauman@chromium.org's avatar jbauman@chromium.org

Enqueuing new frames in a Surface should cause Displays to reaggregate it

Keep track of which Surfaces were included in a Display last
frame, so if a new frame is enqueued in a Surface the Displays containing it will tell their clients to redraw. This way the browser compositor
doesn't have to commit if only the renderer contents changed.

BUG=

Review URL: https://codereview.chromium.org/432093003

Cr-Commit-Position: refs/heads/master@{#290103}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290103 0039d316-1c4b-4281-b951-d872f2087c98
parent e510e37d
......@@ -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_;
}
......
......@@ -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);
};
......
......@@ -14,6 +14,7 @@ class OutputSurface;
class DisplayClient {
public:
virtual scoped_ptr<OutputSurface> CreateOutputSurface() = 0;
virtual void DisplayDamaged() = 0;
protected:
virtual ~DisplayClient() {}
......
......@@ -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();
......
......@@ -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_;
......
......@@ -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];
......
// 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_
......@@ -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(
......
......@@ -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
......@@ -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);
};
......
......@@ -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);
......
......@@ -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;
......
......@@ -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.
......
......@@ -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
......@@ -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);
};
......
......@@ -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();
}
......
......@@ -93,4 +93,7 @@ scoped_ptr<cc::OutputSurface> SurfacesImpl::CreateOutputSurface() {
new ContextProviderMojo(command_buffer_handle_.Pass())));
}
void SurfacesImpl::DisplayDamaged() {
}
} // namespace mojo
......@@ -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_; }
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment