Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / cc / surfaces / surface.cc
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