Home | History | Annotate | Download | only in service
      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