blob: 408fc0817b9fc0d86e739dd89fab2cdf9eafa872 [file] [log] [blame]
[email protected]bffc8302014-01-23 20:52:161// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]0f21e8582013-01-11 11:06:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]bffc8302014-01-23 20:52:165#include "content/renderer/child_frame_compositing_helper.h"
[email protected]0f21e8582013-01-11 11:06:566
dcheng07945f632015-12-26 07:59:327#include <utility>
8
[email protected]38564622014-08-19 02:47:189#include "cc/blink/web_layer_impl.h"
[email protected]09f67382013-10-09 21:03:4510#include "cc/layers/delegated_frame_provider.h"
11#include "cc/layers/delegated_frame_resource_collection.h"
[email protected]f5b4b0f2013-04-02 18:16:2812#include "cc/layers/delegated_renderer_layer.h"
[email protected]cc3cfaa2013-03-18 09:05:5213#include "cc/layers/solid_color_layer.h"
kenrbfc7c02c92015-05-29 22:20:5814#include "cc/layers/surface_layer.h"
[email protected]7f0d825f2013-03-18 07:24:3015#include "cc/output/context_provider.h"
[email protected]73405fb2013-12-11 04:59:3716#include "cc/output/copy_output_request.h"
17#include "cc/output/copy_output_result.h"
[email protected]9260757f2013-09-17 01:24:1618#include "cc/resources/single_release_callback.h"
jbauman38c178eaa2015-06-04 04:24:5419#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4220#include "content/common/browser_plugin/browser_plugin_messages.h"
[email protected]95d31822014-01-03 22:21:5521#include "content/common/frame_messages.h"
[email protected]a45c46e2013-03-07 01:04:4622#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]94224ba62014-02-04 00:25:2423#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2124#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1625#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2726#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5627#include "content/renderer/render_thread_impl.h"
[email protected]73405fb2013-12-11 04:59:3728#include "skia/ext/image_operations.h"
[email protected]bffc8302014-01-23 20:52:1629#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]2255a9332013-06-17 05:12:3130#include "third_party/WebKit/public/web/WebPluginContainer.h"
[email protected]7f0d825f2013-03-18 07:24:3031#include "third_party/khronos/GLES2/gl2.h"
tfarinaebe974f02015-01-03 04:25:3232#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3733#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5634
35namespace content {
36
[email protected]bffc8302014-01-23 20:52:1637ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3338ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:2439 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:1640 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:5841 browser_plugin, nullptr, nullptr,
42 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:1643}
44
45ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3346ChildFrameCompositingHelper::CreateForRenderFrameProxy(
47 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:5348 return new ChildFrameCompositingHelper(
49 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
50 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:1651}
52
53ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:2454 const base::WeakPtr<BrowserPlugin>& browser_plugin,
[email protected]bffc8302014-01-23 20:52:1655 blink::WebFrame* frame,
[email protected]e3244ed2014-06-20 20:04:2756 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:5657 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:2458 : host_routing_id_(host_routing_id),
[email protected]f5b4b0f2013-04-02 18:16:2859 last_route_id_(0),
[email protected]53b4cc12013-07-18 23:02:3060 last_output_surface_id_(0),
[email protected]f5b4b0f2013-04-02 18:16:2861 last_host_id_(0),
[email protected]0d25cb62013-01-21 15:42:2162 ack_pending_(true),
[email protected]94224ba62014-02-04 00:25:2463 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:2764 render_frame_proxy_(render_frame_proxy),
lfgfd437a272015-11-24 21:24:5365 frame_(frame) {}
[email protected]bffc8302014-01-23 20:52:1666
lfga7d368e2015-02-03 23:01:3767ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
68 if (resource_collection_.get())
kenrbfc7c02c92015-05-29 22:20:5869 resource_collection_->SetClient(nullptr);
lfga7d368e2015-02-03 23:01:3770}
[email protected]bffc8302014-01-23 20:52:1671
[email protected]94224ba62014-02-04 00:25:2472BrowserPluginManager* ChildFrameCompositingHelper::GetBrowserPluginManager() {
73 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:5874 return nullptr;
[email protected]94224ba62014-02-04 00:25:2475
fsamuel6c1dfeb2014-12-18 19:21:3376 return BrowserPluginManager::Get();
[email protected]94224ba62014-02-04 00:25:2477}
78
79blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
80 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:5881 return nullptr;
[email protected]94224ba62014-02-04 00:25:2482
83 return browser_plugin_->container();
84}
85
86int ChildFrameCompositingHelper::GetInstanceID() {
87 if (!browser_plugin_)
88 return 0;
89
[email protected]2101c4c2014-08-22 00:16:1690 return browser_plugin_->browser_plugin_instance_id();
[email protected]94224ba62014-02-04 00:25:2491}
92
[email protected]bffc8302014-01-23 20:52:1693void ChildFrameCompositingHelper::SendCompositorFrameSwappedACKToBrowser(
94 FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
95 // This function will be removed when BrowserPluginManager is removed and
96 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:2497 if (GetBrowserPluginManager()) {
98 GetBrowserPluginManager()->Send(
lfgfd437a272015-11-24 21:24:5399 new BrowserPluginHostMsg_CompositorFrameSwappedACK(GetInstanceID(),
100 params));
[email protected]e3244ed2014-06-20 20:04:27101 } else if (render_frame_proxy_) {
102 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16103 new FrameHostMsg_CompositorFrameSwappedACK(host_routing_id_, params));
104 }
[email protected]0f21e8582013-01-11 11:06:56105}
106
[email protected]bffc8302014-01-23 20:52:16107void ChildFrameCompositingHelper::SendReclaimCompositorResourcesToBrowser(
108 FrameHostMsg_ReclaimCompositorResources_Params& params) {
109 // This function will be removed when BrowserPluginManager is removed and
110 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:24111 if (GetBrowserPluginManager()) {
112 GetBrowserPluginManager()->Send(
lfgfd437a272015-11-24 21:24:53113 new BrowserPluginHostMsg_ReclaimCompositorResources(GetInstanceID(),
114 params));
[email protected]e3244ed2014-06-20 20:04:27115 } else if (render_frame_proxy_) {
116 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16117 new FrameHostMsg_ReclaimCompositorResources(host_routing_id_, params));
118 }
119}
120
[email protected]bffc8302014-01-23 20:52:16121void ChildFrameCompositingHelper::DidCommitCompositorFrame() {
[email protected]09f67382013-10-09 21:03:45122 if (!resource_collection_.get() || !ack_pending_)
[email protected]f5b4b0f2013-04-02 18:16:28123 return;
[email protected]396fbb72013-01-23 02:33:43124
[email protected]95d31822014-01-03 22:21:55125 FrameHostMsg_CompositorFrameSwappedACK_Params params;
126 params.producing_host_id = last_host_id_;
127 params.producing_route_id = last_route_id_;
128 params.output_surface_id = last_output_surface_id_;
129 resource_collection_->TakeUnusedResourcesForChildCompositor(
130 &params.ack.resources);
[email protected]f5b4b0f2013-04-02 18:16:28131
[email protected]bffc8302014-01-23 20:52:16132 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]f5b4b0f2013-04-02 18:16:28133
134 ack_pending_ = false;
135}
136
lfgfd437a272015-11-24 21:24:53137void ChildFrameCompositingHelper::UpdateWebLayer(blink::WebLayer* layer) {
[email protected]94224ba62014-02-04 00:25:24138 if (GetContainer()) {
lfgfd437a272015-11-24 21:24:53139 GetContainer()->setWebLayer(layer);
[email protected]94224ba62014-02-04 00:25:24140 } else if (frame_) {
lfgfd437a272015-11-24 21:24:53141 frame_->setRemoteWebLayer(layer);
[email protected]bffc8302014-01-23 20:52:16142 }
lfgfd437a272015-11-24 21:24:53143 web_layer_.reset(layer);
[email protected]0f21e8582013-01-11 11:06:56144}
145
[email protected]bffc8302014-01-23 20:52:16146void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28147 const gfx::Size& new_size,
148 float device_scale_factor,
149 cc::Layer* layer) {
150 if (buffer_size_ != new_size) {
151 buffer_size_ = new_size;
152 // The container size is in DIP, so is the layer size.
153 // Buffer size is in physical pixels, so we need to adjust
154 // it by the device scale factor.
danakjddaec912015-09-25 19:38:40155 gfx::Size device_scale_adjusted_size =
156 gfx::ScaleToFlooredSize(buffer_size_, 1.0f / device_scale_factor);
[email protected]f5b4b0f2013-04-02 18:16:28157 layer->SetBounds(device_scale_adjusted_size);
158 }
159}
160
[email protected]bffc8302014-01-23 20:52:16161void ChildFrameCompositingHelper::OnContainerDestroy() {
fsamuel0147b102014-11-10 17:05:01162 // If we have a pending ACK, then ACK now so we don't lose frames in the
163 // future.
164 DidCommitCompositorFrame();
165
lfgfd437a272015-11-24 21:24:53166 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21167
dcheng58867a92014-08-26 02:50:22168 if (resource_collection_.get())
kenrbfc7c02c92015-05-29 22:20:58169 resource_collection_->SetClient(nullptr);
[email protected]b0030b72013-11-15 20:35:53170
[email protected]7873fe4e2013-11-14 18:35:22171 ack_pending_ = false;
kenrbfc7c02c92015-05-29 22:20:58172 resource_collection_ = nullptr;
173 frame_provider_ = nullptr;
[email protected]0d25cb62013-01-21 15:42:21174}
175
[email protected]f49722f2014-01-30 17:54:50176void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53177 scoped_refptr<cc::SolidColorLayer> crashed_layer =
178 cc::SolidColorLayer::Create(cc_blink::WebLayerImpl::LayerSettings());
179 crashed_layer->SetMasksToBounds(true);
180 crashed_layer->SetBackgroundColor(SkColorSetARGBInline(255, 0, 128, 0));
181 blink::WebLayer* layer = new cc_blink::WebLayerImpl(crashed_layer);
182 UpdateWebLayer(layer);
[email protected]f49722f2014-01-30 17:54:50183}
184
[email protected]bffc8302014-01-23 20:52:16185void ChildFrameCompositingHelper::OnCompositorFrameSwapped(
[email protected]f5b4b0f2013-04-02 18:16:28186 scoped_ptr<cc::CompositorFrame> frame,
187 int route_id,
avi1023d012015-12-25 02:39:14188 uint32_t output_surface_id,
[email protected]f1970082014-04-09 04:29:56189 int host_id,
190 base::SharedMemoryHandle handle) {
[email protected]09f67382013-10-09 21:03:45191 cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
kenrbfc7c02c92015-05-29 22:20:58192
[email protected]b0030b72013-11-15 20:35:53193 // Do nothing if we are getting destroyed or have no frame data.
lfgfd437a272015-11-24 21:24:53194 if (!frame_data)
[email protected]f5b4b0f2013-04-02 18:16:28195 return;
196
[email protected]09f67382013-10-09 21:03:45197 DCHECK(!frame_data->render_pass_list.empty());
vmpstra370ef52015-11-18 10:41:28198 cc::RenderPass* root_pass = frame_data->render_pass_list.back().get();
[email protected]09f67382013-10-09 21:03:45199 gfx::Size frame_size = root_pass->output_rect.size();
200
[email protected]317f17d2013-11-09 05:03:48201 if (last_route_id_ != route_id ||
202 last_output_surface_id_ != output_surface_id ||
203 last_host_id_ != host_id) {
204 // Resource ids are scoped by the output surface.
205 // If the originating output surface doesn't match the last one, it
206 // indicates the guest's output surface may have been recreated, in which
207 // case we should recreate the DelegatedRendererLayer, to avoid matching
208 // resources from the old one with resources from the new one which would
209 // have the same id.
kenrbfc7c02c92015-05-29 22:20:58210 frame_provider_ = nullptr;
[email protected]317f17d2013-11-09 05:03:48211
212 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
213 // any resources from the old output surface with the new output surface id.
dcheng58867a92014-08-26 02:50:22214 if (resource_collection_.get()) {
kenrbfc7c02c92015-05-29 22:20:58215 resource_collection_->SetClient(nullptr);
[email protected]b0030b72013-11-15 20:35:53216
217 if (resource_collection_->LoseAllResources())
218 SendReturnedDelegatedResources();
kenrbfc7c02c92015-05-29 22:20:58219 resource_collection_ = nullptr;
[email protected]317f17d2013-11-09 05:03:48220 }
221 last_output_surface_id_ = output_surface_id;
222 last_route_id_ = route_id;
223 last_host_id_ = host_id;
224 }
dcheng58867a92014-08-26 02:50:22225 if (!resource_collection_.get()) {
[email protected]09f67382013-10-09 21:03:45226 resource_collection_ = new cc::DelegatedFrameResourceCollection;
[email protected]b0030b72013-11-15 20:35:53227 resource_collection_->SetClient(this);
[email protected]09f67382013-10-09 21:03:45228 }
229 if (!frame_provider_.get() || frame_provider_->frame_size() != frame_size) {
230 frame_provider_ = new cc::DelegatedFrameProvider(
dcheng07945f632015-12-26 07:59:32231 resource_collection_.get(), std::move(frame->delegated_frame_data));
lfgfd437a272015-11-24 21:24:53232 scoped_refptr<cc::DelegatedRendererLayer> delegated_layer =
233 cc::DelegatedRendererLayer::Create(
234 cc_blink::WebLayerImpl::LayerSettings(), frame_provider_.get());
235 delegated_layer->SetIsDrawable(true);
fsamuele9741a32014-09-09 05:34:07236 buffer_size_ = gfx::Size();
lfgfd437a272015-11-24 21:24:53237 blink::WebLayer* layer = new cc_blink::WebLayerImpl(delegated_layer);
238 UpdateWebLayer(layer);
[email protected]09f67382013-10-09 21:03:45239 } else {
dcheng07945f632015-12-26 07:59:32240 frame_provider_->SetFrameData(std::move(frame->delegated_frame_data));
[email protected]09f67382013-10-09 21:03:45241 }
242
[email protected]6d3a46e2013-11-25 23:08:53243 CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28244 frame_data->render_pass_list.back()->output_rect.size(),
245 frame->metadata.device_scale_factor,
lfgfd437a272015-11-24 21:24:53246 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
[email protected]f5b4b0f2013-04-02 18:16:28247
[email protected]f5b4b0f2013-04-02 18:16:28248 ack_pending_ = true;
249}
250
kenrbfc7c02c92015-05-29 22:20:58251// static
252void ChildFrameCompositingHelper::SatisfyCallback(
jbauman38c178eaa2015-06-04 04:24:54253 scoped_refptr<ThreadSafeSender> sender,
254 int host_routing_id,
kenrbfc7c02c92015-05-29 22:20:58255 cc::SurfaceSequence sequence) {
jbauman38c178eaa2015-06-04 04:24:54256 // This may be called on either the main or impl thread.
257 sender->Send(new FrameHostMsg_SatisfySequence(host_routing_id, sequence));
kenrbfc7c02c92015-05-29 22:20:58258}
259
260// static
wjmaclean1e720d2f2015-07-14 16:09:52261void ChildFrameCompositingHelper::SatisfyCallbackBrowserPlugin(
262 scoped_refptr<ThreadSafeSender> sender,
263 int host_routing_id,
264 int browser_plugin_instance_id,
265 cc::SurfaceSequence sequence) {
266 sender->Send(new BrowserPluginHostMsg_SatisfySequence(
267 host_routing_id, browser_plugin_instance_id, sequence));
268}
269
270// static
kenrbfc7c02c92015-05-29 22:20:58271void ChildFrameCompositingHelper::RequireCallback(
jbauman38c178eaa2015-06-04 04:24:54272 scoped_refptr<ThreadSafeSender> sender,
273 int host_routing_id,
kenrbfc7c02c92015-05-29 22:20:58274 cc::SurfaceId id,
275 cc::SurfaceSequence sequence) {
jbauman38c178eaa2015-06-04 04:24:54276 // This may be called on either the main or impl thread.
277 sender->Send(new FrameHostMsg_RequireSequence(host_routing_id, id, sequence));
kenrbfc7c02c92015-05-29 22:20:58278}
279
wjmaclean53032adf2015-06-15 16:49:22280void ChildFrameCompositingHelper::RequireCallbackBrowserPlugin(
281 scoped_refptr<ThreadSafeSender> sender,
282 int host_routing_id,
283 int browser_plugin_instance_id,
284 cc::SurfaceId id,
285 cc::SurfaceSequence sequence) {
286 // This may be called on either the main or impl thread.
287 sender->Send(new BrowserPluginHostMsg_RequireSequence(
288 host_routing_id, browser_plugin_instance_id, id, sequence));
289}
290
kenrbfc7c02c92015-05-29 22:20:58291void ChildFrameCompositingHelper::OnSetSurface(
292 const cc::SurfaceId& surface_id,
293 const gfx::Size& frame_size,
294 float scale_factor,
295 const cc::SurfaceSequence& sequence) {
lfgfd437a272015-11-24 21:24:53296 scoped_refptr<ThreadSafeSender> sender(
297 RenderThreadImpl::current()->thread_safe_sender());
298 cc::SurfaceLayer::SatisfyCallback satisfy_callback =
299 render_frame_proxy_
300 ? base::Bind(&ChildFrameCompositingHelper::SatisfyCallback, sender,
301 host_routing_id_)
302 : base::Bind(
303 &ChildFrameCompositingHelper::SatisfyCallbackBrowserPlugin,
304 sender, host_routing_id_,
305 browser_plugin_->browser_plugin_instance_id());
306 cc::SurfaceLayer::RequireCallback require_callback =
307 render_frame_proxy_
308 ? base::Bind(&ChildFrameCompositingHelper::RequireCallback, sender,
309 host_routing_id_)
310 : base::Bind(
311 &ChildFrameCompositingHelper::RequireCallbackBrowserPlugin,
312 sender, host_routing_id_,
313 browser_plugin_->browser_plugin_instance_id());
314 scoped_refptr<cc::SurfaceLayer> surface_layer =
315 cc::SurfaceLayer::Create(cc_blink::WebLayerImpl::LayerSettings(),
316 satisfy_callback, require_callback);
317 surface_layer->SetSurfaceId(surface_id, scale_factor, frame_size);
318 blink::WebLayer* layer = new cc_blink::WebLayerImpl(surface_layer);
319 UpdateWebLayer(layer);
kenrbfc7c02c92015-05-29 22:20:58320
kenrbfc7c02c92015-05-29 22:20:58321 UpdateVisibility(true);
kenrbfc7c02c92015-05-29 22:20:58322
323 // The RWHV creates a destruction dependency on the surface that needs to be
wjmaclean53032adf2015-06-15 16:49:22324 // satisfied. Note: render_frame_proxy_ is null in the case our client is a
325 // BrowserPlugin; in this case the BrowserPlugin sends its own SatisfySequence
326 // message.
327 if (render_frame_proxy_) {
328 render_frame_proxy_->Send(
329 new FrameHostMsg_SatisfySequence(host_routing_id_, sequence));
330 } else if (browser_plugin_.get()) {
331 browser_plugin_->SendSatisfySequence(sequence);
332 }
kenrbfc7c02c92015-05-29 22:20:58333
lfgfd437a272015-11-24 21:24:53334 CheckSizeAndAdjustLayerProperties(
335 frame_size, scale_factor,
336 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
kenrbfc7c02c92015-05-29 22:20:58337}
338
[email protected]bffc8302014-01-23 20:52:16339void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
lfgfd437a272015-11-24 21:24:53340 if (web_layer_)
341 web_layer_->setDrawsContent(visible);
[email protected]69b79122013-02-14 19:16:45342}
343
[email protected]bffc8302014-01-23 20:52:16344void ChildFrameCompositingHelper::UnusedResourcesAreAvailable() {
[email protected]b0030b72013-11-15 20:35:53345 if (ack_pending_)
346 return;
347
348 SendReturnedDelegatedResources();
349}
350
[email protected]bffc8302014-01-23 20:52:16351void ChildFrameCompositingHelper::SendReturnedDelegatedResources() {
352 FrameHostMsg_ReclaimCompositorResources_Params params;
dcheng58867a92014-08-26 02:50:22353 if (resource_collection_.get())
[email protected]bffc8302014-01-23 20:52:16354 resource_collection_->TakeUnusedResourcesForChildCompositor(
355 &params.ack.resources);
356 DCHECK(!params.ack.resources.empty());
[email protected]b0030b72013-11-15 20:35:53357
[email protected]bffc8302014-01-23 20:52:16358 params.route_id = last_route_id_;
359 params.output_surface_id = last_output_surface_id_;
360 params.renderer_host_id = last_host_id_;
361 SendReclaimCompositorResourcesToBrowser(params);
[email protected]b0030b72013-11-15 20:35:53362}
363
[email protected]0f21e8582013-01-11 11:06:56364} // namespace content