1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/mailbox_manager.h" 6 7 #include <algorithm> 8 9 #include "crypto/random.h" 10 #include "gpu/command_buffer/service/mailbox_synchronizer.h" 11 #include "gpu/command_buffer/service/texture_manager.h" 12 13 namespace gpu { 14 namespace gles2 { 15 16 MailboxManager::MailboxManager() 17 : mailbox_to_textures_(std::ptr_fun(&MailboxManager::TargetNameLess)), 18 sync_(MailboxSynchronizer::GetInstance()) { 19 } 20 21 MailboxManager::~MailboxManager() { 22 DCHECK(mailbox_to_textures_.empty()); 23 DCHECK(textures_to_mailboxes_.empty()); 24 } 25 26 Texture* MailboxManager::ConsumeTexture(unsigned target, 27 const Mailbox& mailbox) { 28 TargetName target_name(target, mailbox); 29 MailboxToTextureMap::iterator it = 30 mailbox_to_textures_.find(target_name); 31 if (it != mailbox_to_textures_.end()) 32 return it->second->first; 33 34 if (sync_) { 35 // See if it's visible in another mailbox manager, and if so make it visible 36 // here too. 37 Texture* texture = sync_->CreateTextureFromMailbox(target, mailbox); 38 if (texture) { 39 InsertTexture(target_name, texture); 40 DCHECK_EQ(0U, texture->refs_.size()); 41 } 42 return texture; 43 } 44 45 return NULL; 46 } 47 48 void MailboxManager::ProduceTexture(unsigned target, 49 const Mailbox& mailbox, 50 Texture* texture) { 51 TargetName target_name(target, mailbox); 52 MailboxToTextureMap::iterator it = mailbox_to_textures_.find(target_name); 53 if (it != mailbox_to_textures_.end()) { 54 if (it->second->first == texture) 55 return; 56 TextureToMailboxMap::iterator texture_it = it->second; 57 mailbox_to_textures_.erase(it); 58 textures_to_mailboxes_.erase(texture_it); 59 } 60 InsertTexture(target_name, texture); 61 } 62 63 void MailboxManager::InsertTexture(TargetName target_name, Texture* texture) { 64 texture->SetMailboxManager(this); 65 TextureToMailboxMap::iterator texture_it = 66 textures_to_mailboxes_.insert(std::make_pair(texture, target_name)); 67 mailbox_to_textures_.insert(std::make_pair(target_name, texture_it)); 68 DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); 69 } 70 71 void MailboxManager::TextureDeleted(Texture* texture) { 72 std::pair<TextureToMailboxMap::iterator, 73 TextureToMailboxMap::iterator> range = 74 textures_to_mailboxes_.equal_range(texture); 75 for (TextureToMailboxMap::iterator it = range.first; 76 it != range.second; ++it) { 77 size_t count = mailbox_to_textures_.erase(it->second); 78 DCHECK(count == 1); 79 } 80 textures_to_mailboxes_.erase(range.first, range.second); 81 DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); 82 83 if (sync_) 84 sync_->TextureDeleted(texture); 85 } 86 87 void MailboxManager::PushTextureUpdates() { 88 if (sync_) 89 sync_->PushTextureUpdates(this); 90 } 91 92 void MailboxManager::PullTextureUpdates() { 93 if (sync_) 94 sync_->PullTextureUpdates(this); 95 } 96 97 MailboxManager::TargetName::TargetName(unsigned target, const Mailbox& mailbox) 98 : target(target), 99 mailbox(mailbox) { 100 } 101 102 bool MailboxManager::TargetNameLess(const MailboxManager::TargetName& lhs, 103 const MailboxManager::TargetName& rhs) { 104 return memcmp(&lhs, &rhs, sizeof(lhs)) < 0; 105 } 106 107 } // namespace gles2 108 } // namespace gpu 109