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 Texture* 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 
     48 void 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 
     63 void 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 
     71 void 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 
     87 void MailboxManager::PushTextureUpdates() {
     88   if (sync_)
     89     sync_->PushTextureUpdates(this);
     90 }
     91 
     92 void MailboxManager::PullTextureUpdates() {
     93   if (sync_)
     94     sync_->PullTextureUpdates(this);
     95 }
     96 
     97 MailboxManager::TargetName::TargetName(unsigned target, const Mailbox& mailbox)
     98     : target(target),
     99       mailbox(mailbox) {
    100 }
    101 
    102 bool MailboxManager::TargetNameLess(const MailboxManager::TargetName& lhs,
    103                                     const MailboxManager::TargetName& rhs) {
    104   return memcmp(&lhs, &rhs, sizeof(lhs)) < 0;
    105 }
    106 
    107 }  // namespace gles2
    108 }  // namespace gpu
    109