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 "base/rand_util.h" 10 #include "crypto/hmac.h" 11 #include "gpu/command_buffer/service/texture_manager.h" 12 13 namespace gpu { 14 namespace gles2 { 15 16 MailboxName::MailboxName() { 17 std::fill(key, key + sizeof(key), 0); 18 std::fill(signature, signature + sizeof(signature), 0); 19 } 20 21 MailboxManager::MailboxManager() 22 : hmac_(crypto::HMAC::SHA256), 23 mailbox_to_textures_(std::ptr_fun(&MailboxManager::TargetNameLess)) { 24 base::RandBytes(private_key_, sizeof(private_key_)); 25 bool success = hmac_.Init( 26 base::StringPiece(private_key_, sizeof(private_key_))); 27 DCHECK(success); 28 DCHECK(!IsMailboxNameValid(MailboxName())); 29 } 30 31 MailboxManager::~MailboxManager() { 32 DCHECK(mailbox_to_textures_.empty()); 33 DCHECK(textures_to_mailboxes_.empty()); 34 } 35 36 void MailboxManager::GenerateMailboxName(MailboxName* name) { 37 base::RandBytes(name->key, sizeof(name->key)); 38 SignMailboxName(name); 39 } 40 41 Texture* MailboxManager::ConsumeTexture(unsigned target, 42 const MailboxName& name) { 43 if (!IsMailboxNameValid(name)) 44 return NULL; 45 46 MailboxToTextureMap::iterator it = 47 mailbox_to_textures_.find(TargetName(target, name)); 48 if (it == mailbox_to_textures_.end()) 49 return NULL; 50 51 return it->second->first; 52 } 53 54 bool MailboxManager::ProduceTexture(unsigned target, 55 const MailboxName& name, 56 Texture* texture) { 57 if (!IsMailboxNameValid(name)) 58 return false; 59 60 texture->SetMailboxManager(this); 61 TargetName target_name(target, name); 62 MailboxToTextureMap::iterator it = mailbox_to_textures_.find(target_name); 63 if (it != mailbox_to_textures_.end()) { 64 TextureToMailboxMap::iterator texture_it = it->second; 65 mailbox_to_textures_.erase(it); 66 textures_to_mailboxes_.erase(texture_it); 67 } 68 TextureToMailboxMap::iterator texture_it = 69 textures_to_mailboxes_.insert(std::make_pair(texture, target_name)); 70 mailbox_to_textures_.insert(std::make_pair(target_name, texture_it)); 71 DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); 72 73 return true; 74 } 75 76 void MailboxManager::TextureDeleted(Texture* texture) { 77 std::pair<TextureToMailboxMap::iterator, 78 TextureToMailboxMap::iterator> range = 79 textures_to_mailboxes_.equal_range(texture); 80 for (TextureToMailboxMap::iterator it = range.first; 81 it != range.second; ++it) { 82 size_t count = mailbox_to_textures_.erase(it->second); 83 DCHECK(count == 1); 84 } 85 textures_to_mailboxes_.erase(range.first, range.second); 86 DCHECK_EQ(mailbox_to_textures_.size(), textures_to_mailboxes_.size()); 87 } 88 89 void MailboxManager::SignMailboxName(MailboxName* name) { 90 bool success = hmac_.Sign( 91 base::StringPiece(reinterpret_cast<char*>(name->key), sizeof(name->key)), 92 reinterpret_cast<unsigned char*>(name->signature), 93 sizeof(name->signature)); 94 DCHECK(success); 95 } 96 97 bool MailboxManager::IsMailboxNameValid(const MailboxName& name) { 98 return hmac_.Verify( 99 base::StringPiece(reinterpret_cast<const char*>(name.key), 100 sizeof(name.key)), 101 base::StringPiece(reinterpret_cast<const char*>(name.signature), 102 sizeof(name.signature))); 103 } 104 105 MailboxManager::TargetName::TargetName(unsigned target, const MailboxName& name) 106 : target(target), 107 name(name) { 108 } 109 110 bool MailboxManager::TargetNameLess(const MailboxManager::TargetName& lhs, 111 const MailboxManager::TargetName& rhs) { 112 return memcmp(&lhs, &rhs, sizeof(lhs)) < 0; 113 } 114 115 } // namespace gles2 116 } // namespace gpu 117