OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/gpu/compositor_output_surface.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/command_line.h" | |
10 #include "base/location.h" | |
11 #include "base/single_thread_task_runner.h" | |
12 #include "base/threading/thread_task_runner_handle.h" | |
13 #include "build/build_config.h" | |
14 #include "cc/output/compositor_frame.h" | |
15 #include "cc/output/managed_memory_policy.h" | |
16 #include "cc/output/output_surface_client.h" | |
17 #include "content/common/gpu/client/context_provider_command_buffer.h" | |
18 #include "content/common/view_messages.h" | |
19 #include "content/public/common/content_switches.h" | |
20 #include "content/renderer/gpu/frame_swap_message_queue.h" | |
21 #include "content/renderer/render_thread_impl.h" | |
22 #include "gpu/command_buffer/client/context_support.h" | |
23 #include "gpu/command_buffer/client/gles2_interface.h" | |
24 #include "gpu/ipc/client/command_buffer_proxy_impl.h" | |
25 #include "ipc/ipc_sync_channel.h" | |
26 | |
27 namespace content { | |
28 | |
29 CompositorOutputSurface::CompositorOutputSurface( | |
30 int32_t routing_id, | |
31 uint32_t output_surface_id, | |
32 std::unique_ptr<cc::BeginFrameSource> begin_frame_source, | |
33 scoped_refptr<cc::ContextProvider> context_provider, | |
34 scoped_refptr<cc::ContextProvider> worker_context_provider, | |
35 scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue) | |
36 : OutputSurface(std::move(context_provider), | |
37 std::move(worker_context_provider), | |
38 nullptr), | |
39 output_surface_id_(output_surface_id), | |
40 output_surface_filter_( | |
41 RenderThreadImpl::current()->compositor_message_filter()), | |
42 message_sender_(RenderThreadImpl::current()->sync_message_filter()), | |
43 frame_swap_message_queue_(swap_frame_message_queue), | |
44 begin_frame_source_(std::move(begin_frame_source)), | |
45 routing_id_(routing_id) { | |
46 DCHECK(output_surface_filter_); | |
47 DCHECK(frame_swap_message_queue_); | |
48 DCHECK(message_sender_); | |
49 DCHECK(begin_frame_source_); | |
50 capabilities_.delegated_rendering = true; | |
51 } | |
52 | |
53 CompositorOutputSurface::CompositorOutputSurface( | |
54 int32_t routing_id, | |
55 uint32_t output_surface_id, | |
56 std::unique_ptr<cc::BeginFrameSource> begin_frame_source, | |
57 scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider, | |
58 scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue) | |
59 : OutputSurface(std::move(vulkan_context_provider)), | |
60 output_surface_id_(output_surface_id), | |
61 output_surface_filter_( | |
62 RenderThreadImpl::current()->compositor_message_filter()), | |
63 message_sender_(RenderThreadImpl::current()->sync_message_filter()), | |
64 frame_swap_message_queue_(swap_frame_message_queue), | |
65 begin_frame_source_(std::move(begin_frame_source)), | |
66 routing_id_(routing_id) { | |
67 DCHECK(output_surface_filter_); | |
68 DCHECK(frame_swap_message_queue_); | |
69 DCHECK(message_sender_); | |
70 DCHECK(begin_frame_source_); | |
71 capabilities_.delegated_rendering = true; | |
72 } | |
73 | |
74 CompositorOutputSurface::~CompositorOutputSurface() = default; | |
75 | |
76 bool CompositorOutputSurface::BindToClient( | |
77 cc::OutputSurfaceClient* client) { | |
78 if (!cc::OutputSurface::BindToClient(client)) | |
79 return false; | |
80 | |
81 DCHECK(begin_frame_source_); | |
82 client_->SetBeginFrameSource(begin_frame_source_.get()); | |
83 | |
84 output_surface_proxy_ = new CompositorOutputSurfaceProxy(this); | |
85 output_surface_filter_handler_ = | |
86 base::Bind(&CompositorOutputSurfaceProxy::OnMessageReceived, | |
87 output_surface_proxy_); | |
88 output_surface_filter_->AddHandlerOnCompositorThread( | |
89 routing_id_, | |
90 output_surface_filter_handler_); | |
91 return true; | |
92 } | |
93 | |
94 void CompositorOutputSurface::DetachFromClient() { | |
95 if (!HasClient()) | |
96 return; | |
97 client_->SetBeginFrameSource(nullptr); | |
98 // Destroy the begin frame source on the same thread it was bound on. | |
99 // The OutputSurface itself is destroyed on the main thread. | |
100 begin_frame_source_ = nullptr; | |
101 | |
102 if (output_surface_proxy_) { | |
103 output_surface_proxy_->ClearOutputSurface(); | |
104 output_surface_filter_->RemoveHandlerOnCompositorThread( | |
105 routing_id_, output_surface_filter_handler_); | |
106 } | |
107 cc::OutputSurface::DetachFromClient(); | |
108 } | |
109 | |
110 void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame frame) { | |
111 { | |
112 std::unique_ptr<FrameSwapMessageQueue::SendMessageScope> | |
113 send_message_scope = | |
114 frame_swap_message_queue_->AcquireSendMessageScope(); | |
115 std::vector<std::unique_ptr<IPC::Message>> messages; | |
116 std::vector<IPC::Message> messages_to_deliver_with_frame; | |
117 frame_swap_message_queue_->DrainMessages(&messages); | |
118 FrameSwapMessageQueue::TransferMessages(&messages, | |
119 &messages_to_deliver_with_frame); | |
120 Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, output_surface_id_, | |
121 frame, | |
122 messages_to_deliver_with_frame)); | |
123 // ~send_message_scope. | |
124 } | |
125 } | |
126 | |
127 void CompositorOutputSurface::BindFramebuffer() { | |
128 // This is a delegating output surface, no framebuffer/direct drawing support. | |
129 NOTREACHED(); | |
130 } | |
131 | |
132 uint32_t CompositorOutputSurface::GetFramebufferCopyTextureFormat() { | |
133 // This is a delegating output surface, no framebuffer/direct drawing support. | |
134 NOTREACHED(); | |
135 return 0; | |
136 } | |
137 | |
138 void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) { | |
139 DCHECK(client_thread_checker_.CalledOnValidThread()); | |
140 if (!HasClient()) | |
141 return; | |
142 IPC_BEGIN_MESSAGE_MAP(CompositorOutputSurface, message) | |
143 IPC_MESSAGE_HANDLER(ViewMsg_ReclaimCompositorResources, | |
144 OnReclaimCompositorResources); | |
145 IPC_END_MESSAGE_MAP() | |
146 } | |
147 | |
148 void CompositorOutputSurface::OnReclaimCompositorResources( | |
149 uint32_t output_surface_id, | |
150 bool is_swap_ack, | |
151 const cc::ReturnedResourceArray& resources) { | |
152 // Ignore message if it's a stale one coming from a different output surface | |
153 // (e.g. after a lost context). | |
154 if (output_surface_id != output_surface_id_) | |
155 return; | |
156 client_->ReclaimResources(resources); | |
157 if (is_swap_ack) | |
158 client_->DidSwapBuffersComplete(); | |
159 } | |
160 | |
161 bool CompositorOutputSurface::Send(IPC::Message* message) { | |
162 return message_sender_->Send(message); | |
163 } | |
164 | |
165 } // namespace content | |
OLD | NEW |