Index: cc/surfaces/surface.cc |
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc |
index 6dc261bde664d9549a95c85dfc905caffe12ec65..f78800d8b2637ce07725bec20ae58a70fae43d8e 100644 |
--- a/cc/surfaces/surface.cc |
+++ b/cc/surfaces/surface.cc |
@@ -15,7 +15,9 @@ |
#include "cc/surfaces/local_surface_id_allocator.h" |
#include "cc/surfaces/pending_frame_observer.h" |
#include "cc/surfaces/surface_factory.h" |
+#include "cc/surfaces/surface_factory_client.h" |
#include "cc/surfaces/surface_manager.h" |
+#include "cc/surfaces/surface_resource_holder_client.h" |
namespace cc { |
@@ -50,9 +52,23 @@ void Surface::SetPreviousFrameSurface(Surface* surface) { |
surface->TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); |
} |
+void Surface::Close() { |
+ closed_ = true; |
+} |
+ |
void Surface::QueueFrame(CompositorFrame frame, |
const DrawCallback& callback, |
const WillDrawCallback& will_draw_callback) { |
+ if (closed_) { |
+ if (factory_ && factory_->resource_holder_client()) { |
+ ReturnedResourceArray resources; |
+ TransferableResource::ReturnResources(frame.resource_list, &resources); |
+ factory_->resource_holder_client()->ReturnResources(resources); |
+ } |
+ callback.Run(); |
+ return; |
+ } |
+ |
TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); |
base::Optional<FrameData> previous_pending_frame_data = |
@@ -68,6 +84,24 @@ void Surface::QueueFrame(CompositorFrame frame, |
bool is_pending_frame = !blocking_surfaces_.empty(); |
if (is_pending_frame) { |
+ // Reject CompositorFrames submitted to surfaces referenced from this |
+ // CompositorFrame as fallbacks. This saves some CPU cycles to allow |
+ // children to catch up to the parent. |
+ base::flat_set<FrameSinkId> frame_sink_ids_for_dependencies; |
+ for (const SurfaceId& surface_id : frame.metadata.activation_dependencies) |
+ frame_sink_ids_for_dependencies.insert(surface_id.frame_sink_id()); |
+ for (const SurfaceId& surface_id : frame.metadata.referenced_surfaces) { |
+ // If this |surface_id| corresponds to a fallback surface referenced by |
danakj
2017/05/05 18:06:08
This comment just says what the code below does, w
Fady Samuel
2017/05/05 18:55:11
I've improved the comment, hopefully.
|
+ // this CompositorFrame, then we close the corresponding surface to avoid |
+ // accepting new frames. |
+ bool is_fallback_surface = |
+ frame_sink_ids_for_dependencies.count(surface_id.frame_sink_id()) > 0; |
+ if (is_fallback_surface) { |
+ Surface* surface = factory_->manager()->GetSurfaceForId(surface_id); |
+ DCHECK(surface); |
+ surface->Close(); |
+ } |
+ } |
pending_frame_data_ = |
FrameData(std::move(frame), callback, will_draw_callback); |
// Ask the surface manager to inform |this| when its dependencies are |