blob: d72b3e905a087570e34304ca829656d61c35d4f3 [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
[email protected]38564622014-08-19 02:47:187#include "cc/blink/web_layer_impl.h"
[email protected]09f67382013-10-09 21:03:458#include "cc/layers/delegated_frame_provider.h"
9#include "cc/layers/delegated_frame_resource_collection.h"
[email protected]f5b4b0f2013-04-02 18:16:2810#include "cc/layers/delegated_renderer_layer.h"
[email protected]cc3cfaa2013-03-18 09:05:5211#include "cc/layers/solid_color_layer.h"
kenrbfc7c02c92015-05-29 22:20:5812#include "cc/layers/surface_layer.h"
[email protected]7f0d825f2013-03-18 07:24:3013#include "cc/output/context_provider.h"
[email protected]73405fb2013-12-11 04:59:3714#include "cc/output/copy_output_request.h"
15#include "cc/output/copy_output_result.h"
[email protected]9260757f2013-09-17 01:24:1616#include "cc/resources/single_release_callback.h"
jbauman38c178eaa2015-06-04 04:24:5417#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4218#include "content/common/browser_plugin/browser_plugin_messages.h"
[email protected]95d31822014-01-03 22:21:5519#include "content/common/frame_messages.h"
[email protected]a45c46e2013-03-07 01:04:4620#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]94224ba62014-02-04 00:25:2421#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2122#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1623#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2724#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5625#include "content/renderer/render_thread_impl.h"
[email protected]73405fb2013-12-11 04:59:3726#include "skia/ext/image_operations.h"
[email protected]bffc8302014-01-23 20:52:1627#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]2255a9332013-06-17 05:12:3128#include "third_party/WebKit/public/web/WebPluginContainer.h"
[email protected]7f0d825f2013-03-18 07:24:3029#include "third_party/khronos/GLES2/gl2.h"
tfarinaebe974f02015-01-03 04:25:3230#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3731#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5632
33namespace content {
34
[email protected]bffc8302014-01-23 20:52:1635ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3336ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:2437 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:1638 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:5839 browser_plugin, nullptr, nullptr,
40 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:1641}
42
43ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:3344ChildFrameCompositingHelper::CreateForRenderFrameProxy(
45 RenderFrameProxy* render_frame_proxy) {
46 return new ChildFrameCompositingHelper(base::WeakPtr<BrowserPlugin>(),
47 render_frame_proxy->web_frame(),
48 render_frame_proxy,
49 render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:1650}
51
52ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:2453 const base::WeakPtr<BrowserPlugin>& browser_plugin,
[email protected]bffc8302014-01-23 20:52:1654 blink::WebFrame* frame,
[email protected]e3244ed2014-06-20 20:04:2755 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:5656 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:2457 : host_routing_id_(host_routing_id),
[email protected]f5b4b0f2013-04-02 18:16:2858 last_route_id_(0),
[email protected]53b4cc12013-07-18 23:02:3059 last_output_surface_id_(0),
[email protected]f5b4b0f2013-04-02 18:16:2860 last_host_id_(0),
[email protected]0d25cb62013-01-21 15:42:2161 ack_pending_(true),
[email protected]6d3a46e2013-11-25 23:08:5362 opaque_(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),
jbauman38c178eaa2015-06-04 04:24:5465 frame_(frame) {
kenrbfc7c02c92015-05-29 22:20:5866}
[email protected]bffc8302014-01-23 20:52:1667
lfga7d368e2015-02-03 23:01:3768ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
69 if (resource_collection_.get())
kenrbfc7c02c92015-05-29 22:20:5870 resource_collection_->SetClient(nullptr);
lfga7d368e2015-02-03 23:01:3771}
[email protected]bffc8302014-01-23 20:52:1672
[email protected]94224ba62014-02-04 00:25:2473BrowserPluginManager* ChildFrameCompositingHelper::GetBrowserPluginManager() {
74 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:5875 return nullptr;
[email protected]94224ba62014-02-04 00:25:2476
fsamuel6c1dfeb2014-12-18 19:21:3377 return BrowserPluginManager::Get();
[email protected]94224ba62014-02-04 00:25:2478}
79
80blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
81 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:5882 return nullptr;
[email protected]94224ba62014-02-04 00:25:2483
84 return browser_plugin_->container();
85}
86
87int ChildFrameCompositingHelper::GetInstanceID() {
88 if (!browser_plugin_)
89 return 0;
90
[email protected]2101c4c2014-08-22 00:16:1691 return browser_plugin_->browser_plugin_instance_id();
[email protected]94224ba62014-02-04 00:25:2492}
93
[email protected]bffc8302014-01-23 20:52:1694void ChildFrameCompositingHelper::SendCompositorFrameSwappedACKToBrowser(
95 FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
96 // This function will be removed when BrowserPluginManager is removed and
97 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:2498 if (GetBrowserPluginManager()) {
99 GetBrowserPluginManager()->Send(
[email protected]bffc8302014-01-23 20:52:16100 new BrowserPluginHostMsg_CompositorFrameSwappedACK(
fsamuel2e9413d2015-02-25 01:25:44101 GetInstanceID(), params));
[email protected]e3244ed2014-06-20 20:04:27102 } else if (render_frame_proxy_) {
103 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16104 new FrameHostMsg_CompositorFrameSwappedACK(host_routing_id_, params));
105 }
[email protected]0f21e8582013-01-11 11:06:56106}
107
[email protected]bffc8302014-01-23 20:52:16108void ChildFrameCompositingHelper::SendReclaimCompositorResourcesToBrowser(
109 FrameHostMsg_ReclaimCompositorResources_Params& params) {
110 // This function will be removed when BrowserPluginManager is removed and
111 // BrowserPlugin is modified to use a RenderFrame.
[email protected]94224ba62014-02-04 00:25:24112 if (GetBrowserPluginManager()) {
113 GetBrowserPluginManager()->Send(
[email protected]bffc8302014-01-23 20:52:16114 new BrowserPluginHostMsg_ReclaimCompositorResources(
fsamuel2e9413d2015-02-25 01:25:44115 GetInstanceID(), params));
[email protected]e3244ed2014-06-20 20:04:27116 } else if (render_frame_proxy_) {
117 render_frame_proxy_->Send(
[email protected]bffc8302014-01-23 20:52:16118 new FrameHostMsg_ReclaimCompositorResources(host_routing_id_, params));
119 }
120}
121
[email protected]bffc8302014-01-23 20:52:16122void ChildFrameCompositingHelper::DidCommitCompositorFrame() {
[email protected]09f67382013-10-09 21:03:45123 if (!resource_collection_.get() || !ack_pending_)
[email protected]f5b4b0f2013-04-02 18:16:28124 return;
[email protected]396fbb72013-01-23 02:33:43125
[email protected]95d31822014-01-03 22:21:55126 FrameHostMsg_CompositorFrameSwappedACK_Params params;
127 params.producing_host_id = last_host_id_;
128 params.producing_route_id = last_route_id_;
129 params.output_surface_id = last_output_surface_id_;
130 resource_collection_->TakeUnusedResourcesForChildCompositor(
131 &params.ack.resources);
[email protected]f5b4b0f2013-04-02 18:16:28132
[email protected]bffc8302014-01-23 20:52:16133 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]f5b4b0f2013-04-02 18:16:28134
135 ack_pending_ = false;
136}
137
[email protected]bffc8302014-01-23 20:52:16138void ChildFrameCompositingHelper::EnableCompositing(bool enable) {
[email protected]fc72bb12013-06-02 21:13:46139 if (enable && !background_layer_.get()) {
loysoa6edaaff2015-05-25 03:26:44140 background_layer_ =
141 cc::SolidColorLayer::Create(cc_blink::WebLayerImpl::LayerSettings());
[email protected]7aba6662013-03-12 10:17:34142 background_layer_->SetMasksToBounds(true);
143 background_layer_->SetBackgroundColor(
[email protected]396fbb72013-01-23 02:33:43144 SkColorSetARGBInline(255, 255, 255, 255));
[email protected]38564622014-08-19 02:47:18145 web_layer_.reset(new cc_blink::WebLayerImpl(background_layer_));
[email protected]0f21e8582013-01-11 11:06:56146 }
147
[email protected]94224ba62014-02-04 00:25:24148 if (GetContainer()) {
kenrbfc7c02c92015-05-29 22:20:58149 GetContainer()->setWebLayer(enable ? web_layer_.get() : nullptr);
[email protected]94224ba62014-02-04 00:25:24150 } else if (frame_) {
kenrbfc7c02c92015-05-29 22:20:58151 frame_->setRemoteWebLayer(enable ? web_layer_.get() : nullptr);
[email protected]bffc8302014-01-23 20:52:16152 }
[email protected]0f21e8582013-01-11 11:06:56153}
154
[email protected]bffc8302014-01-23 20:52:16155void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28156 const gfx::Size& new_size,
157 float device_scale_factor,
158 cc::Layer* layer) {
159 if (buffer_size_ != new_size) {
160 buffer_size_ = new_size;
161 // The container size is in DIP, so is the layer size.
162 // Buffer size is in physical pixels, so we need to adjust
163 // it by the device scale factor.
164 gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize(
165 gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor));
166 layer->SetBounds(device_scale_adjusted_size);
167 }
[email protected]6d3a46e2013-11-25 23:08:53168
169 // Manually manage background layer for transparent webview.
170 if (!opaque_)
171 background_layer_->SetIsDrawable(false);
[email protected]f5b4b0f2013-04-02 18:16:28172}
173
[email protected]bffc8302014-01-23 20:52:16174void ChildFrameCompositingHelper::OnContainerDestroy() {
fsamuel0147b102014-11-10 17:05:01175 // If we have a pending ACK, then ACK now so we don't lose frames in the
176 // future.
177 DidCommitCompositorFrame();
178
[email protected]94224ba62014-02-04 00:25:24179 if (GetContainer())
kenrbfc7c02c92015-05-29 22:20:58180 GetContainer()->setWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21181
dcheng58867a92014-08-26 02:50:22182 if (resource_collection_.get())
kenrbfc7c02c92015-05-29 22:20:58183 resource_collection_->SetClient(nullptr);
[email protected]b0030b72013-11-15 20:35:53184
[email protected]7873fe4e2013-11-14 18:35:22185 ack_pending_ = false;
kenrbfc7c02c92015-05-29 22:20:58186 resource_collection_ = nullptr;
187 frame_provider_ = nullptr;
188 delegated_layer_ = nullptr;
189 background_layer_ = nullptr;
190 surface_layer_ = nullptr;
[email protected]0d25cb62013-01-21 15:42:21191 web_layer_.reset();
192}
193
[email protected]f49722f2014-01-30 17:54:50194void ChildFrameCompositingHelper::ChildFrameGone() {
195 background_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 128, 0));
196 background_layer_->RemoveAllChildren();
197 background_layer_->SetIsDrawable(true);
198 background_layer_->SetContentsOpaque(true);
199}
200
[email protected]bffc8302014-01-23 20:52:16201void ChildFrameCompositingHelper::OnCompositorFrameSwapped(
[email protected]f5b4b0f2013-04-02 18:16:28202 scoped_ptr<cc::CompositorFrame> frame,
203 int route_id,
[email protected]53b4cc12013-07-18 23:02:30204 uint32 output_surface_id,
[email protected]f1970082014-04-09 04:29:56205 int host_id,
206 base::SharedMemoryHandle handle) {
[email protected]09f67382013-10-09 21:03:45207 cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
kenrbfc7c02c92015-05-29 22:20:58208
209 // Surface IDs and compositor frames should never be received
210 // interchangeably.
211 DCHECK(!surface_layer_.get());
212
[email protected]b0030b72013-11-15 20:35:53213 // Do nothing if we are getting destroyed or have no frame data.
dcheng58867a92014-08-26 02:50:22214 if (!frame_data || !background_layer_.get())
[email protected]f5b4b0f2013-04-02 18:16:28215 return;
216
[email protected]09f67382013-10-09 21:03:45217 DCHECK(!frame_data->render_pass_list.empty());
218 cc::RenderPass* root_pass = frame_data->render_pass_list.back();
219 gfx::Size frame_size = root_pass->output_rect.size();
220
[email protected]317f17d2013-11-09 05:03:48221 if (last_route_id_ != route_id ||
222 last_output_surface_id_ != output_surface_id ||
223 last_host_id_ != host_id) {
224 // Resource ids are scoped by the output surface.
225 // If the originating output surface doesn't match the last one, it
226 // indicates the guest's output surface may have been recreated, in which
227 // case we should recreate the DelegatedRendererLayer, to avoid matching
228 // resources from the old one with resources from the new one which would
229 // have the same id.
kenrbfc7c02c92015-05-29 22:20:58230 frame_provider_ = nullptr;
[email protected]317f17d2013-11-09 05:03:48231
232 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
233 // any resources from the old output surface with the new output surface id.
dcheng58867a92014-08-26 02:50:22234 if (resource_collection_.get()) {
kenrbfc7c02c92015-05-29 22:20:58235 resource_collection_->SetClient(nullptr);
[email protected]b0030b72013-11-15 20:35:53236
237 if (resource_collection_->LoseAllResources())
238 SendReturnedDelegatedResources();
kenrbfc7c02c92015-05-29 22:20:58239 resource_collection_ = nullptr;
[email protected]317f17d2013-11-09 05:03:48240 }
241 last_output_surface_id_ = output_surface_id;
242 last_route_id_ = route_id;
243 last_host_id_ = host_id;
244 }
dcheng58867a92014-08-26 02:50:22245 if (!resource_collection_.get()) {
[email protected]09f67382013-10-09 21:03:45246 resource_collection_ = new cc::DelegatedFrameResourceCollection;
[email protected]b0030b72013-11-15 20:35:53247 resource_collection_->SetClient(this);
[email protected]09f67382013-10-09 21:03:45248 }
249 if (!frame_provider_.get() || frame_provider_->frame_size() != frame_size) {
250 frame_provider_ = new cc::DelegatedFrameProvider(
251 resource_collection_.get(), frame->delegated_frame_data.Pass());
252 if (delegated_layer_.get())
253 delegated_layer_->RemoveFromParent();
loysoa6edaaff2015-05-25 03:26:44254 delegated_layer_ = cc::DelegatedRendererLayer::Create(
255 cc_blink::WebLayerImpl::LayerSettings(), frame_provider_.get());
[email protected]09f67382013-10-09 21:03:45256 delegated_layer_->SetIsDrawable(true);
fsamuele9741a32014-09-09 05:34:07257 buffer_size_ = gfx::Size();
[email protected]6d3a46e2013-11-25 23:08:53258 SetContentsOpaque(opaque_);
[email protected]09f67382013-10-09 21:03:45259 background_layer_->AddChild(delegated_layer_);
260 } else {
261 frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
262 }
263
[email protected]6d3a46e2013-11-25 23:08:53264 CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28265 frame_data->render_pass_list.back()->output_rect.size(),
266 frame->metadata.device_scale_factor,
267 delegated_layer_.get());
268
[email protected]f5b4b0f2013-04-02 18:16:28269 ack_pending_ = true;
270}
271
kenrbfc7c02c92015-05-29 22:20:58272// static
273void ChildFrameCompositingHelper::SatisfyCallback(
jbauman38c178eaa2015-06-04 04:24:54274 scoped_refptr<ThreadSafeSender> sender,
275 int host_routing_id,
kenrbfc7c02c92015-05-29 22:20:58276 cc::SurfaceSequence sequence) {
jbauman38c178eaa2015-06-04 04:24:54277 // This may be called on either the main or impl thread.
278 sender->Send(new FrameHostMsg_SatisfySequence(host_routing_id, sequence));
kenrbfc7c02c92015-05-29 22:20:58279}
280
281// static
282void ChildFrameCompositingHelper::RequireCallback(
jbauman38c178eaa2015-06-04 04:24:54283 scoped_refptr<ThreadSafeSender> sender,
284 int host_routing_id,
kenrbfc7c02c92015-05-29 22:20:58285 cc::SurfaceId id,
286 cc::SurfaceSequence sequence) {
jbauman38c178eaa2015-06-04 04:24:54287 // This may be called on either the main or impl thread.
288 sender->Send(new FrameHostMsg_RequireSequence(host_routing_id, id, sequence));
kenrbfc7c02c92015-05-29 22:20:58289}
290
291void ChildFrameCompositingHelper::OnSetSurface(
292 const cc::SurfaceId& surface_id,
293 const gfx::Size& frame_size,
294 float scale_factor,
295 const cc::SurfaceSequence& sequence) {
296 // Surface IDs and compositor frames should never be received
297 // interchangably.
298 DCHECK(!delegated_layer_.get());
299
300 // Do nothing if we are getting destroyed.
301 if (!background_layer_.get())
302 return;
303
304 if (!surface_layer_.get()) {
jbauman38c178eaa2015-06-04 04:24:54305 scoped_refptr<ThreadSafeSender> sender(
306 RenderThreadImpl::current()->thread_safe_sender());
kenrbfc7c02c92015-05-29 22:20:58307 cc::SurfaceLayer::SatisfyCallback satisfy_callback =
jbauman38c178eaa2015-06-04 04:24:54308 base::Bind(&ChildFrameCompositingHelper::SatisfyCallback, sender,
309 host_routing_id_);
kenrbfc7c02c92015-05-29 22:20:58310 cc::SurfaceLayer::RequireCallback require_callback =
jbauman38c178eaa2015-06-04 04:24:54311 base::Bind(&ChildFrameCompositingHelper::RequireCallback, sender,
312 host_routing_id_);
kenrbfc7c02c92015-05-29 22:20:58313 surface_layer_ =
314 cc::SurfaceLayer::Create(cc_blink::WebLayerImpl::LayerSettings(),
315 satisfy_callback, require_callback);
316 }
317 surface_layer_->SetSurfaceId(surface_id, scale_factor, frame_size);
318 UpdateVisibility(true);
319 SetContentsOpaque(opaque_);
320 background_layer_->AddChild(surface_layer_);
321
322 // The RWHV creates a destruction dependency on the surface that needs to be
323 // satisfied.
324 render_frame_proxy_->Send(
325 new FrameHostMsg_SatisfySequence(host_routing_id_, sequence));
326
327 CheckSizeAndAdjustLayerProperties(frame_size, scale_factor,
328 surface_layer_.get());
329}
330
[email protected]bffc8302014-01-23 20:52:16331void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
[email protected]fc72bb12013-06-02 21:13:46332 if (delegated_layer_.get())
[email protected]f5b4b0f2013-04-02 18:16:28333 delegated_layer_->SetIsDrawable(visible);
kenrbfc7c02c92015-05-29 22:20:58334 if (surface_layer_.get())
335 surface_layer_->SetIsDrawable(visible);
[email protected]69b79122013-02-14 19:16:45336}
337
[email protected]bffc8302014-01-23 20:52:16338void ChildFrameCompositingHelper::UnusedResourcesAreAvailable() {
[email protected]b0030b72013-11-15 20:35:53339 if (ack_pending_)
340 return;
341
342 SendReturnedDelegatedResources();
343}
344
[email protected]bffc8302014-01-23 20:52:16345void ChildFrameCompositingHelper::SendReturnedDelegatedResources() {
346 FrameHostMsg_ReclaimCompositorResources_Params params;
dcheng58867a92014-08-26 02:50:22347 if (resource_collection_.get())
[email protected]bffc8302014-01-23 20:52:16348 resource_collection_->TakeUnusedResourcesForChildCompositor(
349 &params.ack.resources);
350 DCHECK(!params.ack.resources.empty());
[email protected]b0030b72013-11-15 20:35:53351
[email protected]bffc8302014-01-23 20:52:16352 params.route_id = last_route_id_;
353 params.output_surface_id = last_output_surface_id_;
354 params.renderer_host_id = last_host_id_;
355 SendReclaimCompositorResourcesToBrowser(params);
[email protected]b0030b72013-11-15 20:35:53356}
357
[email protected]bffc8302014-01-23 20:52:16358void ChildFrameCompositingHelper::SetContentsOpaque(bool opaque) {
[email protected]6d3a46e2013-11-25 23:08:53359 opaque_ = opaque;
[email protected]6d3a46e2013-11-25 23:08:53360 if (delegated_layer_.get())
361 delegated_layer_->SetContentsOpaque(opaque_);
kenrbfc7c02c92015-05-29 22:20:58362 if (surface_layer_.get())
363 surface_layer_->SetContentsOpaque(opaque_);
[email protected]6d3a46e2013-11-25 23:08:53364}
365
[email protected]0f21e8582013-01-11 11:06:56366} // namespace content