| 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/surface_display_output_surface.h" | 5 #include "cc/surfaces/surface_display_output_surface.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "cc/output/compositor_frame.h" | 8 #include "cc/output/compositor_frame.h" |
| 9 #include "cc/output/compositor_frame_ack.h" | 9 #include "cc/output/compositor_frame_ack.h" |
| 10 #include "cc/surfaces/display.h" | 10 #include "cc/surfaces/display.h" |
| 11 #include "cc/surfaces/onscreen_display_client.h" | |
| 12 #include "cc/surfaces/surface.h" | 11 #include "cc/surfaces/surface.h" |
| 12 #include "cc/surfaces/surface_id_allocator.h" |
| 13 #include "cc/surfaces/surface_manager.h" | 13 #include "cc/surfaces/surface_manager.h" |
| 14 | 14 |
| 15 namespace cc { | 15 namespace cc { |
| 16 | 16 |
| 17 SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( | 17 SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( |
| 18 SurfaceManager* surface_manager, | 18 SurfaceManager* surface_manager, |
| 19 SurfaceIdAllocator* allocator, | 19 SurfaceIdAllocator* surface_id_allocator, |
| 20 Display* display, |
| 20 scoped_refptr<ContextProvider> context_provider, | 21 scoped_refptr<ContextProvider> context_provider, |
| 21 scoped_refptr<ContextProvider> worker_context_provider) | 22 scoped_refptr<ContextProvider> worker_context_provider) |
| 22 : OutputSurface(std::move(context_provider), | 23 : OutputSurface(std::move(context_provider), |
| 23 std::move(worker_context_provider), | 24 std::move(worker_context_provider), |
| 24 nullptr), | 25 nullptr), |
| 25 display_client_(nullptr), | 26 surface_manager_(surface_manager), |
| 26 factory_(surface_manager, this), | 27 surface_id_allocator_(surface_id_allocator), |
| 27 allocator_(allocator) { | 28 display_(display), |
| 28 factory_.set_needs_sync_points(false); | 29 factory_(surface_manager, this) { |
| 30 DCHECK(thread_checker_.CalledOnValidThread()); |
| 29 capabilities_.delegated_rendering = true; | 31 capabilities_.delegated_rendering = true; |
| 30 capabilities_.adjust_deadline_for_parent = true; | 32 capabilities_.adjust_deadline_for_parent = true; |
| 31 capabilities_.can_force_reclaim_resources = true; | 33 capabilities_.can_force_reclaim_resources = true; |
| 34 |
| 32 // Display and SurfaceDisplayOutputSurface share a GL context, so sync | 35 // Display and SurfaceDisplayOutputSurface share a GL context, so sync |
| 33 // points aren't needed when passing resources between them. | 36 // points aren't needed when passing resources between them. |
| 34 capabilities_.delegated_sync_points_required = false; | 37 capabilities_.delegated_sync_points_required = false; |
| 38 factory_.set_needs_sync_points(false); |
| 35 } | 39 } |
| 36 | 40 |
| 37 SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( | 41 SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface( |
| 38 SurfaceManager* surface_manager, | 42 SurfaceManager* surface_manager, |
| 39 SurfaceIdAllocator* allocator, | 43 SurfaceIdAllocator* surface_id_allocator, |
| 44 Display* display, |
| 40 scoped_refptr<VulkanContextProvider> vulkan_context_provider) | 45 scoped_refptr<VulkanContextProvider> vulkan_context_provider) |
| 41 : OutputSurface(std::move(vulkan_context_provider)), | 46 : OutputSurface(std::move(vulkan_context_provider)), |
| 42 display_client_(nullptr), | 47 surface_manager_(surface_manager), |
| 43 factory_(surface_manager, this), | 48 surface_id_allocator_(surface_id_allocator), |
| 44 allocator_(allocator) { | 49 display_(display), |
| 50 factory_(surface_manager, this) { |
| 51 DCHECK(thread_checker_.CalledOnValidThread()); |
| 45 capabilities_.delegated_rendering = true; | 52 capabilities_.delegated_rendering = true; |
| 46 capabilities_.adjust_deadline_for_parent = true; | 53 capabilities_.adjust_deadline_for_parent = true; |
| 47 capabilities_.can_force_reclaim_resources = true; | 54 capabilities_.can_force_reclaim_resources = true; |
| 48 } | 55 } |
| 49 | 56 |
| 50 SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() { | 57 SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() { |
| 58 DCHECK(thread_checker_.CalledOnValidThread()); |
| 51 if (HasClient()) | 59 if (HasClient()) |
| 52 DetachFromClient(); | 60 DetachFromClient(); |
| 53 if (!surface_id_.is_null()) { | |
| 54 factory_.Destroy(surface_id_); | |
| 55 } | |
| 56 } | 61 } |
| 57 | 62 |
| 58 void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) { | 63 void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) { |
| 59 gfx::Size frame_size = | 64 gfx::Size frame_size = |
| 60 frame->delegated_frame_data->render_pass_list.back()->output_rect.size(); | 65 frame->delegated_frame_data->render_pass_list.back()->output_rect.size(); |
| 61 if (frame_size.IsEmpty() || frame_size != display_size_) { | 66 if (frame_size.IsEmpty() || frame_size != last_swap_frame_size_) { |
| 62 if (!surface_id_.is_null()) { | 67 if (!delegated_surface_id_.is_null()) { |
| 63 factory_.Destroy(surface_id_); | 68 factory_.Destroy(delegated_surface_id_); |
| 64 } | 69 } |
| 65 surface_id_ = allocator_->GenerateId(); | 70 delegated_surface_id_ = surface_id_allocator_->GenerateId(); |
| 66 factory_.Create(surface_id_); | 71 factory_.Create(delegated_surface_id_); |
| 67 display_size_ = frame_size; | 72 last_swap_frame_size_ = frame_size; |
| 68 } | 73 } |
| 69 display_client_->display()->SetSurfaceId(surface_id_, | 74 display_->SetSurfaceId(delegated_surface_id_, |
| 70 frame->metadata.device_scale_factor); | 75 frame->metadata.device_scale_factor); |
| 71 | 76 |
| 72 client_->DidSwapBuffers(); | 77 client_->DidSwapBuffers(); |
| 73 | 78 |
| 74 std::unique_ptr<CompositorFrame> frame_copy(new CompositorFrame()); | 79 std::unique_ptr<CompositorFrame> frame_copy(new CompositorFrame()); |
| 75 frame->AssignTo(frame_copy.get()); | 80 frame->AssignTo(frame_copy.get()); |
| 76 factory_.SubmitCompositorFrame( | 81 factory_.SubmitCompositorFrame( |
| 77 surface_id_, std::move(frame_copy), | 82 delegated_surface_id_, std::move(frame_copy), |
| 78 base::Bind(&SurfaceDisplayOutputSurface::SwapBuffersComplete, | 83 base::Bind(&SurfaceDisplayOutputSurface::SwapBuffersComplete, |
| 79 base::Unretained(this))); | 84 base::Unretained(this))); |
| 80 } | 85 } |
| 81 | 86 |
| 82 bool SurfaceDisplayOutputSurface::BindToClient(OutputSurfaceClient* client) { | 87 bool SurfaceDisplayOutputSurface::BindToClient(OutputSurfaceClient* client) { |
| 83 DCHECK(client); | 88 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 DCHECK(display_client_); | 89 if (!OutputSurface::BindToClient(client)) |
| 85 client_ = client; | 90 return false; |
| 86 factory_.manager()->RegisterSurfaceFactoryClient(allocator_->id_namespace(), | |
| 87 this); | |
| 88 | 91 |
| 92 // We want the Display's output surface to hear about lost context, and since |
| 93 // this shares a context with it, we should not be listening for lost context |
| 94 // callbacks on the context here. |
| 95 if (context_provider()) |
| 96 context_provider()->SetLostContextCallback(base::Closure()); |
| 97 |
| 98 surface_manager_->RegisterSurfaceFactoryClient( |
| 99 surface_id_allocator_->id_namespace(), this); |
| 89 // Avoid initializing GL context here, as this should be sharing the | 100 // Avoid initializing GL context here, as this should be sharing the |
| 90 // Display's context. | 101 // Display's context. |
| 91 return display_client_->Initialize(); | 102 bool init = display_->Initialize(this); |
| 103 // Since this class shares its GL context with the Display, Initialize should |
| 104 // not be possible to fail. |
| 105 DCHECK(init); |
| 106 return true; |
| 92 } | 107 } |
| 93 | 108 |
| 94 void SurfaceDisplayOutputSurface::ForceReclaimResources() { | 109 void SurfaceDisplayOutputSurface::ForceReclaimResources() { |
| 95 if (!surface_id_.is_null()) | 110 if (!delegated_surface_id_.is_null()) { |
| 96 factory_.SubmitCompositorFrame(surface_id_, nullptr, | 111 factory_.SubmitCompositorFrame(delegated_surface_id_, nullptr, |
| 97 SurfaceFactory::DrawCallback()); | 112 SurfaceFactory::DrawCallback()); |
| 113 } |
| 98 } | 114 } |
| 99 | 115 |
| 100 void SurfaceDisplayOutputSurface::DetachFromClient() { | 116 void SurfaceDisplayOutputSurface::DetachFromClient() { |
| 101 DCHECK(HasClient()); | 117 DCHECK(HasClient()); |
| 102 // Unregister the SurfaceFactoryClient here instead of the dtor so that only | 118 // Unregister the SurfaceFactoryClient here instead of the dtor so that only |
| 103 // one client is alive for this namespace at any given time. | 119 // one client is alive for this namespace at any given time. |
| 104 factory_.manager()->UnregisterSurfaceFactoryClient( | 120 surface_manager_->UnregisterSurfaceFactoryClient( |
| 105 allocator_->id_namespace()); | 121 surface_id_allocator_->id_namespace()); |
| 122 if (!delegated_surface_id_.is_null()) |
| 123 factory_.Destroy(delegated_surface_id_); |
| 124 |
| 106 OutputSurface::DetachFromClient(); | 125 OutputSurface::DetachFromClient(); |
| 107 DCHECK(!HasClient()); | |
| 108 } | 126 } |
| 109 | 127 |
| 110 void SurfaceDisplayOutputSurface::ReturnResources( | 128 void SurfaceDisplayOutputSurface::ReturnResources( |
| 111 const ReturnedResourceArray& resources) { | 129 const ReturnedResourceArray& resources) { |
| 112 CompositorFrameAck ack; | 130 CompositorFrameAck ack; |
| 113 ack.resources = resources; | 131 ack.resources = resources; |
| 114 if (client_) | 132 if (client_) |
| 115 client_->ReclaimResources(&ack); | 133 client_->ReclaimResources(&ack); |
| 116 } | 134 } |
| 117 | 135 |
| 118 void SurfaceDisplayOutputSurface::SetBeginFrameSource( | 136 void SurfaceDisplayOutputSurface::SetBeginFrameSource( |
| 119 BeginFrameSource* begin_frame_source) { | 137 BeginFrameSource* begin_frame_source) { |
| 120 DCHECK(client_); | 138 DCHECK(client_); |
| 121 client_->SetBeginFrameSource(begin_frame_source); | 139 client_->SetBeginFrameSource(begin_frame_source); |
| 122 } | 140 } |
| 123 | 141 |
| 142 void SurfaceDisplayOutputSurface::DisplayOutputSurfaceLost() { |
| 143 output_surface_lost_ = true; |
| 144 DidLoseOutputSurface(); |
| 145 } |
| 146 |
| 147 void SurfaceDisplayOutputSurface::DisplaySetMemoryPolicy( |
| 148 const ManagedMemoryPolicy& policy) { |
| 149 SetMemoryPolicy(policy); |
| 150 } |
| 151 |
| 124 void SurfaceDisplayOutputSurface::SwapBuffersComplete(SurfaceDrawStatus drawn) { | 152 void SurfaceDisplayOutputSurface::SwapBuffersComplete(SurfaceDrawStatus drawn) { |
| 125 if (client_ && !display_client_->output_surface_lost()) | 153 // TODO(danakj): Why the lost check? |
| 154 if (!output_surface_lost_) |
| 126 client_->DidSwapBuffersComplete(); | 155 client_->DidSwapBuffersComplete(); |
| 127 } | 156 } |
| 128 | 157 |
| 129 } // namespace cc | 158 } // namespace cc |
| OLD | NEW |