| 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/display.h" | 5 #include "cc/surfaces/display.h" |
| 6 | 6 |
| 7 #include "base/thread_task_runner_handle.h" | 7 #include "base/thread_task_runner_handle.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
| 9 #include "cc/debug/benchmark_instrumentation.h" | 9 #include "cc/debug/benchmark_instrumentation.h" |
| 10 #include "cc/output/compositor_frame.h" | 10 #include "cc/output/compositor_frame.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 DisplayScheduler* scheduler) { | 55 DisplayScheduler* scheduler) { |
| 56 output_surface_ = output_surface.Pass(); | 56 output_surface_ = output_surface.Pass(); |
| 57 scheduler_ = scheduler; | 57 scheduler_ = scheduler; |
| 58 return output_surface_->BindToClient(this); | 58 return output_surface_->BindToClient(this); |
| 59 } | 59 } |
| 60 | 60 |
| 61 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { | 61 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { |
| 62 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) | 62 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) |
| 63 return; | 63 return; |
| 64 | 64 |
| 65 TRACE_EVENT0("cc", "Display::SetSurfaceId"); |
| 66 |
| 65 current_surface_id_ = id; | 67 current_surface_id_ = id; |
| 66 device_scale_factor_ = device_scale_factor; | 68 device_scale_factor_ = device_scale_factor; |
| 67 | 69 |
| 68 UpdateRootSurfaceResourcesLocked(); | 70 UpdateRootSurfaceResourcesLocked(); |
| 69 if (scheduler_) | 71 if (scheduler_) |
| 70 scheduler_->EntireDisplayDamaged(id); | 72 scheduler_->SetNewRootSurface(id); |
| 71 } | 73 } |
| 72 | 74 |
| 73 void Display::Resize(const gfx::Size& size) { | 75 void Display::Resize(const gfx::Size& size) { |
| 74 if (size == current_surface_size_) | 76 if (size == current_surface_size_) |
| 75 return; | 77 return; |
| 78 |
| 79 TRACE_EVENT0("cc", "Display::Resize"); |
| 80 |
| 76 // Need to ensure all pending swaps have executed before the window is | 81 // Need to ensure all pending swaps have executed before the window is |
| 77 // resized, or D3D11 will scale the swap output. | 82 // resized, or D3D11 will scale the swap output. |
| 78 if (settings_.finish_rendering_on_resize) { | 83 if (settings_.finish_rendering_on_resize) { |
| 79 if (!swapped_since_resize_ && scheduler_) | 84 if (!swapped_since_resize_ && scheduler_) |
| 80 scheduler_->ForceImmediateSwapIfPossible(); | 85 scheduler_->ForceImmediateSwapIfPossible(); |
| 81 if (swapped_since_resize_ && output_surface_ && | 86 if (swapped_since_resize_ && output_surface_ && |
| 82 output_surface_->context_provider()) | 87 output_surface_->context_provider()) |
| 83 output_surface_->context_provider()->ContextGL()->ShallowFinishCHROMIUM(); | 88 output_surface_->context_provider()->ContextGL()->ShallowFinishCHROMIUM(); |
| 84 } | 89 } |
| 85 swapped_since_resize_ = false; | 90 swapped_since_resize_ = false; |
| 86 current_surface_size_ = size; | 91 current_surface_size_ = size; |
| 87 if (scheduler_) | 92 if (scheduler_) |
| 88 scheduler_->EntireDisplayDamaged(current_surface_id_); | 93 scheduler_->DisplayResized(); |
| 89 } | 94 } |
| 90 | 95 |
| 91 void Display::SetExternalClip(const gfx::Rect& clip) { | 96 void Display::SetExternalClip(const gfx::Rect& clip) { |
| 92 external_clip_ = clip; | 97 external_clip_ = clip; |
| 93 } | 98 } |
| 94 | 99 |
| 95 void Display::InitializeRenderer() { | 100 void Display::InitializeRenderer() { |
| 96 if (resource_provider_) | 101 if (resource_provider_) |
| 97 return; | 102 return; |
| 98 | 103 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 } | 144 } |
| 140 | 145 |
| 141 void Display::UpdateRootSurfaceResourcesLocked() { | 146 void Display::UpdateRootSurfaceResourcesLocked() { |
| 142 Surface* surface = manager_->GetSurfaceForId(current_surface_id_); | 147 Surface* surface = manager_->GetSurfaceForId(current_surface_id_); |
| 143 bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); | 148 bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame(); |
| 144 if (scheduler_) | 149 if (scheduler_) |
| 145 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); | 150 scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); |
| 146 } | 151 } |
| 147 | 152 |
| 148 bool Display::DrawAndSwap() { | 153 bool Display::DrawAndSwap() { |
| 149 if (current_surface_id_.is_null()) | 154 TRACE_EVENT0("cc", "Display::DrawAndSwap"); |
| 155 |
| 156 if (current_surface_id_.is_null()) { |
| 157 TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); |
| 150 return false; | 158 return false; |
| 159 } |
| 151 | 160 |
| 152 InitializeRenderer(); | 161 InitializeRenderer(); |
| 153 if (!output_surface_) | 162 if (!output_surface_) { |
| 163 TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD); |
| 154 return false; | 164 return false; |
| 165 } |
| 155 | 166 |
| 156 if (output_surface_->SurfaceIsSuspendForRecycle()) | 167 if (output_surface_->SurfaceIsSuspendForRecycle()) |
| 157 return false; | 168 return false; |
| 158 | 169 |
| 159 scoped_ptr<CompositorFrame> frame = | 170 scoped_ptr<CompositorFrame> frame = |
| 160 aggregator_->Aggregate(current_surface_id_); | 171 aggregator_->Aggregate(current_surface_id_); |
| 161 if (!frame) | 172 if (!frame) { |
| 173 TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.", |
| 174 TRACE_EVENT_SCOPE_THREAD); |
| 162 return false; | 175 return false; |
| 163 | 176 } |
| 164 TRACE_EVENT0("cc", "Display::DrawAndSwap"); | |
| 165 | 177 |
| 166 // Run callbacks early to allow pipelining. | 178 // Run callbacks early to allow pipelining. |
| 167 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 179 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
| 168 Surface* surface = manager_->GetSurfaceForId(id_entry.first); | 180 Surface* surface = manager_->GetSurfaceForId(id_entry.first); |
| 169 if (surface) | 181 if (surface) |
| 170 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); | 182 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN); |
| 171 } | 183 } |
| 184 |
| 172 DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); | 185 DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); |
| 173 | 186 |
| 174 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(), | 187 frame->metadata.latency_info.insert(frame->metadata.latency_info.end(), |
| 175 stored_latency_info_.begin(), | 188 stored_latency_info_.begin(), |
| 176 stored_latency_info_.end()); | 189 stored_latency_info_.end()); |
| 177 stored_latency_info_.clear(); | 190 stored_latency_info_.clear(); |
| 178 bool have_copy_requests = false; | 191 bool have_copy_requests = false; |
| 179 for (const auto* pass : frame_data->render_pass_list) { | 192 for (const auto* pass : frame_data->render_pass_list) { |
| 180 have_copy_requests |= !pass->copy_requests.empty(); | 193 have_copy_requests |= !pass->copy_requests.empty(); |
| 181 } | 194 } |
| 182 | 195 |
| 183 gfx::Size surface_size; | 196 gfx::Size surface_size; |
| 184 bool have_damage = false; | 197 bool have_damage = false; |
| 185 if (!frame_data->render_pass_list.empty()) { | 198 if (!frame_data->render_pass_list.empty()) { |
| 186 surface_size = frame_data->render_pass_list.back()->output_rect.size(); | 199 surface_size = frame_data->render_pass_list.back()->output_rect.size(); |
| 187 have_damage = | 200 have_damage = |
| 188 !frame_data->render_pass_list.back()->damage_rect.size().IsEmpty(); | 201 !frame_data->render_pass_list.back()->damage_rect.size().IsEmpty(); |
| 189 } | 202 } |
| 190 bool avoid_swap = surface_size != current_surface_size_; | 203 |
| 204 bool size_matches = surface_size == current_surface_size_; |
| 205 if (!size_matches) |
| 206 TRACE_EVENT_INSTANT0("cc", "Size missmatch.", TRACE_EVENT_SCOPE_THREAD); |
| 207 |
| 191 bool should_draw = !frame->metadata.latency_info.empty() || | 208 bool should_draw = !frame->metadata.latency_info.empty() || |
| 192 have_copy_requests || (have_damage && !avoid_swap); | 209 have_copy_requests || (have_damage && size_matches); |
| 193 | 210 |
| 194 if (should_draw) { | 211 if (should_draw) { |
| 195 gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_); | 212 gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_); |
| 196 gfx::Rect device_clip_rect = | 213 gfx::Rect device_clip_rect = |
| 197 external_clip_.IsEmpty() ? device_viewport_rect : external_clip_; | 214 external_clip_.IsEmpty() ? device_viewport_rect : external_clip_; |
| 198 bool disable_picture_quad_image_filtering = false; | 215 bool disable_picture_quad_image_filtering = false; |
| 199 | 216 |
| 200 renderer_->DecideRenderPassAllocationsForFrame( | 217 renderer_->DecideRenderPassAllocationsForFrame( |
| 201 frame_data->render_pass_list); | 218 frame_data->render_pass_list); |
| 202 renderer_->DrawFrame(&frame_data->render_pass_list, device_scale_factor_, | 219 renderer_->DrawFrame(&frame_data->render_pass_list, device_scale_factor_, |
| 203 device_viewport_rect, device_clip_rect, | 220 device_viewport_rect, device_clip_rect, |
| 204 disable_picture_quad_image_filtering); | 221 disable_picture_quad_image_filtering); |
| 222 } else { |
| 223 TRACE_EVENT_INSTANT0("cc", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD); |
| 205 } | 224 } |
| 206 | 225 |
| 207 if (should_draw && !avoid_swap) { | 226 bool should_swap = should_draw && size_matches; |
| 227 if (should_swap) { |
| 208 swapped_since_resize_ = true; | 228 swapped_since_resize_ = true; |
| 209 for (auto& latency : frame->metadata.latency_info) { | 229 for (auto& latency : frame->metadata.latency_info) { |
| 210 TRACE_EVENT_FLOW_STEP0( | 230 TRACE_EVENT_FLOW_STEP0( |
| 211 "input,benchmark", | 231 "input,benchmark", |
| 212 "LatencyInfo.Flow", | 232 "LatencyInfo.Flow", |
| 213 TRACE_ID_DONT_MANGLE(latency.trace_id), | 233 TRACE_ID_DONT_MANGLE(latency.trace_id), |
| 214 "Display::DrawAndSwap"); | 234 "Display::DrawAndSwap"); |
| 215 } | 235 } |
| 216 benchmark_instrumentation::IssueDisplayRenderingStatsEvent(); | 236 benchmark_instrumentation::IssueDisplayRenderingStatsEvent(); |
| 217 renderer_->SwapBuffers(frame->metadata); | 237 renderer_->SwapBuffers(frame->metadata); |
| 218 } else { | 238 } else { |
| 239 TRACE_EVENT_INSTANT0("cc", "Swap skipped.", TRACE_EVENT_SCOPE_THREAD); |
| 219 stored_latency_info_.insert(stored_latency_info_.end(), | 240 stored_latency_info_.insert(stored_latency_info_.end(), |
| 220 frame->metadata.latency_info.begin(), | 241 frame->metadata.latency_info.begin(), |
| 221 frame->metadata.latency_info.end()); | 242 frame->metadata.latency_info.end()); |
| 222 DidSwapBuffers(); | 243 DidSwapBuffers(); |
| 223 DidSwapBuffersComplete(); | 244 DidSwapBuffersComplete(); |
| 224 } | 245 } |
| 225 | 246 |
| 226 return true; | 247 return true; |
| 227 } | 248 } |
| 228 | 249 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 319 |
| 299 if (surface_id == current_surface_id_) | 320 if (surface_id == current_surface_id_) |
| 300 UpdateRootSurfaceResourcesLocked(); | 321 UpdateRootSurfaceResourcesLocked(); |
| 301 } | 322 } |
| 302 | 323 |
| 303 SurfaceId Display::CurrentSurfaceId() { | 324 SurfaceId Display::CurrentSurfaceId() { |
| 304 return current_surface_id_; | 325 return current_surface_id_; |
| 305 } | 326 } |
| 306 | 327 |
| 307 } // namespace cc | 328 } // namespace cc |
| OLD | NEW |