| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/surfaces/surface_manager.h" | 5 #include "cc/surfaces/surface_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <queue> | 10 #include <queue> |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES); | 149 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES); |
| 150 | 150 |
| 151 // Check some conditions that should never happen. We don't want to crash on | 151 // Check some conditions that should never happen. We don't want to crash on |
| 152 // bad input from a compromised client so just return early. | 152 // bad input from a compromised client so just return early. |
| 153 if (parent_id.frame_sink_id() == child_id.frame_sink_id()) { | 153 if (parent_id.frame_sink_id() == child_id.frame_sink_id()) { |
| 154 DLOG(ERROR) << "Cannot add self reference from " << parent_id << " to " | 154 DLOG(ERROR) << "Cannot add self reference from " << parent_id << " to " |
| 155 << child_id; | 155 << child_id; |
| 156 return; | 156 return; |
| 157 } | 157 } |
| 158 | 158 |
| 159 // We trust that |parent_id| either exists or is about to exist, since is not | |
| 160 // sent over IPC. We don't trust |child_id|, since it is sent over IPC. | |
| 161 if (surface_map_.count(child_id) == 0) { | |
| 162 DLOG(ERROR) << "No surface in map for " << child_id.ToString(); | |
| 163 return; | |
| 164 } | |
| 165 | |
| 166 // There could be a temporary reference to |child_id| which we should now | 159 // There could be a temporary reference to |child_id| which we should now |
| 167 // remove because a real reference is being added to it. To find out whether | 160 // remove because a real reference is being added to it. To find out whether |
| 168 // or not a temporary reference exists, we need to first look up the | 161 // or not a temporary reference exists, we need to first look up the |
| 169 // FrameSinkId of |child_id| in |temp_references_|, which returns a vector of | 162 // FrameSinkId of |child_id| in |temp_references_|, which returns a vector of |
| 170 // LocalSurfaceIds, and then search for the LocalSurfaceId of |child_id| in | 163 // LocalSurfaceIds, and then search for the LocalSurfaceId of |child_id| in |
| 171 // the | 164 // the said vector. If there is no temporary reference, we can immediately add |
| 172 // said vector. If there is no temporary reference, we can immediately add the | 165 // the reference from |parent_id| and return. |
| 173 // reference from |parent_id| and return. | |
| 174 auto refs_iter = temp_references_.find(child_id.frame_sink_id()); | 166 auto refs_iter = temp_references_.find(child_id.frame_sink_id()); |
| 175 if (refs_iter == temp_references_.end()) { | 167 if (refs_iter == temp_references_.end()) { |
| 176 AddSurfaceReferenceImpl(parent_id, child_id); | 168 AddSurfaceReferenceImpl(parent_id, child_id); |
| 177 return; | 169 return; |
| 178 } | 170 } |
| 179 std::vector<LocalSurfaceId>& refs = refs_iter->second; | 171 std::vector<LocalSurfaceId>& refs = refs_iter->second; |
| 180 auto temp_ref_iter = | 172 auto temp_ref_iter = |
| 181 std::find(refs.begin(), refs.end(), child_id.local_surface_id()); | 173 std::find(refs.begin(), refs.end(), child_id.local_surface_id()); |
| 182 if (temp_ref_iter == refs.end()) { | 174 if (temp_ref_iter == refs.end()) { |
| 183 AddSurfaceReferenceImpl(parent_id, child_id); | 175 AddSurfaceReferenceImpl(parent_id, child_id); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 bool changed = false; | 567 bool changed = false; |
| 576 for (auto& observer : observer_list_) | 568 for (auto& observer : observer_list_) |
| 577 observer.OnSurfaceDamaged(surface_id, &changed); | 569 observer.OnSurfaceDamaged(surface_id, &changed); |
| 578 return changed; | 570 return changed; |
| 579 } | 571 } |
| 580 | 572 |
| 581 void SurfaceManager::SurfaceCreated(const SurfaceInfo& surface_info) { | 573 void SurfaceManager::SurfaceCreated(const SurfaceInfo& surface_info) { |
| 582 CHECK(thread_checker_.CalledOnValidThread()); | 574 CHECK(thread_checker_.CalledOnValidThread()); |
| 583 | 575 |
| 584 if (lifetime_type_ == LifetimeType::REFERENCES) { | 576 if (lifetime_type_ == LifetimeType::REFERENCES) { |
| 585 // We can get into a situation where multiple CompositorFrames arrive for a | 577 // We can get into a situation where multiple CompositorFrames arrive for |
| 586 // CompositorFrameSink before the client can add any references for the | 578 // a CompositorFrameSink before the client can add any references for the |
| 587 // frame. When the second frame with a new size arrives, the first will be | 579 // frame. When the second frame with a new size arrives, the first will be |
| 588 // destroyed in SurfaceFactory and then if there are no references it will | 580 // destroyed in SurfaceFactory and then if there are no references it will |
| 589 // be deleted during surface GC. A temporary reference, removed when a real | 581 // be deleted during surface GC. A temporary reference, removed when a |
| 590 // reference is received, is added to prevent this from happening. | 582 // real reference is received, is added to prevent this from happening. |
| 591 AddSurfaceReferenceImpl(GetRootSurfaceId(), surface_info.id()); | 583 auto it = child_to_parent_refs_.find(surface_info.id()); |
| 592 temp_references_[surface_info.id().frame_sink_id()].push_back( | 584 // TODO(fsamuel): Tests create empty sets and so we also need to check that |
| 593 surface_info.id().local_surface_id()); | 585 // they're not empty here. Ideally tests shouldn't do that and we shouldn't |
| 586 // use array notation into maps in tests (see https://crbug.com/691115). |
| 587 bool has_real_reference = |
| 588 it != child_to_parent_refs_.end() && !it->second.empty(); |
| 589 if (!has_real_reference) { |
| 590 AddSurfaceReferenceImpl(GetRootSurfaceId(), surface_info.id()); |
| 591 temp_references_[surface_info.id().frame_sink_id()].push_back( |
| 592 surface_info.id().local_surface_id()); |
| 593 } |
| 594 } | 594 } |
| 595 | 595 |
| 596 for (auto& observer : observer_list_) | 596 for (auto& observer : observer_list_) |
| 597 observer.OnSurfaceCreated(surface_info); | 597 observer.OnSurfaceCreated(surface_info); |
| 598 } | 598 } |
| 599 | 599 |
| 600 #if DCHECK_IS_ON() | 600 #if DCHECK_IS_ON() |
| 601 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, | 601 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, |
| 602 std::string indent, | 602 std::string indent, |
| 603 std::stringstream* str) { | 603 std::stringstream* str) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); | 635 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); |
| 636 std::sort(children.begin(), children.end()); | 636 std::sort(children.begin(), children.end()); |
| 637 | 637 |
| 638 for (const SurfaceId& child_id : children) | 638 for (const SurfaceId& child_id : children) |
| 639 SurfaceReferencesToStringImpl(child_id, indent + " ", str); | 639 SurfaceReferencesToStringImpl(child_id, indent + " ", str); |
| 640 } | 640 } |
| 641 } | 641 } |
| 642 #endif // DCHECK_IS_ON() | 642 #endif // DCHECK_IS_ON() |
| 643 | 643 |
| 644 } // namespace cc | 644 } // namespace cc |
| OLD | NEW |