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 13namespace gpu { 14namespace gles2 { 15 16MailboxManager::MailboxManager() 17 : mailbox_to_textures_(std::ptr_fun(&MailboxManager::TargetNameLess)), 18 sync_(MailboxSynchronizer::GetInstance()) { 19} 20 21MailboxManager::~MailboxManager() { 22 DCHECK(mailbox_to_textures_.empty()); 23 DCHECK(textures_to_mailboxes_.empty()); 24} 25 26Texture* 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 48void 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 63void 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 71void 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 87void MailboxManager::PushTextureUpdates(uint32 sync_point) { 88 if (sync_) 89 sync_->PushTextureUpdates(this, sync_point); 90} 91 92void MailboxManager::PullTextureUpdates(uint32 sync_point) { 93 if (sync_) 94 sync_->PullTextureUpdates(this, sync_point); 95} 96 97MailboxManager::TargetName::TargetName(unsigned target, const Mailbox& mailbox) 98 : target(target), 99 mailbox(mailbox) { 100} 101 102bool MailboxManager::TargetNameLess(const MailboxManager::TargetName& lhs, 103 const MailboxManager::TargetName& rhs) { 104 if (lhs.target != rhs.target) 105 return lhs.target < rhs.target; 106 return lhs.mailbox < rhs.mailbox; 107} 108 109} // namespace gles2 110} // namespace gpu 111