Skip to content

Commit

Permalink
Add gpu::MailboxHolder to hold state for a gpu::Mailbox
Browse files Browse the repository at this point in the history
gpu::Mailbox by itself can hold only a texture id, but in common usage it comes
with texture target and syncpoint information for cross-context sharing.  To
reduce repetition of this pattern, gpu::MailboxHolder holds:

* a gpu::Mailbox
* a GL texture target
* a syncpoint index

Refactor other classes to use a gpu::MailboxHolder instead of separate
gpu::Mailbox and associated state.

Syncpoints are created with uint32 indices; make sure all uses of syncpoints
use the appropriate type.

BUG=None
TEST=local build, unittests on CrOS snow, desktop Linux
TBR=piman@chromium.org, enn@chromium.orge, cevans@chromium.org, scherkus@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@248612 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
sheu@chromium.org committed Feb 3, 2014
1 parent 3a48972 commit df41e25
Show file tree
Hide file tree
Showing 54 changed files with 593 additions and 564 deletions.
1 change: 1 addition & 0 deletions cc/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ include_rules = [
"+gpu/command_buffer/common/gpu_memory_allocation.h",
"+gpu/command_buffer/common/capabilities.h",
"+gpu/command_buffer/common/mailbox.h",
"+gpu/command_buffer/common/mailbox_holder.h",
"+media",
"+skia/ext",
"+third_party/skia/include",
Expand Down
2 changes: 1 addition & 1 deletion cc/layers/delegated_frame_provider_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class DelegatedFrameProviderTest
ResourceProvider::ResourceId resource_id) {
TransferableResource resource;
resource.id = resource_id;
resource.target = GL_TEXTURE_2D;
resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
frame->resource_list.push_back(resource);
}

Expand Down
50 changes: 27 additions & 23 deletions cc/layers/texture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,12 @@ void TextureLayer::SetTextureMailboxInternal(
DCHECK_EQ(mailbox.IsValid(), !!release_callback);

// If we never commited the mailbox, we need to release it here.
if (mailbox.IsValid())
holder_ref_ = MailboxHolder::Create(mailbox, release_callback.Pass());
else
if (mailbox.IsValid()) {
holder_ref_ =
TextureMailboxHolder::Create(mailbox, release_callback.Pass());
} else {
holder_ref_.reset();
}
needs_set_mailbox_ = true;
// If we are within a commit, no need to do it again immediately after.
if (requires_commit)
Expand Down Expand Up @@ -262,7 +264,7 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) {
TextureMailbox texture_mailbox;
scoped_ptr<SingleReleaseCallback> release_callback;
if (holder_ref_) {
MailboxHolder* holder = holder_ref_->holder();
TextureMailboxHolder* holder = holder_ref_->holder();
texture_mailbox = holder->mailbox();
release_callback = holder->GetCallbackForImplThread();
}
Expand All @@ -284,60 +286,61 @@ Region TextureLayer::VisibleContentOpaqueRegion() const {
return Region();
}

TextureLayer::MailboxHolder::MainThreadReference::MainThreadReference(
MailboxHolder* holder)
TextureLayer::TextureMailboxHolder::MainThreadReference::MainThreadReference(
TextureMailboxHolder* holder)
: holder_(holder) {
holder_->InternalAddRef();
}

TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() {
TextureLayer::TextureMailboxHolder::MainThreadReference::
~MainThreadReference() {
holder_->InternalRelease();
}

TextureLayer::MailboxHolder::MailboxHolder(
TextureLayer::TextureMailboxHolder::TextureMailboxHolder(
const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallback> release_callback)
: message_loop_(BlockingTaskRunner::current()),
internal_references_(0),
mailbox_(mailbox),
release_callback_(release_callback.Pass()),
sync_point_(mailbox.sync_point()),
is_lost_(false) {
}
is_lost_(false) {}

TextureLayer::MailboxHolder::~MailboxHolder() {
TextureLayer::TextureMailboxHolder::~TextureMailboxHolder() {
DCHECK_EQ(0u, internal_references_);
}

scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference>
TextureLayer::MailboxHolder::Create(
scoped_ptr<TextureLayer::TextureMailboxHolder::MainThreadReference>
TextureLayer::TextureMailboxHolder::Create(
const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallback> release_callback) {
return scoped_ptr<MainThreadReference>(new MainThreadReference(
new MailboxHolder(mailbox, release_callback.Pass())));
new TextureMailboxHolder(mailbox, release_callback.Pass())));
}

void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) {
void TextureLayer::TextureMailboxHolder::Return(uint32 sync_point,
bool is_lost) {
base::AutoLock lock(arguments_lock_);
sync_point_ = sync_point;
is_lost_ = is_lost;
}

scoped_ptr<SingleReleaseCallback>
TextureLayer::MailboxHolder::GetCallbackForImplThread() {
TextureLayer::TextureMailboxHolder::GetCallbackForImplThread() {
// We can't call GetCallbackForImplThread if we released the main thread
// reference.
DCHECK_GT(internal_references_, 0u);
InternalAddRef();
return SingleReleaseCallback::Create(
base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this));
base::Bind(&TextureMailboxHolder::ReturnAndReleaseOnImplThread, this));
}

void TextureLayer::MailboxHolder::InternalAddRef() {
void TextureLayer::TextureMailboxHolder::InternalAddRef() {
++internal_references_;
}

void TextureLayer::MailboxHolder::InternalRelease() {
void TextureLayer::TextureMailboxHolder::InternalRelease() {
DCHECK(message_loop_->BelongsToCurrentThread());
if (!--internal_references_) {
release_callback_->Run(sync_point_, is_lost_);
Expand All @@ -346,11 +349,12 @@ void TextureLayer::MailboxHolder::InternalRelease() {
}
}

void TextureLayer::MailboxHolder::ReturnAndReleaseOnImplThread(
unsigned sync_point, bool is_lost) {
void TextureLayer::TextureMailboxHolder::ReturnAndReleaseOnImplThread(
uint32 sync_point,
bool is_lost) {
Return(sync_point, is_lost);
message_loop_->PostTask(FROM_HERE,
base::Bind(&MailboxHolder::InternalRelease, this));
message_loop_->PostTask(
FROM_HERE, base::Bind(&TextureMailboxHolder::InternalRelease, this));
}

} // namespace cc
29 changes: 15 additions & 14 deletions cc/layers/texture_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ class TextureLayerClient;
// A Layer containing a the rendered output of a plugin instance.
class CC_EXPORT TextureLayer : public Layer {
public:
class CC_EXPORT MailboxHolder
: public base::RefCountedThreadSafe<MailboxHolder> {
class CC_EXPORT TextureMailboxHolder
: public base::RefCountedThreadSafe<TextureMailboxHolder> {
public:
class CC_EXPORT MainThreadReference {
public:
explicit MainThreadReference(MailboxHolder* holder);
explicit MainThreadReference(TextureMailboxHolder* holder);
~MainThreadReference();
MailboxHolder* holder() { return holder_.get(); }
TextureMailboxHolder* holder() { return holder_.get(); }

private:
scoped_refptr<MailboxHolder> holder_;
scoped_refptr<TextureMailboxHolder> holder_;
DISALLOW_COPY_AND_ASSIGN(MainThreadReference);
};

const TextureMailbox& mailbox() const { return mailbox_; }
void Return(unsigned sync_point, bool is_lost);
void Return(uint32 sync_point, bool is_lost);

// Gets a ReleaseCallback that can be called from another thread. Note: the
// caller must ensure the callback is called.
Expand All @@ -49,17 +49,18 @@ class CC_EXPORT TextureLayer : public Layer {
static scoped_ptr<MainThreadReference> Create(
const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallback> release_callback);
virtual ~MailboxHolder();
virtual ~TextureMailboxHolder();

private:
friend class base::RefCountedThreadSafe<MailboxHolder>;
friend class base::RefCountedThreadSafe<TextureMailboxHolder>;
friend class MainThreadReference;
explicit MailboxHolder(const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallback> release_callback);
explicit TextureMailboxHolder(
const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallback> release_callback);

void InternalAddRef();
void InternalRelease();
void ReturnAndReleaseOnImplThread(unsigned sync_point, bool is_lost);
void ReturnAndReleaseOnImplThread(uint32 sync_point, bool is_lost);

// This member is thread safe, and is accessed on main and impl threads.
const scoped_refptr<BlockingTaskRunner> message_loop_;
Expand All @@ -75,9 +76,9 @@ class CC_EXPORT TextureLayer : public Layer {
// values of these fields are well-ordered such that the last call to
// ReturnAndReleaseOnImplThread() defines their values.
base::Lock arguments_lock_;
unsigned sync_point_;
uint32 sync_point_;
bool is_lost_;
DISALLOW_COPY_AND_ASSIGN(MailboxHolder);
DISALLOW_COPY_AND_ASSIGN(TextureMailboxHolder);
};

// If this texture layer requires special preparation logic for each frame
Expand Down Expand Up @@ -165,7 +166,7 @@ class CC_EXPORT TextureLayer : public Layer {
bool content_committed_;

unsigned texture_id_;
scoped_ptr<MailboxHolder::MainThreadReference> holder_ref_;
scoped_ptr<TextureMailboxHolder::MainThreadReference> holder_ref_;
bool needs_set_mailbox_;

DISALLOW_COPY_AND_ASSIGN(TextureLayer);
Expand Down
Loading

0 comments on commit df41e25

Please sign in to comment.