// Copyright (c) 2012 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 "gpu/command_buffer/service/mailbox_manager.h" #include #include "crypto/random.h" #include "gpu/command_buffer/service/mailbox_synchronizer.h" #include "gpu/command_buffer/service/texture_manager.h" namespace gpu { namespace gles2 { MailboxManager::MailboxManager() : mailbox_to_textures_(std::ptr_fun(&MailboxManager::TargetNameLess)), sync_(MailboxSynchronizer::GetInstance()) { } MailboxManager::~MailboxManager() { DCHECK(mailbox_to_textures_.empty()); DCHECK(textures_to_mailboxes_.empty()); } Texture* MailboxManager::ConsumeTexture(unsigned target, const Mailbox& mailbox) { TargetName target_name(target, mailbox); MailboxToTextureMap::iterator it = mailbox_to_textures_.find(target_name); if (it != mailbox_to_textures_.end()) return it->second->first; if (sync_) { // See if it's visible in another mailbox manager, and if so make it visible // here too. Texture* texture = sync_->CreateTextureFromMailbox(target, mailbox); if (texture) { InsertTexture(target_name, texture); DCHECK_EQ(0U, texture->refs_.size()); } return texture; } return NULL; } void MailboxManager::ProduceTexture(unsigned target, const Mailbox& mailbox, Texture* texture) { TargetName target_name(target, mailbox); MailboxToTextureMap::iterator it = mailbox_to_textures_.find(target_name); if (it != mailbox_to_textures_.end()) { if (it->second->first == texture) return; TextureToMailboxMap::iterator texture_it = it->second; mailbox_to_textures_.erase(it); textures_to_mailboxes_.erase(texture_it); } InsertTexture(target_name, texture); } void MailboxManager::InsertTexture(TargetName target_name, Texture* texture) { texture->SetMailboxManager(this); TextureToMailboxMap::iterator texture_it = textures_to_mailboxes_.insert(std::make_pair(texture, target_name)); mailbox_to_textures_.insert(std::make_pair(target_name, texture_it)); DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); } void MailboxManager::TextureDeleted(Texture* texture) { std::pair range = textures_to_mailboxes_.equal_range(texture); for (TextureToMailboxMap::iterator it = range.first; it != range.second; ++it) { size_t count = mailbox_to_textures_.erase(it->second); DCHECK(count == 1); } textures_to_mailboxes_.erase(range.first, range.second); DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); if (sync_) sync_->TextureDeleted(texture); } void MailboxManager::PushTextureUpdates() { if (sync_) sync_->PushTextureUpdates(this); } void MailboxManager::PullTextureUpdates() { if (sync_) sync_->PullTextureUpdates(this); } MailboxManager::TargetName::TargetName(unsigned target, const Mailbox& mailbox) : target(target), mailbox(mailbox) { } bool MailboxManager::TargetNameLess(const MailboxManager::TargetName& lhs, const MailboxManager::TargetName& rhs) { return memcmp(&lhs, &rhs, sizeof(lhs)) < 0; } } // namespace gles2 } // namespace gpu