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 "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