blob: 82a8adbf037875aabb1f7bc17752aacdb39648e3 [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"
Xu Xing32549162017-07-17 22:25:4315#include "components/viz/common/gpu/context_provider.h"
Fady Samueldfecb7d2017-07-26 11:41:0416#include "components/viz/common/quads/copy_output_request.h"
17#include "components/viz/common/quads/copy_output_result.h"
18#include "components/viz/common/quads/single_release_callback.h"
Fady Samueldbd4b022017-07-14 02:06:4819#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
kylecharc1a739a2017-07-27 23:34:5920#include "components/viz/common/surfaces/stub_surface_reference_factory.h"
21#include "components/viz/common/switches.h"
jbauman38c178eaa2015-06-04 04:24:5422#include "content/child/thread_safe_sender.h"
[email protected]703dd662013-03-05 07:37:4223#include "content/common/browser_plugin/browser_plugin_messages.h"
oshima9000e422016-01-27 03:05:3624#include "content/common/content_switches_internal.h"
[email protected]95d31822014-01-03 22:21:5525#include "content/common/frame_messages.h"
lfgcccffbe2016-03-10 00:05:4626#include "content/public/common/content_client.h"
27#include "content/public/renderer/content_renderer_client.h"
[email protected]94224ba62014-02-04 00:25:2428#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2129#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1630#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2731#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5632#include "content/renderer/render_thread_impl.h"
sadrul85cc5d82016-12-20 03:37:4133#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
[email protected]73405fb2013-12-11 04:59:3734#include "skia/ext/image_operations.h"
[email protected]2255a9332013-06-17 05:12:3135#include "third_party/WebKit/public/web/WebPluginContainer.h"
dcheng5cf543012016-11-24 17:13:3736#include "third_party/WebKit/public/web/WebRemoteFrame.h"
[email protected]7f0d825f2013-03-18 07:24:3037#include "third_party/khronos/GLES2/gl2.h"
lfgcccffbe2016-03-10 00:05:4638#include "third_party/skia/include/core/SkBitmap.h"
39#include "third_party/skia/include/core/SkImage.h"
40#include "ui/gfx/geometry/point_f.h"
tfarinaebe974f02015-01-03 04:25:3241#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3742#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5643
44namespace content {
45
samans72b2a282016-12-17 02:44:1546namespace {
47
48class IframeSurfaceReferenceFactory
Fady Samueldbd4b022017-07-14 02:06:4849 : public viz::SequenceSurfaceReferenceFactory {
samans72b2a282016-12-17 02:44:1550 public:
51 IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
52 int routing_id)
53 : sender_(std::move(sender)), routing_id_(routing_id) {}
54
Fady Samueldbd4b022017-07-14 02:06:4855 void AddPendingSequence(const viz::SurfaceSequence& sequence) {
kenrb6ef29da2017-06-09 22:16:2156 ReleasePendingSequenceIfNecessary();
57 pending_sequence_ = sequence;
58 }
59
samans72b2a282016-12-17 02:44:1560 private:
kenrb6ef29da2017-06-09 22:16:2161 ~IframeSurfaceReferenceFactory() override {
62 ReleasePendingSequenceIfNecessary();
63 }
64
65 void ReleasePendingSequenceIfNecessary() const {
66 if (pending_sequence_.is_valid()) {
67 sender_->Send(
68 new FrameHostMsg_SatisfySequence(routing_id_, pending_sequence_));
Fady Samueldbd4b022017-07-14 02:06:4869 pending_sequence_ = viz::SurfaceSequence();
kenrb6ef29da2017-06-09 22:16:2170 }
71 }
samans72b2a282016-12-17 02:44:1572
73 // cc::SequenceSurfaceReferenceFactory implementation:
Fady Samueld5c26182017-07-12 02:43:3374 void RequireSequence(const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:4875 const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:1576 sender_->Send(
77 new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:2178 // If there is a temporary reference that was waiting on a new one to be
79 // created, it is now safe to release it.
80 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:1581 }
82
Fady Samueldbd4b022017-07-14 02:06:4883 void SatisfySequence(const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:1584 sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence));
85 }
86
87 const scoped_refptr<ThreadSafeSender> sender_;
Fady Samueldbd4b022017-07-14 02:06:4888 mutable viz::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:1589 const int routing_id_;
90
91 DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory);
92};
93
94class BrowserPluginSurfaceReferenceFactory
Fady Samueldbd4b022017-07-14 02:06:4895 : public viz::SequenceSurfaceReferenceFactory {
samans72b2a282016-12-17 02:44:1596 public:
97 BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
98 int routing_id,
99 int browser_plugin_instance_id)
100 : sender_(std::move(sender)),
101 routing_id_(routing_id),
102 browser_plugin_instance_id_(browser_plugin_instance_id) {}
103
Fady Samueldbd4b022017-07-14 02:06:48104 void AddPendingSequence(const viz::SurfaceSequence& sequence) {
kenrb6ef29da2017-06-09 22:16:21105 ReleasePendingSequenceIfNecessary();
106 pending_sequence_ = sequence;
107 }
108
samans72b2a282016-12-17 02:44:15109 private:
kenrb6ef29da2017-06-09 22:16:21110 ~BrowserPluginSurfaceReferenceFactory() override {
111 ReleasePendingSequenceIfNecessary();
112 }
113
114 void ReleasePendingSequenceIfNecessary() const {
115 if (pending_sequence_.is_valid()) {
116 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
117 routing_id_, browser_plugin_instance_id_, pending_sequence_));
Fady Samueldbd4b022017-07-14 02:06:48118 pending_sequence_ = viz::SurfaceSequence();
kenrb6ef29da2017-06-09 22:16:21119 }
120 }
samans72b2a282016-12-17 02:44:15121
122 // cc::SequenceSurfaceRefrenceFactory implementation:
Fady Samueldbd4b022017-07-14 02:06:48123 void SatisfySequence(const viz::SurfaceSequence& seq) const override {
samans72b2a282016-12-17 02:44:15124 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
125 routing_id_, browser_plugin_instance_id_, seq));
126 }
127
Fady Samueld5c26182017-07-12 02:43:33128 void RequireSequence(const viz::SurfaceId& surface_id,
Fady Samueldbd4b022017-07-14 02:06:48129 const viz::SurfaceSequence& sequence) const override {
samans72b2a282016-12-17 02:44:15130 sender_->Send(new BrowserPluginHostMsg_RequireSequence(
131 routing_id_, browser_plugin_instance_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:21132 // If there is a temporary reference that was waiting on a new one to be
133 // created, it is now safe to release it.
134 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:15135 }
136
137 const scoped_refptr<ThreadSafeSender> sender_;
Fady Samueldbd4b022017-07-14 02:06:48138 mutable viz::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:15139 const int routing_id_;
140 const int browser_plugin_instance_id_;
141
142 DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory);
143};
144
145} // namespace
146
[email protected]bffc8302014-01-23 20:52:16147ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33148ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:24149 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:16150 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:58151 browser_plugin, nullptr, nullptr,
152 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:16153}
154
155ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33156ChildFrameCompositingHelper::CreateForRenderFrameProxy(
157 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:53158 return new ChildFrameCompositingHelper(
159 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
160 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:16161}
162
163ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:24164 const base::WeakPtr<BrowserPlugin>& browser_plugin,
dcheng5cf543012016-11-24 17:13:37165 blink::WebRemoteFrame* frame,
[email protected]e3244ed2014-06-20 20:04:27166 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:56167 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:24168 : host_routing_id_(host_routing_id),
[email protected]94224ba62014-02-04 00:25:24169 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:27170 render_frame_proxy_(render_frame_proxy),
samans72b2a282016-12-17 02:44:15171 frame_(frame) {
kylecharc1a739a2017-07-27 23:34:59172 enable_surface_references_ =
173 base::CommandLine::ForCurrentProcess()->HasSwitch(
174 switches::kEnableSurfaceReferences);
samans72b2a282016-12-17 02:44:15175 scoped_refptr<ThreadSafeSender> sender(
176 RenderThreadImpl::current()->thread_safe_sender());
kylecharc1a739a2017-07-27 23:34:59177 if (enable_surface_references_) {
178 surface_reference_factory_ = new viz::StubSurfaceReferenceFactory();
179 } else if (render_frame_proxy_) {
samans72b2a282016-12-17 02:44:15180 surface_reference_factory_ =
181 new IframeSurfaceReferenceFactory(sender, host_routing_id_);
182 } else {
183 surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory(
184 sender, host_routing_id_,
185 browser_plugin_->browser_plugin_instance_id());
186 }
187}
[email protected]bffc8302014-01-23 20:52:16188
lfga7d368e2015-02-03 23:01:37189ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
lfga7d368e2015-02-03 23:01:37190}
[email protected]bffc8302014-01-23 20:52:16191
[email protected]94224ba62014-02-04 00:25:24192blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
193 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:58194 return nullptr;
[email protected]94224ba62014-02-04 00:25:24195
Blink Reformat1c4d759e2017-04-09 16:34:54196 return browser_plugin_->Container();
[email protected]94224ba62014-02-04 00:25:24197}
198
vmpstre87ffcaa2016-08-23 21:01:14199void ChildFrameCompositingHelper::UpdateWebLayer(
200 std::unique_ptr<blink::WebLayer> layer) {
[email protected]94224ba62014-02-04 00:25:24201 if (GetContainer()) {
Blink Reformat1c4d759e2017-04-09 16:34:54202 GetContainer()->SetWebLayer(layer.get());
[email protected]94224ba62014-02-04 00:25:24203 } else if (frame_) {
Blink Reformat1c4d759e2017-04-09 16:34:54204 frame_->SetWebLayer(layer.get());
[email protected]bffc8302014-01-23 20:52:16205 }
vmpstre87ffcaa2016-08-23 21:01:14206 web_layer_ = std::move(layer);
[email protected]0f21e8582013-01-11 11:06:56207}
208
[email protected]bffc8302014-01-23 20:52:16209void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28210 const gfx::Size& new_size,
211 float device_scale_factor,
212 cc::Layer* layer) {
213 if (buffer_size_ != new_size) {
214 buffer_size_ = new_size;
215 // The container size is in DIP, so is the layer size.
216 // Buffer size is in physical pixels, so we need to adjust
217 // it by the device scale factor.
danakjddaec912015-09-25 19:38:40218 gfx::Size device_scale_adjusted_size =
219 gfx::ScaleToFlooredSize(buffer_size_, 1.0f / device_scale_factor);
[email protected]f5b4b0f2013-04-02 18:16:28220 layer->SetBounds(device_scale_adjusted_size);
221 }
222}
223
[email protected]bffc8302014-01-23 20:52:16224void ChildFrameCompositingHelper::OnContainerDestroy() {
lfgfd437a272015-11-24 21:24:53225 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21226}
227
[email protected]f49722f2014-01-30 17:54:50228void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53229 scoped_refptr<cc::SolidColorLayer> crashed_layer =
loyso0940d412016-03-14 01:30:31230 cc::SolidColorLayer::Create();
lfgfd437a272015-11-24 21:24:53231 crashed_layer->SetMasksToBounds(true);
lfgcccffbe2016-03-10 00:05:46232 crashed_layer->SetBackgroundColor(SK_ColorBLACK);
233
234 if (web_layer_) {
235 SkBitmap* sad_bitmap =
236 GetContentClient()->renderer()->GetSadWebViewBitmap();
Blink Reformat1c4d759e2017-04-09 16:34:54237 if (sad_bitmap && web_layer_->Bounds().width > sad_bitmap->width() &&
238 web_layer_->Bounds().height > sad_bitmap->height()) {
lfgcccffbe2016-03-10 00:05:46239 scoped_refptr<cc::PictureImageLayer> sad_layer =
loyso0940d412016-03-14 01:30:31240 cc::PictureImageLayer::Create();
vmpstr81a39a32017-05-16 19:30:21241 sad_layer->SetImage(cc::PaintImage(cc::PaintImage::kNonLazyStableId,
242 SkImage::MakeFromBitmap(*sad_bitmap)));
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
kenrbfc7c02c92015-05-29 22:20:58259void ChildFrameCompositingHelper::OnSetSurface(
Fady Samuel1a21156e2017-07-13 04:57:29260 const viz::SurfaceInfo& surface_info,
Fady Samueldbd4b022017-07-14 02:06:48261 const viz::SurfaceSequence& sequence) {
fsamuel96795522017-01-04 02:41:32262 float scale_factor = surface_info.device_scale_factor();
263 surface_id_ = surface_info.id();
lfgfd437a272015-11-24 21:24:53264 scoped_refptr<cc::SurfaceLayer> surface_layer =
samans72b2a282016-12-17 02:44:15265 cc::SurfaceLayer::Create(surface_reference_factory_);
oshima9000e422016-01-27 03:05:36266 // TODO(oshima): This is a stopgap fix so that the compositor does not
267 // scaledown the content when 2x frame data is added to 1x parent frame data.
268 // Fix this in cc/.
269 if (IsUseZoomForDSFEnabled())
270 scale_factor = 1.0f;
fsamuel96795522017-01-04 02:41:32271
kenrb6ef29da2017-06-09 22:16:21272 // The RWHV creates a destruction dependency on the surface that needs to be
273 // satisfied. The reference factory will satisfy it when a new reference has
274 // been created.
kylecharc1a739a2017-07-27 23:34:59275 if (!enable_surface_references_) {
276 if (render_frame_proxy_) {
277 static_cast<IframeSurfaceReferenceFactory*>(
278 surface_reference_factory_.get())
279 ->AddPendingSequence(sequence);
280 } else {
281 static_cast<BrowserPluginSurfaceReferenceFactory*>(
282 surface_reference_factory_.get())
283 ->AddPendingSequence(sequence);
284 }
kenrb6ef29da2017-06-09 22:16:21285 }
286
Fady Samuel1a21156e2017-07-13 04:57:29287 viz::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor,
288 surface_info.size_in_pixels());
fsamuelcc854aa52017-06-06 03:03:47289 surface_layer->SetPrimarySurfaceInfo(modified_surface_info);
290 surface_layer->SetFallbackSurfaceInfo(modified_surface_info);
lfg042482c2016-01-21 03:53:55291 surface_layer->SetMasksToBounds(true);
vmpstre87ffcaa2016-08-23 21:01:14292 std::unique_ptr<cc_blink::WebLayerImpl> layer(
293 new cc_blink::WebLayerImpl(surface_layer));
lfg04c6bd602016-07-20 17:02:52294 // TODO(lfg): Investigate if it's possible to propagate the information about
295 // the child surface's opacity. https://crbug.com/629851.
Blink Reformat1c4d759e2017-04-09 16:34:54296 layer->SetOpaque(false);
lfg04c6bd602016-07-20 17:02:52297 layer->SetContentsOpaqueIsFixed(true);
vmpstre87ffcaa2016-08-23 21:01:14298 UpdateWebLayer(std::move(layer));
kenrbfc7c02c92015-05-29 22:20:58299
kenrbfc7c02c92015-05-29 22:20:58300 UpdateVisibility(true);
kenrbfc7c02c92015-05-29 22:20:58301
lfgfd437a272015-11-24 21:24:53302 CheckSizeAndAdjustLayerProperties(
fsamuel96795522017-01-04 02:41:32303 surface_info.size_in_pixels(), surface_info.device_scale_factor(),
lfgfd437a272015-11-24 21:24:53304 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
kenrbfc7c02c92015-05-29 22:20:58305}
306
[email protected]bffc8302014-01-23 20:52:16307void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
lfgfd437a272015-11-24 21:24:53308 if (web_layer_)
Blink Reformat1c4d759e2017-04-09 16:34:54309 web_layer_->SetDrawsContent(visible);
[email protected]69b79122013-02-14 19:16:45310}
311
[email protected]0f21e8582013-01-11 11:06:56312} // namespace content