| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
| 11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 12 #include "cc/debug/benchmark_instrumentation.h" | 12 #include "cc/debug/benchmark_instrumentation.h" |
| 13 #include "cc/output/compositor_frame.h" | 13 #include "cc/output/compositor_frame.h" |
| 14 #include "cc/output/compositor_frame_ack.h" | 14 #include "cc/output/compositor_frame_ack.h" |
| 15 #include "cc/output/direct_renderer.h" | 15 #include "cc/output/direct_renderer.h" |
| 16 #include "cc/output/gl_renderer.h" | 16 #include "cc/output/gl_renderer.h" |
| 17 #include "cc/output/renderer_settings.h" | 17 #include "cc/output/renderer_settings.h" |
| 18 #include "cc/output/software_renderer.h" | 18 #include "cc/output/software_renderer.h" |
| 19 #include "cc/scheduler/delay_based_time_source.h" | 19 #include "cc/output/texture_mailbox_deleter.h" |
| 20 #include "cc/scheduler/begin_frame_source.h" |
| 20 #include "cc/surfaces/display_client.h" | 21 #include "cc/surfaces/display_client.h" |
| 21 #include "cc/surfaces/display_scheduler.h" | 22 #include "cc/surfaces/display_scheduler.h" |
| 22 #include "cc/surfaces/surface.h" | 23 #include "cc/surfaces/surface.h" |
| 23 #include "cc/surfaces/surface_aggregator.h" | 24 #include "cc/surfaces/surface_aggregator.h" |
| 24 #include "cc/surfaces/surface_manager.h" | 25 #include "cc/surfaces/surface_manager.h" |
| 25 #include "gpu/command_buffer/client/gles2_interface.h" | 26 #include "gpu/command_buffer/client/gles2_interface.h" |
| 26 #include "ui/gfx/buffer_types.h" | 27 #include "ui/gfx/buffer_types.h" |
| 27 | 28 |
| 28 #if defined(ENABLE_VULKAN) | 29 #if defined(ENABLE_VULKAN) |
| 29 #include "cc/output/vulkan_renderer.h" | 30 #include "cc/output/vulkan_renderer.h" |
| 30 #endif | 31 #endif |
| 31 | 32 |
| 32 namespace { | |
| 33 | |
| 34 class EmptyBeginFrameSource : public cc::BeginFrameSource { | |
| 35 public: | |
| 36 void DidFinishFrame(cc::BeginFrameObserver* obs, | |
| 37 size_t remaining_frames) override{}; | |
| 38 void AddObserver(cc::BeginFrameObserver* obs) override{}; | |
| 39 void RemoveObserver(cc::BeginFrameObserver* obs) override{}; | |
| 40 }; | |
| 41 | |
| 42 } // namespace | |
| 43 | |
| 44 namespace cc { | 33 namespace cc { |
| 45 | 34 |
| 46 Display::Display(SurfaceManager* manager, | 35 Display::Display(SurfaceManager* manager, |
| 47 SharedBitmapManager* bitmap_manager, | 36 SharedBitmapManager* bitmap_manager, |
| 48 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | 37 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, |
| 49 const RendererSettings& settings, | 38 const RendererSettings& settings, |
| 50 uint32_t compositor_surface_namespace, | 39 uint32_t compositor_surface_namespace, |
| 51 base::SingleThreadTaskRunner* task_runner, | 40 std::unique_ptr<BeginFrameSource> begin_frame_source, |
| 52 std::unique_ptr<OutputSurface> output_surface) | 41 std::unique_ptr<OutputSurface> output_surface, |
| 42 std::unique_ptr<DisplayScheduler> scheduler, |
| 43 std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter) |
| 53 : surface_manager_(manager), | 44 : surface_manager_(manager), |
| 54 bitmap_manager_(bitmap_manager), | 45 bitmap_manager_(bitmap_manager), |
| 55 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), | 46 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
| 56 settings_(settings), | 47 settings_(settings), |
| 57 compositor_surface_namespace_(compositor_surface_namespace), | 48 compositor_surface_namespace_(compositor_surface_namespace), |
| 58 task_runner_(task_runner), | 49 begin_frame_source_(std::move(begin_frame_source)), |
| 59 output_surface_(std::move(output_surface)), | 50 output_surface_(std::move(output_surface)), |
| 60 texture_mailbox_deleter_(task_runner) { | 51 scheduler_(std::move(scheduler)), |
| 52 texture_mailbox_deleter_(std::move(texture_mailbox_deleter)) { |
| 53 DCHECK(surface_manager_); |
| 54 DCHECK(output_surface_); |
| 55 DCHECK(texture_mailbox_deleter_); |
| 56 DCHECK_EQ(!scheduler_, !begin_frame_source_); |
| 57 |
| 61 surface_manager_->AddObserver(this); | 58 surface_manager_->AddObserver(this); |
| 59 |
| 60 if (scheduler_) |
| 61 scheduler_->SetClient(this); |
| 62 } | 62 } |
| 63 | 63 |
| 64 Display::~Display() { | 64 Display::~Display() { |
| 65 if (observed_begin_frame_source_) | 65 // Only do this if Initialize() happened. |
| 66 surface_manager_->UnregisterBeginFrameSource(observed_begin_frame_source_); | 66 if (begin_frame_source_ && client_) |
| 67 surface_manager_->UnregisterBeginFrameSource(begin_frame_source_.get()); |
| 68 |
| 67 surface_manager_->RemoveObserver(this); | 69 surface_manager_->RemoveObserver(this); |
| 68 if (aggregator_) { | 70 if (aggregator_) { |
| 69 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { | 71 for (const auto& id_entry : aggregator_->previous_contained_surfaces()) { |
| 70 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); | 72 Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first); |
| 71 if (surface) | 73 if (surface) |
| 72 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); | 74 surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED); |
| 73 } | 75 } |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 77 void Display::CreateScheduler() { | 79 bool Display::Initialize(DisplayClient* client) { |
| 78 DCHECK(!scheduler_); | 80 DCHECK(client); |
| 79 if (!task_runner_) { | 81 client_ = client; |
| 80 // WebView doesn't have a task runner or a real begin frame source, | |
| 81 // so just create something fake here. | |
| 82 internal_begin_frame_source_.reset(new EmptyBeginFrameSource()); | |
| 83 vsync_begin_frame_source_ = internal_begin_frame_source_.get(); | |
| 84 observed_begin_frame_source_ = vsync_begin_frame_source_; | |
| 85 } else { | |
| 86 DCHECK(vsync_begin_frame_source_); | |
| 87 | 82 |
| 88 observed_begin_frame_source_ = vsync_begin_frame_source_; | 83 // This must be done in Initialize() so that the caller can delay this until |
| 89 if (settings_.disable_display_vsync) { | 84 // they are ready to receive a BeginFrameSource. |
| 90 internal_begin_frame_source_.reset(new BackToBackBeginFrameSource( | 85 if (begin_frame_source_) { |
| 91 base::MakeUnique<DelayBasedTimeSource>(task_runner_))); | 86 surface_manager_->RegisterBeginFrameSource(begin_frame_source_.get(), |
| 92 observed_begin_frame_source_ = internal_begin_frame_source_.get(); | 87 compositor_surface_namespace_); |
| 93 } | |
| 94 } | 88 } |
| 95 | 89 |
| 96 scheduler_.reset( | 90 // TODO(danakj): The context given to the Display's OutputSurface should |
| 97 new DisplayScheduler(this, observed_begin_frame_source_, task_runner_, | 91 // already be initialized, so Bind can not fail. DCHECK this instead of |
| 98 output_surface_->capabilities().max_frames_pending)); | 92 // returning. |
| 99 surface_manager_->RegisterBeginFrameSource(observed_begin_frame_source_, | 93 return output_surface_->BindToClient(this); |
| 100 compositor_surface_namespace_); | |
| 101 } | |
| 102 | |
| 103 bool Display::Initialize(DisplayClient* client) { | |
| 104 client_ = client; | |
| 105 if (!output_surface_->BindToClient(this)) | |
| 106 return false; | |
| 107 CreateScheduler(); | |
| 108 return true; | |
| 109 } | |
| 110 | |
| 111 bool Display::InitializeSynchronous(DisplayClient* client) { | |
| 112 client_ = client; | |
| 113 if (!output_surface_->BindToClient(this)) | |
| 114 return false; | |
| 115 // No scheduler created here. | |
| 116 return true; | |
| 117 } | 94 } |
| 118 | 95 |
| 119 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { | 96 void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) { |
| 120 DCHECK_EQ(id.id_namespace(), compositor_surface_namespace_); | 97 DCHECK_EQ(id.id_namespace(), compositor_surface_namespace_); |
| 121 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) | 98 if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) |
| 122 return; | 99 return; |
| 123 | 100 |
| 124 TRACE_EVENT0("cc", "Display::SetSurfaceId"); | 101 TRACE_EVENT0("cc", "Display::SetSurfaceId"); |
| 125 current_surface_id_ = id; | 102 current_surface_id_ = id; |
| 126 device_scale_factor_ = device_scale_factor; | 103 device_scale_factor_ = device_scale_factor; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 gpu_memory_buffer_manager_, nullptr, settings_.highp_threshold_min, | 154 gpu_memory_buffer_manager_, nullptr, settings_.highp_threshold_min, |
| 178 settings_.texture_id_allocation_chunk_size, | 155 settings_.texture_id_allocation_chunk_size, |
| 179 output_surface_->capabilities().delegated_sync_points_required, | 156 output_surface_->capabilities().delegated_sync_points_required, |
| 180 settings_.use_gpu_memory_buffer_resources, | 157 settings_.use_gpu_memory_buffer_resources, |
| 181 std::vector<unsigned>(static_cast<size_t>(gfx::BufferFormat::LAST) + 1, | 158 std::vector<unsigned>(static_cast<size_t>(gfx::BufferFormat::LAST) + 1, |
| 182 GL_TEXTURE_2D))); | 159 GL_TEXTURE_2D))); |
| 183 | 160 |
| 184 if (output_surface_->context_provider()) { | 161 if (output_surface_->context_provider()) { |
| 185 std::unique_ptr<GLRenderer> renderer = GLRenderer::Create( | 162 std::unique_ptr<GLRenderer> renderer = GLRenderer::Create( |
| 186 this, &settings_, output_surface_.get(), resource_provider.get(), | 163 this, &settings_, output_surface_.get(), resource_provider.get(), |
| 187 &texture_mailbox_deleter_, settings_.highp_threshold_min); | 164 texture_mailbox_deleter_.get(), settings_.highp_threshold_min); |
| 188 if (!renderer) | 165 if (!renderer) |
| 189 return; | 166 return; |
| 190 renderer_ = std::move(renderer); | 167 renderer_ = std::move(renderer); |
| 191 } else if (output_surface_->vulkan_context_provider()) { | 168 } else if (output_surface_->vulkan_context_provider()) { |
| 192 #if defined(ENABLE_VULKAN) | 169 #if defined(ENABLE_VULKAN) |
| 193 std::unique_ptr<VulkanRenderer> renderer = VulkanRenderer::Create( | 170 std::unique_ptr<VulkanRenderer> renderer = VulkanRenderer::Create( |
| 194 this, &settings_, output_surface_.get(), resource_provider.get(), | 171 this, &settings_, output_surface_.get(), resource_provider.get(), |
| 195 &texture_mailbox_deleter_, settings_.highp_threshold_min); | 172 texture_mailbox_deleter_.get(), settings_.highp_threshold_min); |
| 196 if (!renderer) | 173 if (!renderer) |
| 197 return; | 174 return; |
| 198 renderer_ = std::move(renderer); | 175 renderer_ = std::move(renderer); |
| 199 #else | 176 #else |
| 200 NOTREACHED(); | 177 NOTREACHED(); |
| 201 #endif | 178 #endif |
| 202 } else { | 179 } else { |
| 203 std::unique_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( | 180 std::unique_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( |
| 204 this, &settings_, output_surface_.get(), resource_provider.get(), | 181 this, &settings_, output_surface_.get(), resource_provider.get(), |
| 205 true /* use_image_hijack_canvas */); | 182 true /* use_image_hijack_canvas */); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 scheduler_->DidSwapBuffers(); | 327 scheduler_->DidSwapBuffers(); |
| 351 } | 328 } |
| 352 | 329 |
| 353 void Display::DidSwapBuffersComplete() { | 330 void Display::DidSwapBuffersComplete() { |
| 354 if (scheduler_) | 331 if (scheduler_) |
| 355 scheduler_->DidSwapBuffersComplete(); | 332 scheduler_->DidSwapBuffersComplete(); |
| 356 if (renderer_) | 333 if (renderer_) |
| 357 renderer_->SwapBuffersComplete(); | 334 renderer_->SwapBuffersComplete(); |
| 358 } | 335 } |
| 359 | 336 |
| 337 void Display::CommitVSyncParameters(base::TimeTicks timebase, |
| 338 base::TimeDelta interval) { |
| 339 // Display uses a BeginFrameSource instead. |
| 340 NOTREACHED(); |
| 341 } |
| 342 |
| 360 void Display::SetBeginFrameSource(BeginFrameSource* source) { | 343 void Display::SetBeginFrameSource(BeginFrameSource* source) { |
| 361 // It's expected that there's only a single source from the | 344 // The BeginFrameSource is set from the constructor, it doesn't come |
| 362 // BrowserCompositorOutputSurface that corresponds to vsync. The BFS is | 345 // from the OutputSurface for the Display. |
| 363 // passed BrowserCompositorOutputSurface -> Display -> DisplayScheduler as an | 346 NOTREACHED(); |
| 364 // input. DisplayScheduler makes a decision about which BFS to use and | |
| 365 // calls back to Display as DisplaySchedulerClient to register for that | |
| 366 // surface id. | |
| 367 DCHECK(!vsync_begin_frame_source_); | |
| 368 vsync_begin_frame_source_ = source; | |
| 369 } | 347 } |
| 370 | 348 |
| 371 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { | 349 void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { |
| 372 client_->DisplaySetMemoryPolicy(policy); | 350 client_->DisplaySetMemoryPolicy(policy); |
| 373 } | 351 } |
| 374 | 352 |
| 375 void Display::OnDraw(const gfx::Transform& transform, | 353 void Display::OnDraw(const gfx::Transform& transform, |
| 376 const gfx::Rect& viewport, | 354 const gfx::Rect& viewport, |
| 377 const gfx::Rect& clip, | 355 const gfx::Rect& clip, |
| 378 bool resourceless_software_draw) { | 356 bool resourceless_software_draw) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 | 404 |
| 427 if (surface_id == current_surface_id_) | 405 if (surface_id == current_surface_id_) |
| 428 UpdateRootSurfaceResourcesLocked(); | 406 UpdateRootSurfaceResourcesLocked(); |
| 429 } | 407 } |
| 430 | 408 |
| 431 SurfaceId Display::CurrentSurfaceId() { | 409 SurfaceId Display::CurrentSurfaceId() { |
| 432 return current_surface_id_; | 410 return current_surface_id_; |
| 433 } | 411 } |
| 434 | 412 |
| 435 } // namespace cc | 413 } // namespace cc |
| OLD | NEW |