Index: cc/surfaces/display.cc |
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc |
index 8309f0b19cb9d3b00156763e00f82de91d985e21..0163942bede8a795d350606b514da69748184e8b 100644 |
--- a/cc/surfaces/display.cc |
+++ b/cc/surfaces/display.cc |
@@ -246,10 +246,12 @@ bool Display::DrawAndSwap() { |
return false; |
} |
- // Run callbacks early to allow pipelining. |
+ // Run callbacks early to allow pipelining. Do not run root surface callback |
+ // here so that browser compositor cannot reclaim resources until we're done |
+ // with drawing. |
for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
- if (surface) |
+ if (surface && surface->surface_id() != current_surface_id_) |
surface->RunDrawCallbacks(); |
} |
@@ -326,10 +328,11 @@ bool Display::DrawAndSwap() { |
if (should_swap) { |
swapped_since_resize_ = true; |
for (auto& latency : frame.metadata.latency_info) { |
- TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", |
+ TRACE_EVENT_WITH_FLOW1( |
+ "input,benchmark", "LatencyInfo.Flow", |
TRACE_ID_DONT_MANGLE(latency.trace_id()), |
- TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, |
- "step", "Display::DrawAndSwap"); |
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step", |
+ "Display::DrawAndSwap"); |
} |
benchmark_instrumentation::IssueDisplayRenderingStatsEvent(); |
renderer_->SwapBuffers(std::move(frame.metadata)); |
@@ -348,6 +351,13 @@ bool Display::DrawAndSwap() { |
} |
} |
+ // Run draw callback for root surface after drawing. It's safe for the browser |
+ // compositor to reclaim resources now. |
+ Surface* root_surface = |
+ surface_manager_->GetSurfaceForId(current_surface_id_); |
+ if (root_surface) |
+ root_surface->RunDrawCallbacks(); |
+ |
client_->DisplayDidDrawAndSwap(); |
return true; |
} |