summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/output/compositor_frame_metadata.h4
-rw-r--r--cc/surfaces/surface.cc8
-rw-r--r--cc/surfaces/surface.h5
-rw-r--r--cc/surfaces/surface_factory.cc15
-rw-r--r--cc/surfaces/surface_factory.h5
-rw-r--r--cc/surfaces/surface_factory_unittest.cc27
-rw-r--r--cc/surfaces/surface_id_allocator.h2
-rw-r--r--cc/surfaces/surface_manager.cc52
-rw-r--r--cc/surfaces/surface_manager.h24
-rw-r--r--cc/surfaces/surface_sequence.h38
-rw-r--r--content/browser/compositor/delegated_frame_host.cc20
-rw-r--r--content/browser/compositor/gpu_process_transport_factory.cc2
-rw-r--r--content/browser/compositor/gpu_process_transport_factory.h4
-rw-r--r--content/browser/compositor/image_transport_factory.h1
-rw-r--r--content/browser/compositor/surface_display_output_surface.cc6
-rw-r--r--content/browser/compositor/surface_display_output_surface.h4
-rw-r--r--content/browser/compositor/test/no_transport_image_transport_factory.cc11
-rw-r--r--content/browser/compositor/test/no_transport_image_transport_factory.h3
-rw-r--r--content/common/cc_messages.h1
-rw-r--r--mojo/aura/surface_context_factory.cc6
-rw-r--r--mojo/aura/surface_context_factory.h2
-rw-r--r--ui/compositor/BUILD.gn1
-rw-r--r--ui/compositor/compositor.cc30
-rw-r--r--ui/compositor/compositor.gyp2
-rw-r--r--ui/compositor/compositor.h15
-rw-r--r--ui/compositor/test/in_process_context_factory.cc10
-rw-r--r--ui/compositor/test/in_process_context_factory.h3
27 files changed, 270 insertions, 31 deletions
diff --git a/cc/output/compositor_frame_metadata.h b/cc/output/compositor_frame_metadata.h
index e9dd706..a6fe2d4 100644
--- a/cc/output/compositor_frame_metadata.h
+++ b/cc/output/compositor_frame_metadata.h
@@ -46,6 +46,10 @@ class CC_EXPORT CompositorFrameMetadata {
ViewportSelectionBound selection_end;
std::vector<ui::LatencyInfo> latency_info;
+
+ // A set of SurfaceSequences that this frame satisfies (always in the same
+ // namespace as the current Surface).
+ std::vector<uint32_t> satisfies_sequences;
};
} // namespace cc
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc
index d58ed4c..4d32d72 100644
--- a/cc/surfaces/surface.cc
+++ b/cc/surfaces/surface.cc
@@ -7,6 +7,7 @@
#include "cc/output/compositor_frame.h"
#include "cc/output/copy_output_request.h"
#include "cc/surfaces/surface_factory.h"
+#include "cc/surfaces/surface_manager.h"
namespace cc {
@@ -17,7 +18,7 @@ static const int kFrameIndexStart = 2;
Surface::Surface(SurfaceId id, const gfx::Size& size, SurfaceFactory* factory)
: surface_id_(id),
size_(size),
- factory_(factory),
+ factory_(factory->AsWeakPtr()),
frame_index_(kFrameIndexStart) {
}
@@ -28,7 +29,7 @@ Surface::~Surface() {
(*it)->SendEmptyResult();
}
copy_requests_.clear();
- if (current_frame_) {
+ if (current_frame_ && factory_) {
ReturnedResourceArray current_resources;
TransferableResource::ReturnResources(
current_frame_->delegated_frame_data->resource_list,
@@ -39,6 +40,7 @@ Surface::~Surface() {
void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
const base::Closure& callback) {
+ DCHECK(factory_);
for (ScopedPtrVector<CopyOutputRequest>::iterator it = copy_requests_.begin();
it != copy_requests_.end();
++it) {
@@ -63,6 +65,8 @@ void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
if (!draw_callback_.is_null())
draw_callback_.Run();
draw_callback_ = callback;
+ factory_->manager()->DidSatisfySequences(
+ surface_id_, &current_frame_->metadata.satisfies_sequences);
}
void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) {
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h
index 718fef4..0df5c17 100644
--- a/cc/surfaces/surface.h
+++ b/cc/surfaces/surface.h
@@ -11,6 +11,7 @@
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "cc/base/scoped_ptr_vector.h"
#include "cc/output/copy_output_request.h"
#include "cc/surfaces/surface_id.h"
@@ -50,12 +51,12 @@ class CC_SURFACES_EXPORT Surface {
void TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info);
void RunDrawCallbacks();
- SurfaceFactory* factory() { return factory_; }
+ base::WeakPtr<SurfaceFactory> factory() { return factory_; }
private:
SurfaceId surface_id_;
gfx::Size size_;
- SurfaceFactory* factory_;
+ base::WeakPtr<SurfaceFactory> factory_;
// TODO(jamesr): Support multiple frames in flight.
scoped_ptr<CompositorFrame> current_frame_;
int frame_index_;
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc
index ab7186a..dcf1130 100644
--- a/cc/surfaces/surface_factory.cc
+++ b/cc/surfaces/surface_factory.cc
@@ -29,17 +29,26 @@ void SurfaceFactory::Create(SurfaceId surface_id, const gfx::Size& size) {
void SurfaceFactory::Destroy(SurfaceId surface_id) {
OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
DCHECK(it != surface_map_.end());
- DCHECK(it->second->factory() == this);
+ DCHECK(it->second->factory().get() == this);
manager_->DeregisterSurface(surface_id);
surface_map_.erase(it);
}
+void SurfaceFactory::DestroyOnSequence(
+ SurfaceId surface_id,
+ const std::set<SurfaceSequence>& dependency_set) {
+ OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
+ DCHECK(it != surface_map_.end());
+ DCHECK(it->second->factory().get() == this);
+ manager_->DestroyOnSequence(surface_map_.take_and_erase(it), dependency_set);
+}
+
void SurfaceFactory::SubmitFrame(SurfaceId surface_id,
scoped_ptr<CompositorFrame> frame,
const base::Closure& callback) {
OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
DCHECK(it != surface_map_.end());
- DCHECK(it->second->factory() == this);
+ DCHECK(it->second->factory().get() == this);
it->second->QueueFrame(frame.Pass(), callback);
manager_->SurfaceModified(surface_id);
}
@@ -52,7 +61,7 @@ void SurfaceFactory::RequestCopyOfSurface(
copy_request->SendEmptyResult();
return;
}
- DCHECK(it->second->factory() == this);
+ DCHECK(it->second->factory().get() == this);
it->second->RequestCopyOfOutput(copy_request.Pass());
manager_->SurfaceModified(surface_id);
}
diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h
index 2516015..3eb4f43 100644
--- a/cc/surfaces/surface_factory.h
+++ b/cc/surfaces/surface_factory.h
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "cc/surfaces/surface_id.h"
#include "cc/surfaces/surface_resource_holder.h"
+#include "cc/surfaces/surface_sequence.h"
#include "cc/surfaces/surfaces_export.h"
namespace gfx {
@@ -37,6 +38,8 @@ class CC_SURFACES_EXPORT SurfaceFactory
void Create(SurfaceId surface_id, const gfx::Size& size);
void Destroy(SurfaceId surface_id);
+ void DestroyOnSequence(SurfaceId surface_id,
+ const std::set<SurfaceSequence>& dependency_set);
// A frame can only be submitted to a surface created by this factory,
// although the frame may reference surfaces created by other factories.
// The callback is called the first time this frame is used to draw.
@@ -52,6 +55,8 @@ class CC_SURFACES_EXPORT SurfaceFactory
void RefResources(const TransferableResourceArray& resources);
void UnrefResources(const ReturnedResourceArray& resources);
+ SurfaceManager* manager() { return manager_; }
+
private:
SurfaceManager* manager_;
SurfaceFactoryClient* client_;
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc
index 5cb83fe..ba2a888 100644
--- a/cc/surfaces/surface_factory_unittest.cc
+++ b/cc/surfaces/surface_factory_unittest.cc
@@ -372,5 +372,32 @@ TEST_F(SurfaceFactoryTest, DestroyWithResourceRefs) {
factory_.SubmitFrame(id, frame.Pass(), base::Closure());
}
+TEST_F(SurfaceFactoryTest, DestroySequence) {
+ SurfaceId id2(5);
+ factory_.Create(id2, gfx::Size(5, 5));
+
+ // Check that waiting before the sequence is satisfied works.
+ std::set<SurfaceSequence> sequence;
+ sequence.insert(SurfaceSequence(0, 4));
+ factory_.DestroyOnSequence(id2, sequence);
+
+ scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
+ scoped_ptr<CompositorFrame> frame(new CompositorFrame);
+ frame->metadata.satisfies_sequences.push_back(6);
+ frame->metadata.satisfies_sequences.push_back(4);
+ frame->delegated_frame_data = frame_data.Pass();
+ DCHECK(manager_.GetSurfaceForId(id2));
+ factory_.SubmitFrame(surface_id_, frame.Pass(), base::Closure());
+ DCHECK(!manager_.GetSurfaceForId(id2));
+
+ // Check that waiting after the sequence is satisfied works.
+ factory_.Create(id2, gfx::Size(5, 5));
+ sequence.clear();
+ sequence.insert(SurfaceSequence(0, 6));
+ DCHECK(manager_.GetSurfaceForId(id2));
+ factory_.DestroyOnSequence(id2, sequence);
+ DCHECK(!manager_.GetSurfaceForId(id2));
+}
+
} // namespace
} // namespace cc
diff --git a/cc/surfaces/surface_id_allocator.h b/cc/surfaces/surface_id_allocator.h
index d410f06..96a241f 100644
--- a/cc/surfaces/surface_id_allocator.h
+++ b/cc/surfaces/surface_id_allocator.h
@@ -21,6 +21,8 @@ class CC_SURFACES_EXPORT SurfaceIdAllocator {
static uint32_t NamespaceForId(SurfaceId id);
+ uint32_t id_namespace() const { return id_namespace_; }
+
private:
const uint32_t id_namespace_;
uint32_t next_id_;
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc
index 1e3699d..920f464 100644
--- a/cc/surfaces/surface_manager.cc
+++ b/cc/surfaces/surface_manager.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_id_allocator.h"
namespace cc {
@@ -15,6 +16,12 @@ SurfaceManager::SurfaceManager() {
SurfaceManager::~SurfaceManager() {
DCHECK(thread_checker_.CalledOnValidThread());
+ for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
+ it != surfaces_to_destroy_.end();
+ ++it) {
+ DeregisterSurface(it->first->surface_id());
+ delete it->first;
+ }
}
void SurfaceManager::RegisterSurface(Surface* surface) {
@@ -31,6 +38,51 @@ void SurfaceManager::DeregisterSurface(SurfaceId surface_id) {
surface_map_.erase(it);
}
+void SurfaceManager::DestroyOnSequence(
+ scoped_ptr<Surface> surface,
+ const std::set<SurfaceSequence>& dependency_set) {
+ surfaces_to_destroy_.push_back(make_pair(surface.release(), dependency_set));
+ SearchForSatisfaction();
+}
+
+void SurfaceManager::DidSatisfySequences(SurfaceId id,
+ std::vector<uint32_t>* sequence) {
+ for (std::vector<uint32_t>::iterator it = sequence->begin();
+ it != sequence->end();
+ ++it) {
+ satisfied_sequences_.insert(
+ SurfaceSequence(SurfaceIdAllocator::NamespaceForId(id), *it));
+ }
+ sequence->clear();
+ SearchForSatisfaction();
+}
+
+void SurfaceManager::SearchForSatisfaction() {
+ for (SurfaceDestroyList::iterator dest_it = surfaces_to_destroy_.begin();
+ dest_it != surfaces_to_destroy_.end();) {
+ std::set<SurfaceSequence>& dependency_set = dest_it->second;
+
+ for (std::set<SurfaceSequence>::iterator it = dependency_set.begin();
+ it != dependency_set.end();) {
+ if (satisfied_sequences_.count(*it) > 0) {
+ satisfied_sequences_.erase(*it);
+ std::set<SurfaceSequence>::iterator old_it = it;
+ ++it;
+ dependency_set.erase(old_it);
+ } else {
+ ++it;
+ }
+ }
+ if (dependency_set.empty()) {
+ scoped_ptr<Surface> surf(dest_it->first);
+ DeregisterSurface(surf->surface_id());
+ dest_it = surfaces_to_destroy_.erase(dest_it);
+ } else {
+ ++dest_it;
+ }
+ }
+}
+
Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) {
DCHECK(thread_checker_.CalledOnValidThread());
SurfaceMap::iterator it = surface_map_.find(surface_id);
diff --git a/cc/surfaces/surface_manager.h b/cc/surfaces/surface_manager.h
index 7515be5..66db9d9 100644
--- a/cc/surfaces/surface_manager.h
+++ b/cc/surfaces/surface_manager.h
@@ -5,12 +5,17 @@
#ifndef CC_SURFACES_SURFACE_MANAGER_H_
#define CC_SURFACES_SURFACE_MANAGER_H_
+#include <list>
+#include <set>
+#include <vector>
+
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/threading/thread_checker.h"
#include "cc/surfaces/surface_damage_observer.h"
#include "cc/surfaces/surface_id.h"
+#include "cc/surfaces/surface_sequence.h"
#include "cc/surfaces/surfaces_export.h"
namespace cc {
@@ -25,6 +30,10 @@ class CC_SURFACES_EXPORT SurfaceManager {
void RegisterSurface(Surface* surface);
void DeregisterSurface(SurfaceId surface_id);
+ // Destroy the Surface once a set of sequence numbers has been satisfied.
+ void DestroyOnSequence(scoped_ptr<Surface> surface,
+ const std::set<SurfaceSequence>& dependency_set);
+
Surface* GetSurfaceForId(SurfaceId surface_id);
void AddObserver(SurfaceDamageObserver* obs) {
@@ -37,12 +46,27 @@ class CC_SURFACES_EXPORT SurfaceManager {
void SurfaceModified(SurfaceId surface_id);
+ // A frame for a surface satisfies a set of sequence numbers.
+ void DidSatisfySequences(SurfaceId id, std::vector<uint32_t>* sequence);
+
private:
+ void SearchForSatisfaction();
+
typedef base::hash_map<SurfaceId, Surface*> SurfaceMap;
SurfaceMap surface_map_;
ObserverList<SurfaceDamageObserver> observer_list_;
base::ThreadChecker thread_checker_;
+ // List of surfaces to be destroyed, along with what sequences they're still
+ // waiting on.
+ typedef std::list<std::pair<Surface*, std::set<SurfaceSequence>>>
+ SurfaceDestroyList;
+ SurfaceDestroyList surfaces_to_destroy_;
+
+ // Set of SurfaceSequences that have been satisfied by a frame but not yet
+ // waited on.
+ std::set<SurfaceSequence> satisfied_sequences_;
+
DISALLOW_COPY_AND_ASSIGN(SurfaceManager);
};
diff --git a/cc/surfaces/surface_sequence.h b/cc/surfaces/surface_sequence.h
new file mode 100644
index 0000000..4c99e45
--- /dev/null
+++ b/cc/surfaces/surface_sequence.h
@@ -0,0 +1,38 @@
+// 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_SEQUENCE_H_
+#define CC_SURFACES_SURFACE_SEQUENCE_H_
+
+namespace cc {
+
+// A per-surface-namespace sequence number that's used to coordinate
+// dependencies between frames. A sequence number may be satisfied once, and
+// may be depended on once.
+struct SurfaceSequence {
+ SurfaceSequence() : id_namespace(0u), sequence(0u) {}
+ SurfaceSequence(uint32_t id_namespace, uint32_t sequence)
+ : id_namespace(id_namespace), sequence(sequence) {}
+
+ uint32_t id_namespace;
+ uint32_t sequence;
+};
+
+inline bool operator==(const SurfaceSequence& a, const SurfaceSequence& b) {
+ return a.id_namespace == b.id_namespace && a.sequence == b.sequence;
+}
+
+inline bool operator!=(const SurfaceSequence& a, const SurfaceSequence& b) {
+ return !(a == b);
+}
+
+inline bool operator<(const SurfaceSequence& a, const SurfaceSequence& b) {
+ if (a.id_namespace != b.id_namespace)
+ return a.id_namespace < b.id_namespace;
+ return a.sequence < b.sequence;
+}
+
+} // namespace cc
+
+#endif // CC_SURFACES_SURFACE_SEQUENCE_H_
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc
index 9df4600..9a26d42 100644
--- a/content/browser/compositor/delegated_frame_host.cc
+++ b/content/browser/compositor/delegated_frame_host.cc
@@ -370,16 +370,26 @@ void DelegatedFrameHost::SwapDelegatedFrame(
if (!surface_factory_) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
cc::SurfaceManager* manager = factory->GetSurfaceManager();
- id_allocator_ = factory->CreateSurfaceIdAllocator();
+ id_allocator_ =
+ factory->GetContextFactory()->CreateSurfaceIdAllocator();
surface_factory_ =
make_scoped_ptr(new cc::SurfaceFactory(manager, this));
}
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_);
+ if (!surface_id_.is_null()) {
+ if (compositor) {
+ std::set<cc::SurfaceSequence> seq;
+ seq.insert(compositor->InsertSurfaceSequenceForNextFrame());
+ // Destruction of this surface needs to wait for compositors that
+ // have drawn using it to swap frames that don't reference it.
+ // TODO(jbauman): Handle cases where the compositor has been
+ // changed since the last draw.
+ surface_factory_->DestroyOnSequence(surface_id_, seq);
+ } else {
+ 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);
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 36b3e0c..abdbdb2 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -202,7 +202,7 @@ scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
scoped_ptr<SurfaceDisplayOutputSurface> output_surface(
new SurfaceDisplayOutputSurface(
- manager, next_surface_id_namespace_++, context_provider));
+ manager, compositor->surface_id_allocator(), context_provider));
display_client->set_surface_output_surface(output_surface.get());
output_surface->set_display_client(display_client.get());
data->display_client = display_client.Pass();
diff --git a/content/browser/compositor/gpu_process_transport_factory.h b/content/browser/compositor/gpu_process_transport_factory.h
index cb78094..abed2f8 100644
--- a/content/browser/compositor/gpu_process_transport_factory.h
+++ b/content/browser/compositor/gpu_process_transport_factory.h
@@ -56,12 +56,12 @@ class GpuProcessTransportFactory
virtual bool DoesCreateTestContexts() override;
virtual cc::SharedBitmapManager* GetSharedBitmapManager() override;
virtual base::MessageLoopProxy* GetCompositorMessageLoop() override;
+ virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
+ override;
// ImageTransportFactory implementation.
virtual ui::ContextFactory* GetContextFactory() override;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() override;
- virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
- override;
virtual cc::SurfaceManager* GetSurfaceManager() override;
virtual GLHelper* GetGLHelper() override;
virtual void AddObserver(ImageTransportFactoryObserver* observer) override;
diff --git a/content/browser/compositor/image_transport_factory.h b/content/browser/compositor/image_transport_factory.h
index c3af76a..4b5dec1 100644
--- a/content/browser/compositor/image_transport_factory.h
+++ b/content/browser/compositor/image_transport_factory.h
@@ -72,7 +72,6 @@ class CONTENT_EXPORT ImageTransportFactory {
virtual ui::ContextFactory* GetContextFactory() = 0;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() = 0;
- virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() = 0;
virtual cc::SurfaceManager* GetSurfaceManager() = 0;
// Gets a GLHelper instance, associated with the shared context. This
diff --git a/content/browser/compositor/surface_display_output_surface.cc b/content/browser/compositor/surface_display_output_surface.cc
index c1a09f8f..2f06581 100644
--- a/content/browser/compositor/surface_display_output_surface.cc
+++ b/content/browser/compositor/surface_display_output_surface.cc
@@ -15,14 +15,14 @@ namespace content {
SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface(
cc::SurfaceManager* surface_manager,
- uint32_t surface_id_namespace,
+ cc::SurfaceIdAllocator* allocator,
const scoped_refptr<cc::ContextProvider>& context_provider)
: cc::OutputSurface(context_provider,
scoped_ptr<cc::SoftwareOutputDevice>()),
display_client_(NULL),
surface_manager_(surface_manager),
factory_(surface_manager, this),
- allocator_(surface_id_namespace) {
+ allocator_(allocator) {
capabilities_.delegated_rendering = true;
capabilities_.max_frames_pending = 1;
}
@@ -47,7 +47,7 @@ void SurfaceDisplayOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
if (!surface_id_.is_null()) {
factory_.Destroy(surface_id_);
}
- surface_id_ = allocator_.GenerateId();
+ surface_id_ = allocator_->GenerateId();
factory_.Create(surface_id_, frame_size);
display_size_ = frame_size;
display_client_->display()->Resize(surface_id_, frame_size);
diff --git a/content/browser/compositor/surface_display_output_surface.h b/content/browser/compositor/surface_display_output_surface.h
index 3549ad2..ac1a3e2 100644
--- a/content/browser/compositor/surface_display_output_surface.h
+++ b/content/browser/compositor/surface_display_output_surface.h
@@ -27,7 +27,7 @@ class SurfaceDisplayOutputSurface : public cc::OutputSurface,
// The underlying cc::Display and cc::SurfaceManager must outlive this class.
SurfaceDisplayOutputSurface(
cc::SurfaceManager* surface_manager,
- uint32_t surface_id_namespace,
+ cc::SurfaceIdAllocator* allocator,
const scoped_refptr<cc::ContextProvider>& context_provider);
virtual ~SurfaceDisplayOutputSurface();
@@ -54,7 +54,7 @@ class SurfaceDisplayOutputSurface : public cc::OutputSurface,
cc::SurfaceFactory factory_;
gfx::Size display_size_;
cc::SurfaceId surface_id_;
- cc::SurfaceIdAllocator allocator_;
+ cc::SurfaceIdAllocator* allocator_;
DISALLOW_COPY_AND_ASSIGN(SurfaceDisplayOutputSurface);
};
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.cc b/content/browser/compositor/test/no_transport_image_transport_factory.cc
index 524223f..808d297 100644
--- a/content/browser/compositor/test/no_transport_image_transport_factory.cc
+++ b/content/browser/compositor/test/no_transport_image_transport_factory.cc
@@ -5,6 +5,7 @@
#include "content/browser/compositor/test/no_transport_image_transport_factory.h"
#include "cc/output/context_provider.h"
+#include "cc/surfaces/surface_manager.h"
#include "content/common/gpu/client/gl_helper.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "ui/compositor/compositor.h"
@@ -13,7 +14,8 @@
namespace content {
NoTransportImageTransportFactory::NoTransportImageTransportFactory()
- : context_factory_(new ui::InProcessContextFactory) {
+ : context_factory_(new ui::InProcessContextFactory),
+ surface_manager_(new cc::SurfaceManager) {
}
NoTransportImageTransportFactory::~NoTransportImageTransportFactory() {
@@ -31,13 +33,8 @@ NoTransportImageTransportFactory::GetSharedSurfaceHandle() {
return gfx::GLSurfaceHandle();
}
-scoped_ptr<cc::SurfaceIdAllocator>
-NoTransportImageTransportFactory::CreateSurfaceIdAllocator() {
- return scoped_ptr<cc::SurfaceIdAllocator>();
-}
-
cc::SurfaceManager* NoTransportImageTransportFactory::GetSurfaceManager() {
- return NULL;
+ return surface_manager_.get();
}
GLHelper* NoTransportImageTransportFactory::GetGLHelper() {
diff --git a/content/browser/compositor/test/no_transport_image_transport_factory.h b/content/browser/compositor/test/no_transport_image_transport_factory.h
index 6bcca6f..67ba4ec 100644
--- a/content/browser/compositor/test/no_transport_image_transport_factory.h
+++ b/content/browser/compositor/test/no_transport_image_transport_factory.h
@@ -24,8 +24,6 @@ class NoTransportImageTransportFactory : public ImageTransportFactory {
// ImageTransportFactory implementation.
virtual ui::ContextFactory* GetContextFactory() override;
virtual gfx::GLSurfaceHandle GetSharedSurfaceHandle() override;
- virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
- override;
virtual cc::SurfaceManager* GetSurfaceManager() override;
virtual GLHelper* GetGLHelper() override;
virtual void AddObserver(ImageTransportFactoryObserver* observer) override;
@@ -38,6 +36,7 @@ class NoTransportImageTransportFactory : public ImageTransportFactory {
scoped_ptr<ui::ContextFactory> context_factory_;
scoped_refptr<cc::ContextProvider> context_provider_;
scoped_ptr<GLHelper> gl_helper_;
+ scoped_ptr<cc::SurfaceManager> surface_manager_;
ObserverList<ImageTransportFactoryObserver> observer_list_;
DISALLOW_COPY_AND_ASSIGN(NoTransportImageTransportFactory);
diff --git a/content/common/cc_messages.h b/content/common/cc_messages.h
index d51f7af..b29fdc6 100644
--- a/content/common/cc_messages.h
+++ b/content/common/cc_messages.h
@@ -287,6 +287,7 @@ IPC_STRUCT_TRAITS_BEGIN(cc::CompositorFrameMetadata)
IPC_STRUCT_TRAITS_MEMBER(selection_start)
IPC_STRUCT_TRAITS_MEMBER(selection_end)
IPC_STRUCT_TRAITS_MEMBER(latency_info)
+ IPC_STRUCT_TRAITS_MEMBER(satisfies_sequences)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::GLFrameData)
diff --git a/mojo/aura/surface_context_factory.cc b/mojo/aura/surface_context_factory.cc
index 1e56029..9f1e77a 100644
--- a/mojo/aura/surface_context_factory.cc
+++ b/mojo/aura/surface_context_factory.cc
@@ -6,6 +6,7 @@
#include "cc/output/output_surface.h"
#include "cc/resources/shared_bitmap_manager.h"
+#include "cc/surfaces/surface_id_allocator.h"
#include "mojo/public/interfaces/application/shell.mojom.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "ui/compositor/reflector.h"
@@ -55,4 +56,9 @@ base::MessageLoopProxy* SurfaceContextFactory::GetCompositorMessageLoop() {
return nullptr;
}
+scoped_ptr<cc::SurfaceIdAllocator>
+SurfaceContextFactory::CreateSurfaceIdAllocator() {
+ return nullptr;
+}
+
} // namespace mojo
diff --git a/mojo/aura/surface_context_factory.h b/mojo/aura/surface_context_factory.h
index dc0e8d0..cc9aba3 100644
--- a/mojo/aura/surface_context_factory.h
+++ b/mojo/aura/surface_context_factory.h
@@ -32,6 +32,8 @@ class SurfaceContextFactory : public ui::ContextFactory {
virtual bool DoesCreateTestContexts() override;
virtual cc::SharedBitmapManager* GetSharedBitmapManager() override;
virtual base::MessageLoopProxy* GetCompositorMessageLoop() override;
+ virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
+ override;
SurfaceBinding surface_binding_;
diff --git a/ui/compositor/BUILD.gn b/ui/compositor/BUILD.gn
index ada7f9e..38b79ad 100644
--- a/ui/compositor/BUILD.gn
+++ b/ui/compositor/BUILD.gn
@@ -109,6 +109,7 @@ source_set("test_support") {
deps = [
"//base/test:test_support",
"//cc",
+ "//cc/surfaces",
"//cc:test_support",
"//skia",
"//testing/gtest",
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 1b6f342..4d07e1e 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -20,6 +20,7 @@
#include "cc/layers/layer.h"
#include "cc/output/begin_frame_args.h"
#include "cc/output/context_provider.h"
+#include "cc/surfaces/surface_id_allocator.h"
#include "cc/trees/layer_tree_host.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/compositor/compositor_observer.h"
@@ -68,12 +69,31 @@ namespace {} // namespace
namespace ui {
+class SatisfySwapPromise : public cc::SwapPromise {
+ public:
+ explicit SatisfySwapPromise(uint32_t id) : id_(id) {}
+
+ private:
+ virtual void DidSwap(cc::CompositorFrameMetadata* metadata) OVERRIDE {
+ metadata->satisfies_sequences.push_back(id_);
+ }
+
+ virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE {
+ // TODO(jbauman): Send to the SurfaceManager immediately.
+ DCHECK(false);
+ }
+ virtual int64 TraceId() const OVERRIDE { return 0; }
+ uint32_t id_;
+};
+
Compositor::Compositor(gfx::AcceleratedWidget widget,
ui::ContextFactory* context_factory,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: context_factory_(context_factory),
root_layer_(NULL),
widget_(widget),
+ surface_id_allocator_(context_factory->CreateSurfaceIdAllocator()),
+ surface_sequence_number_(0),
compositor_thread_loop_(context_factory->GetCompositorMessageLoop()),
task_runner_(task_runner),
vsync_manager_(new CompositorVSyncManager()),
@@ -406,6 +426,16 @@ void Compositor::SetLayerTreeDebugState(
host_->SetDebugState(debug_state);
}
+cc::SurfaceSequence Compositor::InsertSurfaceSequenceForNextFrame() {
+ cc::SurfaceSequence sequence;
+ sequence.id_namespace = surface_id_allocator_->id_namespace();
+ sequence.sequence = ++surface_sequence_number_;
+ scoped_ptr<cc::SwapPromise> promise(
+ new SatisfySwapPromise(surface_sequence_number_));
+ host_->QueueSwapPromise(promise.Pass());
+ return sequence;
+}
+
scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
if (!compositor_lock_) {
compositor_lock_ = new CompositorLock(this);
diff --git a/ui/compositor/compositor.gyp b/ui/compositor/compositor.gyp
index 4a1437e..76cb687 100644
--- a/ui/compositor/compositor.gyp
+++ b/ui/compositor/compositor.gyp
@@ -14,6 +14,7 @@
'<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
'<(DEPTH)/cc/cc.gyp:cc',
+ '<(DEPTH)/cc/cc.gyp:cc_surfaces',
'<(DEPTH)/gpu/gpu.gyp:command_buffer_common',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/ui/gfx/gfx.gyp:gfx',
@@ -87,6 +88,7 @@
'dependencies': [
'<(DEPTH)/base/base.gyp:base',
'<(DEPTH)/cc/cc.gyp:cc',
+ '<(DEPTH)/cc/cc.gyp:cc_surfaces',
'<(DEPTH)/cc/cc_tests.gyp:cc_test_support',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/testing/gtest.gyp:gtest',
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index d808f62..bd96541 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -13,6 +13,7 @@
#include "base/observer_list.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
+#include "cc/surfaces/surface_sequence.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -37,6 +38,7 @@ class Layer;
class LayerTreeDebugState;
class LayerTreeHost;
class SharedBitmapManager;
+class SurfaceIdAllocator;
}
namespace gfx {
@@ -95,6 +97,9 @@ class COMPOSITOR_EXPORT ContextFactory {
// Gets the compositor message loop, or NULL if not using threaded
// compositing.
virtual base::MessageLoopProxy* GetCompositorMessageLoop() = 0;
+
+ // Creates a Surface ID allocator with a new namespace.
+ virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() = 0;
};
// This class represents a lock on the compositor, that can be used to prevent
@@ -266,6 +271,14 @@ class COMPOSITOR_EXPORT Compositor
return &layer_animator_collection_;
}
+ // Inserts a SurfaceSequence that will be satisfied on the next frame this
+ // compositor commits and swaps.
+ cc::SurfaceSequence InsertSurfaceSequenceForNextFrame();
+
+ cc::SurfaceIdAllocator* surface_id_allocator() {
+ return surface_id_allocator_.get();
+ }
+
private:
friend class base::RefCounted<Compositor>;
friend class CompositorLock;
@@ -290,6 +303,8 @@ class COMPOSITOR_EXPORT Compositor
ObserverList<CompositorAnimationObserver> animation_observer_list_;
gfx::AcceleratedWidget widget_;
+ scoped_ptr<cc::SurfaceIdAllocator> surface_id_allocator_;
+ uint32_t surface_sequence_number_;
scoped_refptr<cc::Layer> root_web_layer_;
scoped_ptr<cc::LayerTreeHost> host_;
scoped_refptr<base::MessageLoopProxy> compositor_thread_loop_;
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index fa2380f..d815a5c 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/threading/thread.h"
#include "cc/output/output_surface.h"
+#include "cc/surfaces/surface_id_allocator.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/compositor/reflector.h"
@@ -19,7 +20,8 @@
namespace ui {
InProcessContextFactory::InProcessContextFactory()
- : shared_bitmap_manager_(new cc::TestSharedBitmapManager()) {
+ : shared_bitmap_manager_(new cc::TestSharedBitmapManager()),
+ next_surface_id_namespace_(1u) {
DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone)
<< "If running tests, ensure that main() is calling "
<< "gfx::GLSurface::InitializeOneOffForTests()";
@@ -102,4 +104,10 @@ base::MessageLoopProxy* InProcessContextFactory::GetCompositorMessageLoop() {
return compositor_thread_->message_loop_proxy().get();
}
+scoped_ptr<cc::SurfaceIdAllocator>
+InProcessContextFactory::CreateSurfaceIdAllocator() {
+ return make_scoped_ptr(
+ new cc::SurfaceIdAllocator(next_surface_id_namespace_++));
+}
+
} // namespace ui
diff --git a/ui/compositor/test/in_process_context_factory.h b/ui/compositor/test/in_process_context_factory.h
index 56f2d7e..6100edb 100644
--- a/ui/compositor/test/in_process_context_factory.h
+++ b/ui/compositor/test/in_process_context_factory.h
@@ -40,12 +40,15 @@ class InProcessContextFactory : public ContextFactory {
virtual bool DoesCreateTestContexts() override;
virtual cc::SharedBitmapManager* GetSharedBitmapManager() override;
virtual base::MessageLoopProxy* GetCompositorMessageLoop() override;
+ virtual scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator()
+ override;
private:
scoped_ptr<base::Thread> compositor_thread_;
scoped_refptr<webkit::gpu::ContextProviderInProcess>
shared_main_thread_contexts_;
scoped_ptr<cc::SharedBitmapManager> shared_bitmap_manager_;
+ uint32_t next_surface_id_namespace_;
DISALLOW_COPY_AND_ASSIGN(InProcessContextFactory);
};