blob: 4edf6acedae8149e0aed4ee06d7a4a3e3e03ec3f [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
kylecharc1a739a2017-07-27 23:34:599#include "base/command_line.h"
kylechar5e037002018-01-05 15:30:1910#include "build/build_config.h"
[email protected]38564622014-08-19 02:47:1811#include "cc/blink/web_layer_impl.h"
lfgcccffbe2016-03-10 00:05:4612#include "cc/layers/picture_image_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"
vmpstr55c7657ca2017-04-29 00:46:4815#include "cc/paint/paint_image.h"
Vladimir Levin988d0242017-08-08 00:02:5716#include "cc/paint/paint_image_builder.h"
danakjf20f4502017-09-26 17:13:3117#include "components/viz/common/frame_sinks/copy_output_request.h"
18#include "components/viz/common/frame_sinks/copy_output_result.h"
Xu Xing32549162017-07-17 22:25:4319#include "components/viz/common/gpu/context_provider.h"
danakjf20f4502017-09-26 17:13:3120#include "components/viz/common/resources/single_release_callback.h"
Fady Samueldbd4b022017-07-14 02:06:4821#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
kylecharc1a739a2017-07-27 23:34:5922#include "components/viz/common/surfaces/stub_surface_reference_factory.h"
23#include "components/viz/common/switches.h"
jbauman38c178eaa2015-06-04 04:24:5424#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4225#include "content/common/browser_plugin/browser_plugin_messages.h"
oshima9000e422016-01-27 03:05:3626#include "content/common/content_switches_internal.h"
[email protected]95d31822014-01-03 22:21:5527#include "content/common/frame_messages.h"
lfgcccffbe2016-03-10 00:05:4628#include "content/public/common/content_client.h"
29#include "content/public/renderer/content_renderer_client.h"
[email protected]94224ba62014-02-04 00:25:2430#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2131#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1632#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2733#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5634#include "content/renderer/render_thread_impl.h"
sadrul85cc5d82016-12-20 03:37:4135#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
[email protected]73405fb2013-12-11 04:59:3736#include "skia/ext/image_operations.h"
[email protected]2255a9332013-06-17 05:12:3137#include "third_party/WebKit/public/web/WebPluginContainer.h"
dcheng5cf543012016-11-24 17:13:3738#include "third_party/WebKit/public/web/WebRemoteFrame.h"
[email protected]7f0d825f2013-03-18 07:24:3039#include "third_party/khronos/GLES2/gl2.h"
lfgcccffbe2016-03-10 00:05:4640#include "third_party/skia/include/core/SkBitmap.h"
41#include "third_party/skia/include/core/SkImage.h"
42#include "ui/gfx/geometry/point_f.h"
tfarinaebe974f02015-01-03 04:25:3243#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3744#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5645
46namespace content {
47
samans72b2a282016-12-17 02:44:1548namespace {
49
kylechar5e037002018-01-05 15:30:1950bool AreSurfaceReferencesEnabled() {
51#if defined(OS_ANDROID)
52 return base::CommandLine::ForCurrentProcess()->HasSwitch(
53 switches::kEnableSurfaceReferences);
54#else
55 // Surface references are always enabled for non-Android platforms.
56 return true;
57#endif
58}
59
samans72b2a282016-12-17 02:44:1560class IframeSurfaceReferenceFactory
Fady Samueldbd4b022017-07-14 02:06:4861 : public viz::SequenceSurfaceReferenceFactory {
samans72b2a282016-12-17 02:44:1562 public:
63 IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
64 int routing_id)
65 : sender_(std::move(sender)), routing_id_(routing_id) {}
66
Fady Samueldbd4b022017-07-14 02:06:4867 void AddPendingSequence(const viz::SurfaceSequence& sequence) {
kenrb6ef29da2017-06-09 22:16:2168 ReleasePendingSequenceIfNecessary();
69 pending_sequence_ = sequence;
70 }
71
samans72b2a282016-12-17 02:44:1572 private:
kenrb6ef29da2017-06-09 22:16:2173 ~IframeSurfaceReferenceFactory() override {
74 ReleasePendingSequenceIfNecessary();
75 }
76
77 void ReleasePendingSequenceIfNecessary() const {
78 if (pending_sequence_.is_valid()) {
79 sender_->Send(
80 new FrameHostMsg_SatisfySequence(routing_id_, pending_sequence_));
Fady Samueldbd4b022017-07-14 02:06:4881 pending_sequence_ = viz::SurfaceSequence();
kenrb6ef29da2017-06-09 22:16:2182 }
83 }
samans72b2a282016-12-17 02:44:1584
85 // cc::SequenceSurfaceReferenceFactory implementation:
Fady Samueld5c26182017-07-12 02:43:3386 void RequireSequence(const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:4887 const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:1588 sender_->Send(
89 new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:2190 // If there is a temporary reference that was waiting on a new one to be
91 // created, it is now safe to release it.
92 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:1593 }
94
Fady Samueldbd4b022017-07-14 02:06:4895 void SatisfySequence(const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:1596 sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence));
97 }
98
99 const scoped_refptr<ThreadSafeSender> sender_;
Fady Samueldbd4b022017-07-14 02:06:48100 mutable viz::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:15101 const int routing_id_;
102
103 DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory);
104};
105
106class BrowserPluginSurfaceReferenceFactory
Fady Samueldbd4b022017-07-14 02:06:48107 : public viz::SequenceSurfaceReferenceFactory {
samans72b2a282016-12-17 02:44:15108 public:
109 BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
110 int routing_id,
111 int browser_plugin_instance_id)
112 : sender_(std::move(sender)),
113 routing_id_(routing_id),
114 browser_plugin_instance_id_(browser_plugin_instance_id) {}
115
Fady Samueldbd4b022017-07-14 02:06:48116 void AddPendingSequence(const viz::SurfaceSequence& sequence) {
kenrb6ef29da2017-06-09 22:16:21117 ReleasePendingSequenceIfNecessary();
118 pending_sequence_ = sequence;
119 }
120
samans72b2a282016-12-17 02:44:15121 private:
kenrb6ef29da2017-06-09 22:16:21122 ~BrowserPluginSurfaceReferenceFactory() override {
123 ReleasePendingSequenceIfNecessary();
124 }
125
126 void ReleasePendingSequenceIfNecessary() const {
127 if (pending_sequence_.is_valid()) {
128 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
129 routing_id_, browser_plugin_instance_id_, pending_sequence_));
Fady Samueldbd4b022017-07-14 02:06:48130 pending_sequence_ = viz::SurfaceSequence();
kenrb6ef29da2017-06-09 22:16:21131 }
132 }
samans72b2a282016-12-17 02:44:15133
134 // cc::SequenceSurfaceRefrenceFactory implementation:
Fady Samueldbd4b022017-07-14 02:06:48135 void SatisfySequence(const viz::SurfaceSequence& seq) const override {
samans72b2a282016-12-17 02:44:15136 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
137 routing_id_, browser_plugin_instance_id_, seq));
138 }
139
Fady Samueld5c26182017-07-12 02:43:33140 void RequireSequence(const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:48141 const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:15142 sender_->Send(new BrowserPluginHostMsg_RequireSequence(
143 routing_id_, browser_plugin_instance_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:21144 // If there is a temporary reference that was waiting on a new one to be
145 // created, it is now safe to release it.
146 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:15147 }
148
149 const scoped_refptr<ThreadSafeSender> sender_;
Fady Samueldbd4b022017-07-14 02:06:48150 mutable viz::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:15151 const int routing_id_;
152 const int browser_plugin_instance_id_;
153
154 DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory);
155};
156
157} // namespace
158
[email protected]bffc8302014-01-23 20:52:16159ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33160ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:24161 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:16162 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:58163 browser_plugin, nullptr, nullptr,
164 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:16165}
166
167ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33168ChildFrameCompositingHelper::CreateForRenderFrameProxy(
169 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:53170 return new ChildFrameCompositingHelper(
171 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
172 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:16173}
174
175ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:24176 const base::WeakPtr<BrowserPlugin>& browser_plugin,
dcheng5cf543012016-11-24 17:13:37177 blink::WebRemoteFrame* frame,
[email protected]e3244ed2014-06-20 20:04:27178 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:56179 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:24180 : host_routing_id_(host_routing_id),
[email protected]94224ba62014-02-04 00:25:24181 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:27182 render_frame_proxy_(render_frame_proxy),
kylechar5e037002018-01-05 15:30:19183 frame_(frame),
184 enable_surface_references_(AreSurfaceReferencesEnabled()) {
185 // In some tests there is no RenderThreadImpl instance.
186 if (enable_surface_references_ || !RenderThreadImpl::current()) {
kylecharc1a739a2017-07-27 23:34:59187 surface_reference_factory_ = new viz::StubSurfaceReferenceFactory();
samans72b2a282016-12-17 02:44:15188 } else {
Fady Samuelea0d99e2017-09-28 02:21:07189 scoped_refptr<ThreadSafeSender> sender(
190 RenderThreadImpl::current()->thread_safe_sender());
191 if (render_frame_proxy_) {
192 surface_reference_factory_ =
193 new IframeSurfaceReferenceFactory(sender, host_routing_id_);
194 } else {
195 surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory(
196 sender, host_routing_id_,
197 browser_plugin_->browser_plugin_instance_id());
198 }
samans72b2a282016-12-17 02:44:15199 }
200}
[email protected]bffc8302014-01-23 20:52:16201
lfga7d368e2015-02-03 23:01:37202ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
lfga7d368e2015-02-03 23:01:37203}
[email protected]bffc8302014-01-23 20:52:16204
[email protected]94224ba62014-02-04 00:25:24205blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
206 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:58207 return nullptr;
[email protected]94224ba62014-02-04 00:25:24208
Blink Reformat1c4d759e2017-04-09 16:34:54209 return browser_plugin_->Container();
[email protected]94224ba62014-02-04 00:25:24210}
211
vmpstre87ffcaa2016-08-23 21:01:14212void ChildFrameCompositingHelper::UpdateWebLayer(
213 std::unique_ptr<blink::WebLayer> layer) {
[email protected]94224ba62014-02-04 00:25:24214 if (GetContainer()) {
Blink Reformat1c4d759e2017-04-09 16:34:54215 GetContainer()->SetWebLayer(layer.get());
[email protected]94224ba62014-02-04 00:25:24216 } else if (frame_) {
Blink Reformat1c4d759e2017-04-09 16:34:54217 frame_->SetWebLayer(layer.get());
[email protected]bffc8302014-01-23 20:52:16218 }
vmpstre87ffcaa2016-08-23 21:01:14219 web_layer_ = std::move(layer);
[email protected]0f21e8582013-01-11 11:06:56220}
221
[email protected]bffc8302014-01-23 20:52:16222void ChildFrameCompositingHelper::OnContainerDestroy() {
lfgfd437a272015-11-24 21:24:53223 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21224}
225
[email protected]f49722f2014-01-30 17:54:50226void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53227 scoped_refptr<cc::SolidColorLayer> crashed_layer =
loyso0940d412016-03-14 01:30:31228 cc::SolidColorLayer::Create();
lfgfd437a272015-11-24 21:24:53229 crashed_layer->SetMasksToBounds(true);
lfgcccffbe2016-03-10 00:05:46230 crashed_layer->SetBackgroundColor(SK_ColorBLACK);
231
232 if (web_layer_) {
233 SkBitmap* sad_bitmap =
234 GetContentClient()->renderer()->GetSadWebViewBitmap();
Blink Reformat1c4d759e2017-04-09 16:34:54235 if (sad_bitmap && web_layer_->Bounds().width > sad_bitmap->width() &&
236 web_layer_->Bounds().height > sad_bitmap->height()) {
lfgcccffbe2016-03-10 00:05:46237 scoped_refptr<cc::PictureImageLayer> sad_layer =
loyso0940d412016-03-14 01:30:31238 cc::PictureImageLayer::Create();
Vladimir Levinf67b0fc02017-10-06 01:48:11239 sad_layer->SetImage(cc::PaintImageBuilder::WithDefault()
Vladimir Levin988d0242017-08-08 00:02:57240 .set_id(cc::PaintImage::kNonLazyStableId)
241 .set_image(SkImage::MakeFromBitmap(*sad_bitmap))
242 .TakePaintImage());
lfgcccffbe2016-03-10 00:05:46243 sad_layer->SetBounds(
244 gfx::Size(sad_bitmap->width(), sad_bitmap->height()));
245 sad_layer->SetPosition(gfx::PointF(
Blink Reformat1c4d759e2017-04-09 16:34:54246 (web_layer_->Bounds().width - sad_bitmap->width()) / 2,
247 (web_layer_->Bounds().height - sad_bitmap->height()) / 2));
lfgcccffbe2016-03-10 00:05:46248 sad_layer->SetIsDrawable(true);
249
250 crashed_layer->AddChild(sad_layer);
251 }
252 }
253
vmpstre87ffcaa2016-08-23 21:01:14254 std::unique_ptr<blink::WebLayer> layer(
255 new cc_blink::WebLayerImpl(crashed_layer));
256 UpdateWebLayer(std::move(layer));
[email protected]f49722f2014-01-30 17:54:50257}
258
Fady Samuel1cc05222017-11-17 10:42:26259void ChildFrameCompositingHelper::SetPrimarySurfaceId(
260 const viz::SurfaceId& surface_id,
261 const gfx::Size& frame_size_in_dip) {
262 if (last_primary_surface_id_ == surface_id)
Fady Samuel64eb4b4f2017-11-09 00:31:52263 return;
264
Fady Samuel1cc05222017-11-17 10:42:26265 last_primary_surface_id_ = surface_id;
Fady Samuel509c2d52017-08-28 19:00:58266
267 surface_layer_ = cc::SurfaceLayer::Create(surface_reference_factory_);
268 surface_layer_->SetMasksToBounds(true);
Fady Samuel02de6ee2018-01-05 21:20:21269 surface_layer_->SetBackgroundColor(SK_ColorTRANSPARENT);
Fady Samuel509c2d52017-08-28 19:00:58270
Fady Samuel1cc05222017-11-17 10:42:26271 surface_layer_->SetPrimarySurfaceId(surface_id);
Fady Samuelb47442d2017-10-13 04:17:34272 surface_layer_->SetFallbackSurfaceId(fallback_surface_id_);
Fady Samuel509c2d52017-08-28 19:00:58273
274 std::unique_ptr<cc_blink::WebLayerImpl> layer(
275 new cc_blink::WebLayerImpl(surface_layer_));
276 // TODO(lfg): Investigate if it's possible to propagate the information about
277 // the child surface's opacity. https://crbug.com/629851.
278 layer->SetOpaque(false);
279 layer->SetContentsOpaqueIsFixed(true);
280 UpdateWebLayer(std::move(layer));
281
282 UpdateVisibility(true);
283
Fady Samuel1cc05222017-11-17 10:42:26284 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())
285 ->layer()
286 ->SetBounds(frame_size_in_dip);
Fady Samuel509c2d52017-08-28 19:00:58287}
288
Fady Samuel1cc05222017-11-17 10:42:26289void ChildFrameCompositingHelper::SetFallbackSurfaceId(
290 const viz::SurfaceId& surface_id,
291 const gfx::Size& frame_size_in_dip,
Fady Samueldbd4b022017-07-14 02:06:48292 const viz::SurfaceSequence& sequence) {
Fady Samuel1cc05222017-11-17 10:42:26293 if (fallback_surface_id_ == surface_id)
Fady Samuel64eb4b4f2017-11-09 00:31:52294 return;
295
Fady Samuel1cc05222017-11-17 10:42:26296 fallback_surface_id_ = surface_id;
kenrb6ef29da2017-06-09 22:16:21297 // The RWHV creates a destruction dependency on the surface that needs to be
298 // satisfied. The reference factory will satisfy it when a new reference has
299 // been created.
kylecharc1a739a2017-07-27 23:34:59300 if (!enable_surface_references_) {
301 if (render_frame_proxy_) {
302 static_cast<IframeSurfaceReferenceFactory*>(
303 surface_reference_factory_.get())
304 ->AddPendingSequence(sequence);
305 } else {
306 static_cast<BrowserPluginSurfaceReferenceFactory*>(
307 surface_reference_factory_.get())
308 ->AddPendingSequence(sequence);
309 }
kenrb6ef29da2017-06-09 22:16:21310 }
311
Fady Samueld10aadd82017-11-03 18:23:57312 if (!surface_layer_) {
Fady Samuel1cc05222017-11-17 10:42:26313 SetPrimarySurfaceId(surface_id, frame_size_in_dip);
Fady Samueld10aadd82017-11-03 18:23:57314 return;
315 }
316
Fady Samuel1cc05222017-11-17 10:42:26317 surface_layer_->SetFallbackSurfaceId(surface_id);
kenrbfc7c02c92015-05-29 22:20:58318}
319
[email protected]bffc8302014-01-23 20:52:16320void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
lfgfd437a272015-11-24 21:24:53321 if (web_layer_)
Blink Reformat1c4d759e2017-04-09 16:34:54322 web_layer_->SetDrawsContent(visible);
[email protected]69b79122013-02-14 19:16:45323}
324
[email protected]0f21e8582013-01-11 11:06:56325} // namespace content