OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/renderer/browser_plugin/browser_plugin_compositing_helper.h" | 5 #include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h" |
6 | 6 |
7 #include "cc/layers/delegated_renderer_layer.h" | 7 #include "cc/layers/delegated_renderer_layer.h" |
8 #include "cc/layers/solid_color_layer.h" | 8 #include "cc/layers/solid_color_layer.h" |
9 #include "cc/layers/texture_layer.h" | 9 #include "cc/layers/texture_layer.h" |
10 #include "cc/output/context_provider.h" | 10 #include "cc/output/context_provider.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 buffer_size_ = new_size; | 77 buffer_size_ = new_size; |
78 // The container size is in DIP, so is the layer size. | 78 // The container size is in DIP, so is the layer size. |
79 // Buffer size is in physical pixels, so we need to adjust | 79 // Buffer size is in physical pixels, so we need to adjust |
80 // it by the device scale factor. | 80 // it by the device scale factor. |
81 gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize( | 81 gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize( |
82 gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor)); | 82 gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor)); |
83 layer->SetBounds(device_scale_adjusted_size); | 83 layer->SetBounds(device_scale_adjusted_size); |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 // If we have a mailbox that was freed up from the compositor, | |
88 // but we are not expected to return it to the guest renderer | |
89 // via an ACK, we should free it because we now own it. | |
90 // To free the mailbox memory, we need a context to consume it | |
91 // into a texture ID and then delete this texture ID. | |
92 // We use a shared graphics context accessible from the main | |
93 // thread to do it. | |
94 void BrowserPluginCompositingHelper::FreeMailboxMemory( | |
95 const std::string& mailbox_name, | |
96 unsigned sync_point) { | |
97 if (mailbox_name.empty()) | |
98 return; | |
99 | |
100 scoped_refptr<cc::ContextProvider> context_provider = | |
101 RenderThreadImpl::current()->OffscreenContextProviderForMainThread(); | |
102 if (!context_provider.get()) | |
103 return; | |
104 | |
105 WebKit::WebGraphicsContext3D *context = context_provider->Context3d(); | |
106 // When a buffer is released from the compositor, we also get a | |
107 // sync point that specifies when in the command buffer | |
108 // it's safe to use it again. | |
109 // If the sync point is non-zero, we need to tell our context | |
110 // to wait until this sync point is reached before we can safely | |
111 // delete the buffer. | |
112 if (sync_point) | |
113 context->waitSyncPoint(sync_point); | |
114 | |
115 unsigned texture_id = context->createTexture(); | |
116 context->bindTexture(GL_TEXTURE_2D, texture_id); | |
117 context->consumeTextureCHROMIUM( | |
118 GL_TEXTURE_2D, | |
119 reinterpret_cast<const int8*>(mailbox_name.data())); | |
120 context->deleteTexture(texture_id); | |
121 } | |
122 | |
123 void BrowserPluginCompositingHelper::MailboxReleased( | 87 void BrowserPluginCompositingHelper::MailboxReleased( |
124 const std::string& mailbox_name, | 88 const std::string& mailbox_name, |
125 int gpu_route_id, | 89 int gpu_route_id, |
126 int gpu_host_id, | 90 int gpu_host_id, |
127 unsigned sync_point, | 91 unsigned sync_point, |
128 bool lost_resource) { | 92 bool lost_resource) { |
129 if (lost_resource) { | 93 if (lost_resource) { |
130 // Recurse with an empty mailbox if the one being released was lost. | 94 // Recurse with an empty mailbox if the one being released was lost. |
131 MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0, false); | 95 MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0, false); |
132 return; | 96 return; |
133 } | 97 } |
134 | 98 |
135 // This means the GPU process crashed and we have nothing further to do. | 99 // This means the GPU process crashed and we have nothing further to do. |
136 // Nobody is expecting an ACK and the buffer doesn't need to be deleted | 100 // Nobody is expecting an ACK and the buffer doesn't need to be deleted |
137 // because it went away with the GPU process. | 101 // because it went away with the GPU process. |
138 if (last_host_id_ != gpu_host_id) | 102 if (last_host_id_ != gpu_host_id) |
139 return; | 103 return; |
140 | 104 |
141 // This means the guest crashed. | 105 // This means the guest crashed. |
142 // Either ACK the last buffer, so texture transport could | 106 // Either ACK the last buffer, so texture transport could |
143 // be destroyed of delete the mailbox if nobody wants it back. | 107 // be destroyed of delete the mailbox if nobody wants it back. |
144 if (last_route_id_ != gpu_route_id) { | 108 if (last_route_id_ != gpu_route_id) { |
145 if (!ack_pending_for_crashed_guest_) { | 109 if (ack_pending_for_crashed_guest_) { |
146 FreeMailboxMemory(mailbox_name, sync_point); | |
147 } else { | |
148 ack_pending_for_crashed_guest_ = false; | 110 ack_pending_for_crashed_guest_ = false; |
149 browser_plugin_manager_->Send( | 111 browser_plugin_manager_->Send( |
150 new BrowserPluginHostMsg_BuffersSwappedACK( | 112 new BrowserPluginHostMsg_BuffersSwappedACK( |
151 host_routing_id_, | 113 host_routing_id_, |
152 instance_id_, | 114 instance_id_, |
153 gpu_route_id, | 115 gpu_route_id, |
154 gpu_host_id, | 116 gpu_host_id, |
155 mailbox_name, | 117 mailbox_name, |
156 sync_point)); | 118 sync_point)); |
157 } | 119 } |
158 return; | 120 return; |
159 } | 121 } |
160 | 122 |
161 // We need to send an ACK to TextureImageTransportSurface | 123 // We need to send an ACK to TextureImageTransportSurface |
162 // for every buffer it sends us. However, if a buffer is freed up from | 124 // for every buffer it sends us. However, if a buffer is freed up from |
163 // the compositor in cases like switching back to SW mode without a new | 125 // the compositor in cases like switching back to SW mode without a new |
164 // buffer arriving, no ACK is needed and we destroy this buffer. | 126 // buffer arriving, no ACK is needed and we destroy this buffer. |
165 if (!ack_pending_) { | 127 if (!ack_pending_) { |
166 FreeMailboxMemory(mailbox_name, sync_point); | |
167 last_mailbox_valid_ = false; | 128 last_mailbox_valid_ = false; |
168 return; | 129 return; |
169 } | 130 } |
170 ack_pending_ = false; | 131 ack_pending_ = false; |
171 browser_plugin_manager_->Send( | 132 browser_plugin_manager_->Send( |
172 new BrowserPluginHostMsg_BuffersSwappedACK( | 133 new BrowserPluginHostMsg_BuffersSwappedACK( |
173 host_routing_id_, | 134 host_routing_id_, |
174 instance_id_, | 135 instance_id_, |
175 gpu_route_id, | 136 gpu_route_id, |
176 gpu_host_id, | 137 gpu_host_id, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 } | 252 } |
292 | 253 |
293 void BrowserPluginCompositingHelper::UpdateVisibility(bool visible) { | 254 void BrowserPluginCompositingHelper::UpdateVisibility(bool visible) { |
294 if (texture_layer_.get()) | 255 if (texture_layer_.get()) |
295 texture_layer_->SetIsDrawable(visible); | 256 texture_layer_->SetIsDrawable(visible); |
296 if (delegated_layer_.get()) | 257 if (delegated_layer_.get()) |
297 delegated_layer_->SetIsDrawable(visible); | 258 delegated_layer_->SetIsDrawable(visible); |
298 } | 259 } |
299 | 260 |
300 } // namespace content | 261 } // namespace content |
OLD | NEW |