Chromium Code Reviews| Index: cc/surfaces/referenced_surface_tracker.cc |
| diff --git a/cc/surfaces/referenced_surface_tracker.cc b/cc/surfaces/referenced_surface_tracker.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..417a8eb3d1f6225cb6d9f904e619cc92f2e7d6d1 |
| --- /dev/null |
| +++ b/cc/surfaces/referenced_surface_tracker.cc |
| @@ -0,0 +1,82 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "cc/surfaces/referenced_surface_tracker.h" |
| + |
| +#include <utility> |
| + |
| +#include "base/logging.h" |
| + |
| +namespace cc { |
| + |
| +ReferencedSurfaceTracker::ReferencedSurfaceTracker( |
| + const FrameSinkId& frame_sink_id) |
| + : current_surface_id_(frame_sink_id, LocalFrameId()) { |
| + DCHECK(current_surface_id_.frame_sink_id().is_valid()); |
| +} |
| + |
| +ReferencedSurfaceTracker::~ReferencedSurfaceTracker() {} |
| + |
| +void ReferencedSurfaceTracker::UpdateReferences( |
| + const LocalFrameId& local_frame_id, |
| + const std::vector<SurfaceId>& referenced_surfaces) { |
| + DCHECK(local_frame_id.is_valid()); |
| + |
| + // Clear references to add/remove from the last frame. |
| + references_to_remove_.clear(); |
| + references_to_add_.clear(); |
| + |
| + // If |current_surface_id_| is changing then update |current_surface_id_|. |
| + // Also clear |referenced_surfaces_| because we haven't added any references |
| + // from the new SurfaceId yet. |
| + if (current_surface_id_.local_frame_id() != local_frame_id) { |
| + current_surface_id_ = |
| + SurfaceId(current_surface_id_.frame_sink_id(), local_frame_id); |
| + referenced_surfaces_.clear(); |
| + } |
| + |
| + UpdateReferencedSurfaces(referenced_surfaces); |
| +} |
| + |
| +void ReferencedSurfaceTracker::UpdateReferencedSurfaces( |
| + const std::vector<SurfaceId>& new_referenced_surfaces) { |
| + std::unordered_set<SurfaceId, SurfaceIdHash> new_referenced_surfaces_set; |
| + |
| + // Add references for each SurfaceId in |new_referenced_surfaces| if they |
| + // aren't already referenced. |
|
Fady Samuel
2017/01/18 01:08:55
Can you use std::set_difference?
kylechar
2017/01/18 15:20:15
It's possible but I don't think the right solution
|
| + for (const SurfaceId& surface_id : new_referenced_surfaces) { |
| + ReferenceSurface(surface_id); |
| + new_referenced_surfaces_set.insert(surface_id); |
| + } |
| + |
| + // Check for SurfaceIds that are no longer referenced and remove them. |
| + for (const SurfaceId& surface_id : referenced_surfaces_) { |
| + if (new_referenced_surfaces_set.count(surface_id) == 0) |
| + UnreferenceSurface(surface_id); |
| + } |
| +} |
| + |
| +void ReferencedSurfaceTracker::ReferenceSurface(const SurfaceId& surface_id) { |
| + // If we already have a reference to |surface_id| then return early. |
| + if (referenced_surfaces_.count(surface_id) > 0) |
| + return; |
| + |
| + // Record that surface is referenced and add a reference. |
| + references_to_add_.push_back( |
| + SurfaceReference(current_surface_id_, surface_id)); |
| + referenced_surfaces_.insert(surface_id); |
| +} |
| + |
| +void ReferencedSurfaceTracker::UnreferenceSurface(const SurfaceId& surface_id) { |
| + auto iter = referenced_surfaces_.find(surface_id); |
| + if (iter == referenced_surfaces_.end()) |
| + return; |
| + |
| + // Remove record that surface is referenced and remove reference. |
| + references_to_remove_.push_back( |
| + SurfaceReference(current_surface_id_, surface_id)); |
| + referenced_surfaces_.erase(iter); |
| +} |
| + |
| +} // namespace cc |