blob: 78a129b782bababc2cb4213f2377757713af7eeb [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"
[email protected]38564622014-08-19 02:47:1810#include "cc/blink/web_layer_impl.h"
lfgcccffbe2016-03-10 00:05:4611#include "cc/layers/picture_image_layer.h"
[email protected]cc3cfaa2013-03-18 09:05:5212#include "cc/layers/solid_color_layer.h"
kenrbfc7c02c92015-05-29 22:20:5813#include "cc/layers/surface_layer.h"
vmpstr55c7657ca2017-04-29 00:46:4814#include "cc/paint/paint_image.h"
Vladimir Levin988d0242017-08-08 00:02:5715#include "cc/paint/paint_image_builder.h"
danakjf20f4502017-09-26 17:13:3116#include "components/viz/common/frame_sinks/copy_output_request.h"
17#include "components/viz/common/frame_sinks/copy_output_result.h"
Xu Xing32549162017-07-17 22:25:4318#include "components/viz/common/gpu/context_provider.h"
danakjf20f4502017-09-26 17:13:3119#include "components/viz/common/resources/single_release_callback.h"
Fady Samueldbd4b022017-07-14 02:06:4820#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
kylecharc1a739a2017-07-27 23:34:5921#include "components/viz/common/surfaces/stub_surface_reference_factory.h"
22#include "components/viz/common/switches.h"
jbauman38c178eaa2015-06-04 04:24:5423#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4224#include "content/common/browser_plugin/browser_plugin_messages.h"
oshima9000e422016-01-27 03:05:3625#include "content/common/content_switches_internal.h"
[email protected]95d31822014-01-03 22:21:5526#include "content/common/frame_messages.h"
lfgcccffbe2016-03-10 00:05:4627#include "content/public/common/content_client.h"
28#include "content/public/renderer/content_renderer_client.h"
[email protected]94224ba62014-02-04 00:25:2429#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2130#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1631#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2732#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5633#include "content/renderer/render_thread_impl.h"
sadrul85cc5d82016-12-20 03:37:4134#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
[email protected]73405fb2013-12-11 04:59:3735#include "skia/ext/image_operations.h"
[email protected]2255a9332013-06-17 05:12:3136#include "third_party/WebKit/public/web/WebPluginContainer.h"
dcheng5cf543012016-11-24 17:13:3737#include "third_party/WebKit/public/web/WebRemoteFrame.h"
[email protected]7f0d825f2013-03-18 07:24:3038#include "third_party/khronos/GLES2/gl2.h"
lfgcccffbe2016-03-10 00:05:4639#include "third_party/skia/include/core/SkBitmap.h"
40#include "third_party/skia/include/core/SkImage.h"
41#include "ui/gfx/geometry/point_f.h"
tfarinaebe974f02015-01-03 04:25:3242#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3743#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5644
45namespace content {
46
samans72b2a282016-12-17 02:44:1547namespace {
48
49class IframeSurfaceReferenceFactory
Fady Samueldbd4b022017-07-14 02:06:4850 : public viz::SequenceSurfaceReferenceFactory {
samans72b2a282016-12-17 02:44:1551 public:
52 IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
53 int routing_id)
54 : sender_(std::move(sender)), routing_id_(routing_id) {}
55
Fady Samueldbd4b022017-07-14 02:06:4856 void AddPendingSequence(const viz::SurfaceSequence& sequence) {
kenrb6ef29da2017-06-09 22:16:2157 ReleasePendingSequenceIfNecessary();
58 pending_sequence_ = sequence;
59 }
60
samans72b2a282016-12-17 02:44:1561 private:
kenrb6ef29da2017-06-09 22:16:2162 ~IframeSurfaceReferenceFactory() override {
63 ReleasePendingSequenceIfNecessary();
64 }
65
66 void ReleasePendingSequenceIfNecessary() const {
67 if (pending_sequence_.is_valid()) {
68 sender_->Send(
69 new FrameHostMsg_SatisfySequence(routing_id_, pending_sequence_));
Fady Samueldbd4b022017-07-14 02:06:4870 pending_sequence_ = viz::SurfaceSequence();
kenrb6ef29da2017-06-09 22:16:2171 }
72 }
samans72b2a282016-12-17 02:44:1573
74 // cc::SequenceSurfaceReferenceFactory implementation:
Fady Samueld5c26182017-07-12 02:43:3375 void RequireSequence(const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:4876 const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:1577 sender_->Send(
78 new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:2179 // If there is a temporary reference that was waiting on a new one to be
80 // created, it is now safe to release it.
81 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:1582 }
83
Fady Samueldbd4b022017-07-14 02:06:4884 void SatisfySequence(const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:1585 sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence));
86 }
87
88 const scoped_refptr<ThreadSafeSender> sender_;
Fady Samueldbd4b022017-07-14 02:06:4889 mutable viz::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:1590 const int routing_id_;
91
92 DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory);
93};
94
95class BrowserPluginSurfaceReferenceFactory
Fady Samueldbd4b022017-07-14 02:06:4896 : public viz::SequenceSurfaceReferenceFactory {
samans72b2a282016-12-17 02:44:1597 public:
98 BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
99 int routing_id,
100 int browser_plugin_instance_id)
101 : sender_(std::move(sender)),
102 routing_id_(routing_id),
103 browser_plugin_instance_id_(browser_plugin_instance_id) {}
104
Fady Samueldbd4b022017-07-14 02:06:48105 void AddPendingSequence(const viz::SurfaceSequence& sequence) {
kenrb6ef29da2017-06-09 22:16:21106 ReleasePendingSequenceIfNecessary();
107 pending_sequence_ = sequence;
108 }
109
samans72b2a282016-12-17 02:44:15110 private:
kenrb6ef29da2017-06-09 22:16:21111 ~BrowserPluginSurfaceReferenceFactory() override {
112 ReleasePendingSequenceIfNecessary();
113 }
114
115 void ReleasePendingSequenceIfNecessary() const {
116 if (pending_sequence_.is_valid()) {
117 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
118 routing_id_, browser_plugin_instance_id_, pending_sequence_));
Fady Samueldbd4b022017-07-14 02:06:48119 pending_sequence_ = viz::SurfaceSequence();
kenrb6ef29da2017-06-09 22:16:21120 }
121 }
samans72b2a282016-12-17 02:44:15122
123 // cc::SequenceSurfaceRefrenceFactory implementation:
Fady Samueldbd4b022017-07-14 02:06:48124 void SatisfySequence(const viz::SurfaceSequence& seq) const override {
samans72b2a282016-12-17 02:44:15125 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
126 routing_id_, browser_plugin_instance_id_, seq));
127 }
128
Fady Samueld5c26182017-07-12 02:43:33129 void RequireSequence(const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:48130 const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:15131 sender_->Send(new BrowserPluginHostMsg_RequireSequence(
132 routing_id_, browser_plugin_instance_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:21133 // If there is a temporary reference that was waiting on a new one to be
134 // created, it is now safe to release it.
135 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:15136 }
137
138 const scoped_refptr<ThreadSafeSender> sender_;
Fady Samueldbd4b022017-07-14 02:06:48139 mutable viz::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:15140 const int routing_id_;
141 const int browser_plugin_instance_id_;
142
143 DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory);
144};
145
146} // namespace
147
[email protected]bffc8302014-01-23 20:52:16148ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33149ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:24150 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:16151 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:58152 browser_plugin, nullptr, nullptr,
153 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:16154}
155
156ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33157ChildFrameCompositingHelper::CreateForRenderFrameProxy(
158 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:53159 return new ChildFrameCompositingHelper(
160 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
161 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:16162}
163
164ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:24165 const base::WeakPtr<BrowserPlugin>& browser_plugin,
dcheng5cf543012016-11-24 17:13:37166 blink::WebRemoteFrame* frame,
[email protected]e3244ed2014-06-20 20:04:27167 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:56168 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:24169 : host_routing_id_(host_routing_id),
[email protected]94224ba62014-02-04 00:25:24170 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:27171 render_frame_proxy_(render_frame_proxy),
samans72b2a282016-12-17 02:44:15172 frame_(frame) {
kylecharc1a739a2017-07-27 23:34:59173 enable_surface_references_ =
kylechar68156e62017-08-15 13:29:52174 !base::CommandLine::ForCurrentProcess()->HasSwitch(
175 switches::kDisableSurfaceReferences);
kylecharc1a739a2017-07-27 23:34:59176 if (enable_surface_references_) {
177 surface_reference_factory_ = new viz::StubSurfaceReferenceFactory();
samans72b2a282016-12-17 02:44:15178 } else {
Fady Samuelea0d99e2017-09-28 02:21:07179 scoped_refptr<ThreadSafeSender> sender(
180 RenderThreadImpl::current()->thread_safe_sender());
181 if (render_frame_proxy_) {
182 surface_reference_factory_ =
183 new IframeSurfaceReferenceFactory(sender, host_routing_id_);
184 } else {
185 surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory(
186 sender, host_routing_id_,
187 browser_plugin_->browser_plugin_instance_id());
188 }
samans72b2a282016-12-17 02:44:15189 }
190}
[email protected]bffc8302014-01-23 20:52:16191
lfga7d368e2015-02-03 23:01:37192ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
lfga7d368e2015-02-03 23:01:37193}
[email protected]bffc8302014-01-23 20:52:16194
[email protected]94224ba62014-02-04 00:25:24195blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
196 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:58197 return nullptr;
[email protected]94224ba62014-02-04 00:25:24198
Blink Reformat1c4d759e2017-04-09 16:34:54199 return browser_plugin_->Container();
[email protected]94224ba62014-02-04 00:25:24200}
201
vmpstre87ffcaa2016-08-23 21:01:14202void ChildFrameCompositingHelper::UpdateWebLayer(
203 std::unique_ptr<blink::WebLayer> layer) {
[email protected]94224ba62014-02-04 00:25:24204 if (GetContainer()) {
Blink Reformat1c4d759e2017-04-09 16:34:54205 GetContainer()->SetWebLayer(layer.get());
[email protected]94224ba62014-02-04 00:25:24206 } else if (frame_) {
Blink Reformat1c4d759e2017-04-09 16:34:54207 frame_->SetWebLayer(layer.get());
[email protected]bffc8302014-01-23 20:52:16208 }
vmpstre87ffcaa2016-08-23 21:01:14209 web_layer_ = std::move(layer);
[email protected]0f21e8582013-01-11 11:06:56210}
211
[email protected]bffc8302014-01-23 20:52:16212void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
Fady Samuel509c2d52017-08-28 19:00:58213 const viz::SurfaceInfo& surface_info,
[email protected]f5b4b0f2013-04-02 18:16:28214 cc::Layer* layer) {
Fady Samuel509c2d52017-08-28 19:00:58215 if (last_surface_size_in_pixels_ == surface_info.size_in_pixels())
216 return;
217
218 last_surface_size_in_pixels_ = surface_info.size_in_pixels();
219 // The container size is in DIP, so is the layer size.
220 // Buffer size is in physical pixels, so we need to adjust
221 // it by the device scale factor.
222 gfx::Size device_scale_adjusted_size = gfx::ScaleToFlooredSize(
223 surface_info.size_in_pixels(), 1.0f / surface_info.device_scale_factor());
224 layer->SetBounds(device_scale_adjusted_size);
[email protected]f5b4b0f2013-04-02 18:16:28225}
226
[email protected]bffc8302014-01-23 20:52:16227void ChildFrameCompositingHelper::OnContainerDestroy() {
lfgfd437a272015-11-24 21:24:53228 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21229}
230
[email protected]f49722f2014-01-30 17:54:50231void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53232 scoped_refptr<cc::SolidColorLayer> crashed_layer =
loyso0940d412016-03-14 01:30:31233 cc::SolidColorLayer::Create();
lfgfd437a272015-11-24 21:24:53234 crashed_layer->SetMasksToBounds(true);
lfgcccffbe2016-03-10 00:05:46235 crashed_layer->SetBackgroundColor(SK_ColorBLACK);
236
237 if (web_layer_) {
238 SkBitmap* sad_bitmap =
239 GetContentClient()->renderer()->GetSadWebViewBitmap();
Blink Reformat1c4d759e2017-04-09 16:34:54240 if (sad_bitmap && web_layer_->Bounds().width > sad_bitmap->width() &&
241 web_layer_->Bounds().height > sad_bitmap->height()) {
lfgcccffbe2016-03-10 00:05:46242 scoped_refptr<cc::PictureImageLayer> sad_layer =
loyso0940d412016-03-14 01:30:31243 cc::PictureImageLayer::Create();
Vladimir Levinf67b0fc02017-10-06 01:48:11244 sad_layer->SetImage(cc::PaintImageBuilder::WithDefault()
Vladimir Levin988d0242017-08-08 00:02:57245 .set_id(cc::PaintImage::kNonLazyStableId)
246 .set_image(SkImage::MakeFromBitmap(*sad_bitmap))
247 .TakePaintImage());
lfgcccffbe2016-03-10 00:05:46248 sad_layer->SetBounds(
249 gfx::Size(sad_bitmap->width(), sad_bitmap->height()));
250 sad_layer->SetPosition(gfx::PointF(
Blink Reformat1c4d759e2017-04-09 16:34:54251 (web_layer_->Bounds().width - sad_bitmap->width()) / 2,
252 (web_layer_->Bounds().height - sad_bitmap->height()) / 2));
lfgcccffbe2016-03-10 00:05:46253 sad_layer->SetIsDrawable(true);
254
255 crashed_layer->AddChild(sad_layer);
256 }
257 }
258
vmpstre87ffcaa2016-08-23 21:01:14259 std::unique_ptr<blink::WebLayer> layer(
260 new cc_blink::WebLayerImpl(crashed_layer));
261 UpdateWebLayer(std::move(layer));
[email protected]f49722f2014-01-30 17:54:50262}
263
Fady Samuel509c2d52017-08-28 19:00:58264void ChildFrameCompositingHelper::SetPrimarySurfaceInfo(
265 const viz::SurfaceInfo& surface_info) {
266 last_primary_surface_id_ = surface_info.id();
267 float scale_factor = surface_info.device_scale_factor();
268 // TODO(oshima): This is a stopgap fix so that the compositor does not
269 // scaledown the content when 2x frame data is added to 1x parent frame data.
270 // Fix this in cc/.
271 if (IsUseZoomForDSFEnabled())
272 scale_factor = 1.0f;
273
274 surface_layer_ = cc::SurfaceLayer::Create(surface_reference_factory_);
275 surface_layer_->SetMasksToBounds(true);
Fady Samuelea0d99e2017-09-28 02:21:07276 surface_layer_->SetDefaultBackgroundColor(SK_ColorTRANSPARENT);
Fady Samuel509c2d52017-08-28 19:00:58277
278 viz::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor,
279 surface_info.size_in_pixels());
280 surface_layer_->SetPrimarySurfaceInfo(modified_surface_info);
Fady Samuelb47442d2017-10-13 04:17:34281 surface_layer_->SetFallbackSurfaceId(fallback_surface_id_);
Fady Samuel509c2d52017-08-28 19:00:58282
283 std::unique_ptr<cc_blink::WebLayerImpl> layer(
284 new cc_blink::WebLayerImpl(surface_layer_));
285 // TODO(lfg): Investigate if it's possible to propagate the information about
286 // the child surface's opacity. https://crbug.com/629851.
287 layer->SetOpaque(false);
288 layer->SetContentsOpaqueIsFixed(true);
289 UpdateWebLayer(std::move(layer));
290
291 UpdateVisibility(true);
292
293 CheckSizeAndAdjustLayerProperties(
294 surface_info,
295 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
296}
297
Fady Samuelb47442d2017-10-13 04:17:34298void ChildFrameCompositingHelper::SetFallbackSurfaceId(
299 const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:48300 const viz::SurfaceSequence& sequence) {
Fady Samuelb47442d2017-10-13 04:17:34301 fallback_surface_id_ = surface_id;
kenrb6ef29da2017-06-09 22:16:21302 // The RWHV creates a destruction dependency on the surface that needs to be
303 // satisfied. The reference factory will satisfy it when a new reference has
304 // been created.
kylecharc1a739a2017-07-27 23:34:59305 if (!enable_surface_references_) {
306 if (render_frame_proxy_) {
307 static_cast<IframeSurfaceReferenceFactory*>(
308 surface_reference_factory_.get())
309 ->AddPendingSequence(sequence);
310 } else {
311 static_cast<BrowserPluginSurfaceReferenceFactory*>(
312 surface_reference_factory_.get())
313 ->AddPendingSequence(sequence);
314 }
kenrb6ef29da2017-06-09 22:16:21315 }
316
Fady Samuelb47442d2017-10-13 04:17:34317 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