blob: 8d715a2ba63b0d514c73c2e5355fec3b03513559 [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"
lfgcccffbe2016-03-10 00:05:4610#include "cc/layers/picture_image_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"
vmpstr55c7657ca2017-04-29 00:46:4816#include "cc/paint/paint_image.h"
[email protected]9260757f2013-09-17 01:24:1617#include "cc/resources/single_release_callback.h"
samans72b2a282016-12-17 02:44:1518#include "cc/surfaces/sequence_surface_reference_factory.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"
oshima9000e422016-01-27 03:05:3621#include "content/common/content_switches_internal.h"
[email protected]95d31822014-01-03 22:21:5522#include "content/common/frame_messages.h"
lfgcccffbe2016-03-10 00:05:4623#include "content/public/common/content_client.h"
24#include "content/public/renderer/content_renderer_client.h"
[email protected]94224ba62014-02-04 00:25:2425#include "content/renderer/browser_plugin/browser_plugin.h"
[email protected]0d25cb62013-01-21 15:42:2126#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1627#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2728#include "content/renderer/render_frame_proxy.h"
[email protected]0f21e8582013-01-11 11:06:5629#include "content/renderer/render_thread_impl.h"
sadrul85cc5d82016-12-20 03:37:4130#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
[email protected]73405fb2013-12-11 04:59:3731#include "skia/ext/image_operations.h"
[email protected]2255a9332013-06-17 05:12:3132#include "third_party/WebKit/public/web/WebPluginContainer.h"
dcheng5cf543012016-11-24 17:13:3733#include "third_party/WebKit/public/web/WebRemoteFrame.h"
[email protected]7f0d825f2013-03-18 07:24:3034#include "third_party/khronos/GLES2/gl2.h"
lfgcccffbe2016-03-10 00:05:4635#include "third_party/skia/include/core/SkBitmap.h"
36#include "third_party/skia/include/core/SkImage.h"
37#include "ui/gfx/geometry/point_f.h"
tfarinaebe974f02015-01-03 04:25:3238#include "ui/gfx/geometry/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3739#include "ui/gfx/skia_util.h"
[email protected]0f21e8582013-01-11 11:06:5640
41namespace content {
42
samans72b2a282016-12-17 02:44:1543namespace {
44
45class IframeSurfaceReferenceFactory
46 : public cc::SequenceSurfaceReferenceFactory {
47 public:
48 IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
49 int routing_id)
50 : sender_(std::move(sender)), routing_id_(routing_id) {}
51
kenrb6ef29da2017-06-09 22:16:2152 void AddPendingSequence(const cc::SurfaceSequence& sequence) {
53 ReleasePendingSequenceIfNecessary();
54 pending_sequence_ = sequence;
55 }
56
samans72b2a282016-12-17 02:44:1557 private:
kenrb6ef29da2017-06-09 22:16:2158 ~IframeSurfaceReferenceFactory() override {
59 ReleasePendingSequenceIfNecessary();
60 }
61
62 void ReleasePendingSequenceIfNecessary() const {
63 if (pending_sequence_.is_valid()) {
64 sender_->Send(
65 new FrameHostMsg_SatisfySequence(routing_id_, pending_sequence_));
66 pending_sequence_ = cc::SurfaceSequence();
67 }
68 }
samans72b2a282016-12-17 02:44:1569
70 // cc::SequenceSurfaceReferenceFactory implementation:
71 void RequireSequence(const cc::SurfaceId& surface_id,
72 const cc::SurfaceSequence& sequence) const override {
73 sender_->Send(
74 new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:2175 // If there is a temporary reference that was waiting on a new one to be
76 // created, it is now safe to release it.
77 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:1578 }
79
80 void SatisfySequence(const cc::SurfaceSequence& sequence) const override {
81 sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence));
82 }
83
84 const scoped_refptr<ThreadSafeSender> sender_;
kenrb6ef29da2017-06-09 22:16:2185 mutable cc::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:1586 const int routing_id_;
87
88 DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory);
89};
90
91class BrowserPluginSurfaceReferenceFactory
92 : public cc::SequenceSurfaceReferenceFactory {
93 public:
94 BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender,
95 int routing_id,
96 int browser_plugin_instance_id)
97 : sender_(std::move(sender)),
98 routing_id_(routing_id),
99 browser_plugin_instance_id_(browser_plugin_instance_id) {}
100
kenrb6ef29da2017-06-09 22:16:21101 void AddPendingSequence(const cc::SurfaceSequence& sequence) {
102 ReleasePendingSequenceIfNecessary();
103 pending_sequence_ = sequence;
104 }
105
samans72b2a282016-12-17 02:44:15106 private:
kenrb6ef29da2017-06-09 22:16:21107 ~BrowserPluginSurfaceReferenceFactory() override {
108 ReleasePendingSequenceIfNecessary();
109 }
110
111 void ReleasePendingSequenceIfNecessary() const {
112 if (pending_sequence_.is_valid()) {
113 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
114 routing_id_, browser_plugin_instance_id_, pending_sequence_));
115 pending_sequence_ = cc::SurfaceSequence();
116 }
117 }
samans72b2a282016-12-17 02:44:15118
119 // cc::SequenceSurfaceRefrenceFactory implementation:
120 void SatisfySequence(const cc::SurfaceSequence& seq) const override {
121 sender_->Send(new BrowserPluginHostMsg_SatisfySequence(
122 routing_id_, browser_plugin_instance_id_, seq));
123 }
124
125 void RequireSequence(const cc::SurfaceId& surface_id,
126 const cc::SurfaceSequence& sequence) const override {
127 sender_->Send(new BrowserPluginHostMsg_RequireSequence(
128 routing_id_, browser_plugin_instance_id_, surface_id, sequence));
kenrb6ef29da2017-06-09 22:16:21129 // If there is a temporary reference that was waiting on a new one to be
130 // created, it is now safe to release it.
131 ReleasePendingSequenceIfNecessary();
samans72b2a282016-12-17 02:44:15132 }
133
134 const scoped_refptr<ThreadSafeSender> sender_;
kenrb6ef29da2017-06-09 22:16:21135 mutable cc::SurfaceSequence pending_sequence_;
samans72b2a282016-12-17 02:44:15136 const int routing_id_;
137 const int browser_plugin_instance_id_;
138
139 DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory);
140};
141
142} // namespace
143
[email protected]bffc8302014-01-23 20:52:16144ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33145ChildFrameCompositingHelper::CreateForBrowserPlugin(
[email protected]94224ba62014-02-04 00:25:24146 const base::WeakPtr<BrowserPlugin>& browser_plugin) {
[email protected]bffc8302014-01-23 20:52:16147 return new ChildFrameCompositingHelper(
kenrbfc7c02c92015-05-29 22:20:58148 browser_plugin, nullptr, nullptr,
149 browser_plugin->render_frame_routing_id());
[email protected]bffc8302014-01-23 20:52:16150}
151
152ChildFrameCompositingHelper*
[email protected]c092f5c2014-07-18 01:34:33153ChildFrameCompositingHelper::CreateForRenderFrameProxy(
154 RenderFrameProxy* render_frame_proxy) {
lfgfd437a272015-11-24 21:24:53155 return new ChildFrameCompositingHelper(
156 base::WeakPtr<BrowserPlugin>(), render_frame_proxy->web_frame(),
157 render_frame_proxy, render_frame_proxy->routing_id());
[email protected]bffc8302014-01-23 20:52:16158}
159
160ChildFrameCompositingHelper::ChildFrameCompositingHelper(
[email protected]94224ba62014-02-04 00:25:24161 const base::WeakPtr<BrowserPlugin>& browser_plugin,
dcheng5cf543012016-11-24 17:13:37162 blink::WebRemoteFrame* frame,
[email protected]e3244ed2014-06-20 20:04:27163 RenderFrameProxy* render_frame_proxy,
[email protected]0f21e8582013-01-11 11:06:56164 int host_routing_id)
[email protected]94224ba62014-02-04 00:25:24165 : host_routing_id_(host_routing_id),
[email protected]94224ba62014-02-04 00:25:24166 browser_plugin_(browser_plugin),
[email protected]e3244ed2014-06-20 20:04:27167 render_frame_proxy_(render_frame_proxy),
samans72b2a282016-12-17 02:44:15168 frame_(frame) {
169 scoped_refptr<ThreadSafeSender> sender(
170 RenderThreadImpl::current()->thread_safe_sender());
171 if (render_frame_proxy_) {
172 surface_reference_factory_ =
173 new IframeSurfaceReferenceFactory(sender, host_routing_id_);
174 } else {
175 surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory(
176 sender, host_routing_id_,
177 browser_plugin_->browser_plugin_instance_id());
178 }
179}
[email protected]bffc8302014-01-23 20:52:16180
lfga7d368e2015-02-03 23:01:37181ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {
lfga7d368e2015-02-03 23:01:37182}
[email protected]bffc8302014-01-23 20:52:16183
[email protected]94224ba62014-02-04 00:25:24184blink::WebPluginContainer* ChildFrameCompositingHelper::GetContainer() {
185 if (!browser_plugin_)
kenrbfc7c02c92015-05-29 22:20:58186 return nullptr;
[email protected]94224ba62014-02-04 00:25:24187
Blink Reformat1c4d759e2017-04-09 16:34:54188 return browser_plugin_->Container();
[email protected]94224ba62014-02-04 00:25:24189}
190
vmpstre87ffcaa2016-08-23 21:01:14191void ChildFrameCompositingHelper::UpdateWebLayer(
192 std::unique_ptr<blink::WebLayer> layer) {
[email protected]94224ba62014-02-04 00:25:24193 if (GetContainer()) {
Blink Reformat1c4d759e2017-04-09 16:34:54194 GetContainer()->SetWebLayer(layer.get());
[email protected]94224ba62014-02-04 00:25:24195 } else if (frame_) {
Blink Reformat1c4d759e2017-04-09 16:34:54196 frame_->SetWebLayer(layer.get());
[email protected]bffc8302014-01-23 20:52:16197 }
vmpstre87ffcaa2016-08-23 21:01:14198 web_layer_ = std::move(layer);
[email protected]0f21e8582013-01-11 11:06:56199}
200
[email protected]bffc8302014-01-23 20:52:16201void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28202 const gfx::Size& new_size,
203 float device_scale_factor,
204 cc::Layer* layer) {
205 if (buffer_size_ != new_size) {
206 buffer_size_ = new_size;
207 // The container size is in DIP, so is the layer size.
208 // Buffer size is in physical pixels, so we need to adjust
209 // it by the device scale factor.
danakjddaec912015-09-25 19:38:40210 gfx::Size device_scale_adjusted_size =
211 gfx::ScaleToFlooredSize(buffer_size_, 1.0f / device_scale_factor);
[email protected]f5b4b0f2013-04-02 18:16:28212 layer->SetBounds(device_scale_adjusted_size);
213 }
214}
215
[email protected]bffc8302014-01-23 20:52:16216void ChildFrameCompositingHelper::OnContainerDestroy() {
lfgfd437a272015-11-24 21:24:53217 UpdateWebLayer(nullptr);
[email protected]0d25cb62013-01-21 15:42:21218}
219
[email protected]f49722f2014-01-30 17:54:50220void ChildFrameCompositingHelper::ChildFrameGone() {
lfgfd437a272015-11-24 21:24:53221 scoped_refptr<cc::SolidColorLayer> crashed_layer =
loyso0940d412016-03-14 01:30:31222 cc::SolidColorLayer::Create();
lfgfd437a272015-11-24 21:24:53223 crashed_layer->SetMasksToBounds(true);
lfgcccffbe2016-03-10 00:05:46224 crashed_layer->SetBackgroundColor(SK_ColorBLACK);
225
226 if (web_layer_) {
227 SkBitmap* sad_bitmap =
228 GetContentClient()->renderer()->GetSadWebViewBitmap();
Blink Reformat1c4d759e2017-04-09 16:34:54229 if (sad_bitmap && web_layer_->Bounds().width > sad_bitmap->width() &&
230 web_layer_->Bounds().height > sad_bitmap->height()) {
lfgcccffbe2016-03-10 00:05:46231 scoped_refptr<cc::PictureImageLayer> sad_layer =
loyso0940d412016-03-14 01:30:31232 cc::PictureImageLayer::Create();
vmpstr81a39a32017-05-16 19:30:21233 sad_layer->SetImage(cc::PaintImage(cc::PaintImage::kNonLazyStableId,
234 SkImage::MakeFromBitmap(*sad_bitmap)));
lfgcccffbe2016-03-10 00:05:46235 sad_layer->SetBounds(
236 gfx::Size(sad_bitmap->width(), sad_bitmap->height()));
237 sad_layer->SetPosition(gfx::PointF(
Blink Reformat1c4d759e2017-04-09 16:34:54238 (web_layer_->Bounds().width - sad_bitmap->width()) / 2,
239 (web_layer_->Bounds().height - sad_bitmap->height()) / 2));
lfgcccffbe2016-03-10 00:05:46240 sad_layer->SetIsDrawable(true);
241
242 crashed_layer->AddChild(sad_layer);
243 }
244 }
245
vmpstre87ffcaa2016-08-23 21:01:14246 std::unique_ptr<blink::WebLayer> layer(
247 new cc_blink::WebLayerImpl(crashed_layer));
248 UpdateWebLayer(std::move(layer));
[email protected]f49722f2014-01-30 17:54:50249}
250
kenrbfc7c02c92015-05-29 22:20:58251void ChildFrameCompositingHelper::OnSetSurface(
fsamuel96795522017-01-04 02:41:32252 const cc::SurfaceInfo& surface_info,
kenrbfc7c02c92015-05-29 22:20:58253 const cc::SurfaceSequence& sequence) {
fsamuel96795522017-01-04 02:41:32254 float scale_factor = surface_info.device_scale_factor();
255 surface_id_ = surface_info.id();
lfgfd437a272015-11-24 21:24:53256 scoped_refptr<cc::SurfaceLayer> surface_layer =
samans72b2a282016-12-17 02:44:15257 cc::SurfaceLayer::Create(surface_reference_factory_);
oshima9000e422016-01-27 03:05:36258 // TODO(oshima): This is a stopgap fix so that the compositor does not
259 // scaledown the content when 2x frame data is added to 1x parent frame data.
260 // Fix this in cc/.
261 if (IsUseZoomForDSFEnabled())
262 scale_factor = 1.0f;
fsamuel96795522017-01-04 02:41:32263
kenrb6ef29da2017-06-09 22:16:21264 // The RWHV creates a destruction dependency on the surface that needs to be
265 // satisfied. The reference factory will satisfy it when a new reference has
266 // been created.
267 if (render_frame_proxy_) {
268 static_cast<IframeSurfaceReferenceFactory*>(
269 surface_reference_factory_.get())
270 ->AddPendingSequence(sequence);
271 } else {
272 static_cast<BrowserPluginSurfaceReferenceFactory*>(
273 surface_reference_factory_.get())
274 ->AddPendingSequence(sequence);
275 }
276
fsamuelcc854aa52017-06-06 03:03:47277 cc::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor,
278 surface_info.size_in_pixels());
279 surface_layer->SetPrimarySurfaceInfo(modified_surface_info);
280 surface_layer->SetFallbackSurfaceInfo(modified_surface_info);
lfg042482c2016-01-21 03:53:55281 surface_layer->SetMasksToBounds(true);
vmpstre87ffcaa2016-08-23 21:01:14282 std::unique_ptr<cc_blink::WebLayerImpl> layer(
283 new cc_blink::WebLayerImpl(surface_layer));
lfg04c6bd602016-07-20 17:02:52284 // TODO(lfg): Investigate if it's possible to propagate the information about
285 // the child surface's opacity. https://crbug.com/629851.
Blink Reformat1c4d759e2017-04-09 16:34:54286 layer->SetOpaque(false);
lfg04c6bd602016-07-20 17:02:52287 layer->SetContentsOpaqueIsFixed(true);
vmpstre87ffcaa2016-08-23 21:01:14288 UpdateWebLayer(std::move(layer));
kenrbfc7c02c92015-05-29 22:20:58289
kenrbfc7c02c92015-05-29 22:20:58290 UpdateVisibility(true);
kenrbfc7c02c92015-05-29 22:20:58291
lfgfd437a272015-11-24 21:24:53292 CheckSizeAndAdjustLayerProperties(
fsamuel96795522017-01-04 02:41:32293 surface_info.size_in_pixels(), surface_info.device_scale_factor(),
lfgfd437a272015-11-24 21:24:53294 static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer());
kenrbfc7c02c92015-05-29 22:20:58295}
296
[email protected]bffc8302014-01-23 20:52:16297void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
lfgfd437a272015-11-24 21:24:53298 if (web_layer_)
Blink Reformat1c4d759e2017-04-09 16:34:54299 web_layer_->SetDrawsContent(visible);
[email protected]69b79122013-02-14 19:16:45300}
301
[email protected]0f21e8582013-01-11 11:06:56302} // namespace content