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 void MailboxManager::GenerateMailbox(Mailbox* mailbox) { 27 crypto::RandBytes(mailbox->name, sizeof(mailbox->name)); 28 } 29 30 Texture* MailboxManager::ConsumeTexture(unsigned target, 31 const Mailbox& mailbox) { 32 TargetName target_name(target, mailbox); 33 MailboxToTextureMap::iterator it = 34 mailbox_to_textures_.find(target_name); 35 if (it != mailbox_to_textures_.end()) 36 return it->second->first; 37 38 if (sync_) { 39 // See if it's visible in another mailbox manager, and if so make it visible 40 // here too. 41 Texture* texture = sync_->CreateTextureFromMailbox(target, mailbox); 42 if (texture) { 43 InsertTexture(target_name, texture); 44 DCHECK_EQ(0U, texture->refs_.size()); 45 } 46 return texture; 47 } 48 49 return NULL; 50 } 51 52 void MailboxManager::ProduceTexture(unsigned target, 53 const Mailbox& mailbox, 54 Texture* texture) { 55 TargetName target_name(target, mailbox); 56 MailboxToTextureMap::iterator it = mailbox_to_textures_.find(target_name); 57 if (it != mailbox_to_textures_.end()) { 58 if (it->second->first == texture) 59 return; 60 TextureToMailboxMap::iterator texture_it = it->second; 61 mailbox_to_textures_.erase(it); 62 textures_to_mailboxes_.erase(texture_it); 63 } 64 InsertTexture(target_name, texture); 65 } 66 67 void MailboxManager::InsertTexture(TargetName target_name, Texture* texture) { 68 texture->SetMailboxManager(this); 69 TextureToMailboxMap::iterator texture_it = 70 textures_to_mailboxes_.insert(std::make_pair(texture, target_name)); 71 mailbox_to_textures_.insert(std::make_pair(target_name, texture_it)); 72 DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); 73 } 74 75 void MailboxManager::TextureDeleted(Texture* texture) { 76 std::pair<TextureToMailboxMap::iterator, 77 TextureToMailboxMap::iterator> range = 78 textures_to_mailboxes_.equal_range(texture); 79 for (TextureToMailboxMap::iterator it = range.first; 80 it != range.second; ++it) { 81 size_t count = mailbox_to_textures_.erase(it->second); 82 DCHECK(count == 1); 83 } 84 textures_to_mailboxes_.erase(range.first, range.second); 85 DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); 86 87 if (sync_) 88 sync_->TextureDeleted(texture); 89 } 90 91 void MailboxManager::PushTextureUpdates() { 92 if (sync_) 93 sync_->PushTextureUpdates(this); 94 } 95 96 void MailboxManager::PullTextureUpdates() { 97 if (sync_) 98 sync_->PullTextureUpdates(this); 99 } 100 101 MailboxManager::TargetName::TargetName(unsigned target, const Mailbox& mailbox) 102 : target(target), 103 mailbox(mailbox) { 104 } 105 106 bool MailboxManager::TargetNameLess(const MailboxManager::TargetName& lhs, 107 const MailboxManager::TargetName& rhs) { 108 return memcmp(&lhs, &rhs, sizeof(lhs)) < 0; 109 } 110 111 } // namespace gles2 112 } // namespace gpu 113