1 // Copyright 2014 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 "cc/surfaces/surface.h" 6 7 #include "cc/output/compositor_frame.h" 8 #include "cc/surfaces/surface_manager.h" 9 10 namespace cc { 11 12 Surface::Surface(SurfaceManager* manager, 13 SurfaceClient* client, 14 const gfx::Size& size) 15 : manager_(manager), 16 client_(client), 17 size_(size) { 18 surface_id_ = manager_->RegisterAndAllocateIdForSurface(this); 19 } 20 21 Surface::~Surface() { 22 manager_->DeregisterSurface(surface_id_); 23 } 24 25 void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame) { 26 scoped_ptr<CompositorFrame> previous_frame = current_frame_.Pass(); 27 current_frame_ = frame.Pass(); 28 ReceiveResourcesFromClient( 29 current_frame_->delegated_frame_data->resource_list); 30 if (previous_frame) { 31 ReturnedResourceArray previous_resources; 32 TransferableResource::ReturnResources( 33 previous_frame->delegated_frame_data->resource_list, 34 &previous_resources); 35 UnrefResources(previous_resources); 36 } 37 } 38 39 CompositorFrame* Surface::GetEligibleFrame() { return current_frame_.get(); } 40 41 void Surface::ReturnUnusedResourcesToClient() { 42 client_->ReturnResources(resources_available_to_return_); 43 resources_available_to_return_.clear(); 44 } 45 46 void Surface::RefCurrentFrameResources() { 47 if (!current_frame_) 48 return; 49 const TransferableResourceArray& current_frame_resources = 50 current_frame_->delegated_frame_data->resource_list; 51 for (size_t i = 0; i < current_frame_resources.size(); ++i) { 52 const TransferableResource& resource = current_frame_resources[i]; 53 ResourceIdCountMap::iterator it = 54 resource_id_use_count_map_.find(resource.id); 55 DCHECK(it != resource_id_use_count_map_.end()); 56 it->second.refs_holding_resource_alive++; 57 } 58 } 59 60 Surface::ResourceRefs::ResourceRefs() 61 : refs_received_from_child(0), refs_holding_resource_alive(0) { 62 } 63 64 void Surface::ReceiveResourcesFromClient( 65 const TransferableResourceArray& resources) { 66 for (TransferableResourceArray::const_iterator it = resources.begin(); 67 it != resources.end(); 68 ++it) { 69 ResourceRefs& ref = resource_id_use_count_map_[it->id]; 70 ref.refs_holding_resource_alive++; 71 ref.refs_received_from_child++; 72 } 73 } 74 75 void Surface::UnrefResources(const ReturnedResourceArray& resources) { 76 for (ReturnedResourceArray::const_iterator it = resources.begin(); 77 it != resources.end(); 78 ++it) { 79 ResourceProvider::ResourceId id = it->id; 80 ResourceIdCountMap::iterator count_it = resource_id_use_count_map_.find(id); 81 DCHECK(count_it != resource_id_use_count_map_.end()); 82 count_it->second.refs_holding_resource_alive -= it->count; 83 if (count_it->second.refs_holding_resource_alive == 0) { 84 resources_available_to_return_.push_back(*it); 85 resources_available_to_return_.back().count = 86 count_it->second.refs_received_from_child; 87 resource_id_use_count_map_.erase(count_it); 88 } 89 } 90 } 91 92 } // namespace cc 93