blob: 433d652175429289ea8c3b928d790aaf3c21f70e [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]09f67382013-10-09 21:03:457#include "cc/layers/delegated_frame_provider.h"
8#include "cc/layers/delegated_frame_resource_collection.h"
[email protected]f5b4b0f2013-04-02 18:16:289#include "cc/layers/delegated_renderer_layer.h"
[email protected]cc3cfaa2013-03-18 09:05:5210#include "cc/layers/solid_color_layer.h"
11#include "cc/layers/texture_layer.h"
[email protected]7f0d825f2013-03-18 07:24:3012#include "cc/output/context_provider.h"
[email protected]73405fb2013-12-11 04:59:3713#include "cc/output/copy_output_request.h"
14#include "cc/output/copy_output_result.h"
[email protected]9260757f2013-09-17 01:24:1615#include "cc/resources/single_release_callback.h"
[email protected]703dd662013-03-05 07:37:4216#include "content/common/browser_plugin/browser_plugin_messages.h"
[email protected]95d31822014-01-03 22:21:5517#include "content/common/frame_messages.h"
[email protected]a45c46e2013-03-07 01:04:4618#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]0d25cb62013-01-21 15:42:2119#include "content/renderer/browser_plugin/browser_plugin_manager.h"
[email protected]bffc8302014-01-23 20:52:1620#include "content/renderer/render_frame_impl.h"
[email protected]0f21e8582013-01-11 11:06:5621#include "content/renderer/render_thread_impl.h"
[email protected]73405fb2013-12-11 04:59:3722#include "skia/ext/image_operations.h"
[email protected]5c30b5e02013-05-30 03:46:0823#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
[email protected]bffc8302014-01-23 20:52:1624#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]2255a9332013-06-17 05:12:3125#include "third_party/WebKit/public/web/WebPluginContainer.h"
[email protected]7f0d825f2013-03-18 07:24:3026#include "third_party/khronos/GLES2/gl2.h"
[email protected]7e95a6d2013-03-04 23:31:3427#include "ui/gfx/size_conversions.h"
[email protected]73405fb2013-12-11 04:59:3728#include "ui/gfx/skia_util.h"
[email protected]799fd732013-05-15 21:18:5229#include "webkit/renderer/compositor_bindings/web_layer_impl.h"
[email protected]0f21e8582013-01-11 11:06:5630
31namespace content {
32
[email protected]bffc8302014-01-23 20:52:1633ChildFrameCompositingHelper::SwapBuffersInfo::SwapBuffersInfo()
[email protected]9f39c202013-06-18 16:06:4234 : route_id(0),
[email protected]53b4cc12013-07-18 23:02:3035 output_surface_id(0),
[email protected]9f39c202013-06-18 16:06:4236 host_id(0),
37 software_frame_id(0),
[email protected]bffc8302014-01-23 20:52:1638 shared_memory(NULL) {}
[email protected]9f39c202013-06-18 16:06:4239
[email protected]bffc8302014-01-23 20:52:1640ChildFrameCompositingHelper*
41ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin(
[email protected]180ef242013-11-07 06:50:4642 blink::WebPluginContainer* container,
[email protected]0d25cb62013-01-21 15:42:2143 BrowserPluginManager* manager,
[email protected]cc8ed212013-02-07 22:31:0344 int instance_id,
[email protected]bffc8302014-01-23 20:52:1645 int host_routing_id) {
46 return new ChildFrameCompositingHelper(
47 container, NULL, manager, NULL, instance_id, host_routing_id);
48}
49
50ChildFrameCompositingHelper*
51ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame(
52 blink::WebFrame* frame,
53 RenderFrameImpl* render_frame,
54 int host_routing_id) {
55 return new ChildFrameCompositingHelper(
56 NULL, frame, NULL, render_frame, 0, host_routing_id);
57}
58
59ChildFrameCompositingHelper::ChildFrameCompositingHelper(
60 blink::WebPluginContainer* container,
61 blink::WebFrame* frame,
62 BrowserPluginManager* manager,
63 RenderFrameImpl* render_frame,
64 int instance_id,
[email protected]0f21e8582013-01-11 11:06:5665 int host_routing_id)
[email protected]cc8ed212013-02-07 22:31:0366 : instance_id_(instance_id),
67 host_routing_id_(host_routing_id),
[email protected]f5b4b0f2013-04-02 18:16:2868 last_route_id_(0),
[email protected]53b4cc12013-07-18 23:02:3069 last_output_surface_id_(0),
[email protected]f5b4b0f2013-04-02 18:16:2870 last_host_id_(0),
[email protected]0f21e8582013-01-11 11:06:5671 last_mailbox_valid_(false),
[email protected]0d25cb62013-01-21 15:42:2172 ack_pending_(true),
[email protected]9afdaef2013-09-26 07:24:3773 software_ack_pending_(false),
[email protected]6d3a46e2013-11-25 23:08:5374 opaque_(true),
[email protected]0d25cb62013-01-21 15:42:2175 container_(container),
[email protected]bffc8302014-01-23 20:52:1676 frame_(frame),
77 browser_plugin_manager_(manager),
78 render_frame_(render_frame) {}
79
80ChildFrameCompositingHelper::~ChildFrameCompositingHelper() {}
81
82void ChildFrameCompositingHelper::SendCompositorFrameSwappedACKToBrowser(
83 FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
84 // This function will be removed when BrowserPluginManager is removed and
85 // BrowserPlugin is modified to use a RenderFrame.
86 if (browser_plugin_manager_) {
87 browser_plugin_manager_->Send(
88 new BrowserPluginHostMsg_CompositorFrameSwappedACK(
89 host_routing_id_, instance_id_, params));
90 } else {
91 DCHECK(render_frame_);
92 render_frame_->Send(
93 new FrameHostMsg_CompositorFrameSwappedACK(host_routing_id_, params));
94 }
[email protected]0f21e8582013-01-11 11:06:5695}
96
[email protected]bffc8302014-01-23 20:52:1697void ChildFrameCompositingHelper::SendBuffersSwappedACKToBrowser(
98 FrameHostMsg_BuffersSwappedACK_Params& params) {
99 // This function will be removed when BrowserPluginManager is removed and
100 // BrowserPlugin is modified to use a RenderFrame.
101 if (browser_plugin_manager_) {
102 browser_plugin_manager_->Send(new BrowserPluginHostMsg_BuffersSwappedACK(
103 host_routing_id_, instance_id_, params));
104 } else {
105 DCHECK(render_frame_);
106 render_frame_->Send(
107 new FrameHostMsg_BuffersSwappedACK(host_routing_id_, params));
108 }
[email protected]0f21e8582013-01-11 11:06:56109}
110
[email protected]bffc8302014-01-23 20:52:16111void ChildFrameCompositingHelper::SendReclaimCompositorResourcesToBrowser(
112 FrameHostMsg_ReclaimCompositorResources_Params& params) {
113 // This function will be removed when BrowserPluginManager is removed and
114 // BrowserPlugin is modified to use a RenderFrame.
115 if (browser_plugin_manager_) {
116 browser_plugin_manager_->Send(
117 new BrowserPluginHostMsg_ReclaimCompositorResources(
118 host_routing_id_, instance_id_, params));
119 } else {
120 DCHECK(render_frame_);
121 render_frame_->Send(
122 new FrameHostMsg_ReclaimCompositorResources(host_routing_id_, params));
123 }
124}
125
126void ChildFrameCompositingHelper::CopyFromCompositingSurface(
[email protected]73405fb2013-12-11 04:59:37127 int request_id,
128 gfx::Rect source_rect,
129 gfx::Size dest_size) {
130 CHECK(background_layer_);
131 scoped_ptr<cc::CopyOutputRequest> request =
132 cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
[email protected]bffc8302014-01-23 20:52:16133 &ChildFrameCompositingHelper::CopyFromCompositingSurfaceHasResult,
[email protected]73405fb2013-12-11 04:59:37134 this,
135 request_id,
136 dest_size));
137 request->set_area(source_rect);
138 background_layer_->RequestCopyOfOutput(request.Pass());
139}
140
[email protected]bffc8302014-01-23 20:52:16141void ChildFrameCompositingHelper::DidCommitCompositorFrame() {
[email protected]9afdaef2013-09-26 07:24:37142 if (software_ack_pending_) {
[email protected]95d31822014-01-03 22:21:55143 FrameHostMsg_CompositorFrameSwappedACK_Params params;
144 params.producing_host_id = last_host_id_;
145 params.producing_route_id = last_route_id_;
146 params.output_surface_id = last_output_surface_id_;
[email protected]9afdaef2013-09-26 07:24:37147 if (!unacked_software_frames_.empty()) {
[email protected]95d31822014-01-03 22:21:55148 params.ack.last_software_frame_id = unacked_software_frames_.back();
[email protected]9afdaef2013-09-26 07:24:37149 unacked_software_frames_.pop_back();
150 }
151
[email protected]bffc8302014-01-23 20:52:16152 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]9afdaef2013-09-26 07:24:37153
154 software_ack_pending_ = false;
155 }
[email protected]09f67382013-10-09 21:03:45156 if (!resource_collection_.get() || !ack_pending_)
[email protected]f5b4b0f2013-04-02 18:16:28157 return;
[email protected]396fbb72013-01-23 02:33:43158
[email protected]95d31822014-01-03 22:21:55159 FrameHostMsg_CompositorFrameSwappedACK_Params params;
160 params.producing_host_id = last_host_id_;
161 params.producing_route_id = last_route_id_;
162 params.output_surface_id = last_output_surface_id_;
163 resource_collection_->TakeUnusedResourcesForChildCompositor(
164 &params.ack.resources);
[email protected]f5b4b0f2013-04-02 18:16:28165
[email protected]bffc8302014-01-23 20:52:16166 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]f5b4b0f2013-04-02 18:16:28167
168 ack_pending_ = false;
169}
170
[email protected]bffc8302014-01-23 20:52:16171void ChildFrameCompositingHelper::EnableCompositing(bool enable) {
[email protected]fc72bb12013-06-02 21:13:46172 if (enable && !background_layer_.get()) {
[email protected]67be9b1d2013-03-08 02:27:45173 background_layer_ = cc::SolidColorLayer::Create();
[email protected]7aba6662013-03-12 10:17:34174 background_layer_->SetMasksToBounds(true);
175 background_layer_->SetBackgroundColor(
[email protected]396fbb72013-01-23 02:33:43176 SkColorSetARGBInline(255, 255, 255, 255));
[email protected]9af1a092013-03-18 12:16:34177 web_layer_.reset(new webkit::WebLayerImpl(background_layer_));
[email protected]0f21e8582013-01-11 11:06:56178 }
179
[email protected]bffc8302014-01-23 20:52:16180 if (container_) {
181 container_->setWebLayer(enable ? web_layer_.get() : NULL);
182 } else {
183 frame_->setRemoteWebLayer(enable ? web_layer_.get() : NULL);
184 }
[email protected]0f21e8582013-01-11 11:06:56185}
186
[email protected]bffc8302014-01-23 20:52:16187void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28188 const gfx::Size& new_size,
189 float device_scale_factor,
190 cc::Layer* layer) {
191 if (buffer_size_ != new_size) {
192 buffer_size_ = new_size;
193 // The container size is in DIP, so is the layer size.
194 // Buffer size is in physical pixels, so we need to adjust
195 // it by the device scale factor.
196 gfx::Size device_scale_adjusted_size = gfx::ToFlooredSize(
197 gfx::ScaleSize(buffer_size_, 1.0f / device_scale_factor));
198 layer->SetBounds(device_scale_adjusted_size);
199 }
[email protected]6d3a46e2013-11-25 23:08:53200
201 // Manually manage background layer for transparent webview.
202 if (!opaque_)
203 background_layer_->SetIsDrawable(false);
[email protected]f5b4b0f2013-04-02 18:16:28204}
205
[email protected]bffc8302014-01-23 20:52:16206void ChildFrameCompositingHelper::MailboxReleased(SwapBuffersInfo mailbox,
207 unsigned sync_point,
208 bool lost_resource) {
[email protected]9f39c202013-06-18 16:06:42209 if (mailbox.type == SOFTWARE_COMPOSITOR_FRAME) {
210 delete mailbox.shared_memory;
211 mailbox.shared_memory = NULL;
212 } else if (lost_resource) {
213 // Reset mailbox's name if the resource was lost.
214 mailbox.name.SetZero();
[email protected]7ba3ca72013-04-11 06:37:25215 }
216
[email protected]c049b2e2013-06-11 04:39:30217 // This means the GPU process crashed or guest crashed.
[email protected]53b4cc12013-07-18 23:02:30218 if (last_host_id_ != mailbox.host_id ||
219 last_output_surface_id_ != mailbox.output_surface_id ||
220 last_route_id_ != mailbox.route_id)
[email protected]4f7bbdc2013-01-29 02:31:39221 return;
222
[email protected]9afdaef2013-09-26 07:24:37223 if (mailbox.type == SOFTWARE_COMPOSITOR_FRAME)
224 unacked_software_frames_.push_back(mailbox.software_frame_id);
225
[email protected]c049b2e2013-06-11 04:39:30226 // We need to send an ACK to for every buffer sent to us.
227 // However, if a buffer is freed up from
[email protected]0d25cb62013-01-21 15:42:21228 // the compositor in cases like switching back to SW mode without a new
[email protected]c049b2e2013-06-11 04:39:30229 // buffer arriving, no ACK is needed.
[email protected]0d25cb62013-01-21 15:42:21230 if (!ack_pending_) {
[email protected]0d25cb62013-01-21 15:42:21231 last_mailbox_valid_ = false;
232 return;
233 }
234 ack_pending_ = false;
[email protected]c049b2e2013-06-11 04:39:30235 switch (mailbox.type) {
236 case TEXTURE_IMAGE_TRANSPORT: {
237 std::string mailbox_name(reinterpret_cast<const char*>(mailbox.name.name),
238 sizeof(mailbox.name.name));
[email protected]95d31822014-01-03 22:21:55239 FrameHostMsg_BuffersSwappedACK_Params params;
240 params.gpu_host_id = mailbox.host_id;
241 params.gpu_route_id = mailbox.route_id;
242 params.mailbox_name = mailbox_name;
243 params.sync_point = sync_point;
[email protected]bffc8302014-01-23 20:52:16244 SendBuffersSwappedACKToBrowser(params);
[email protected]c049b2e2013-06-11 04:39:30245 break;
246 }
[email protected]9f39c202013-06-18 16:06:42247 case GL_COMPOSITOR_FRAME: {
[email protected]95d31822014-01-03 22:21:55248 FrameHostMsg_CompositorFrameSwappedACK_Params params;
249 params.producing_host_id = mailbox.host_id;
250 params.producing_route_id = mailbox.route_id;
251 params.output_surface_id = mailbox.output_surface_id;
252 params.ack.gl_frame_data.reset(new cc::GLFrameData());
253 params.ack.gl_frame_data->mailbox = mailbox.name;
254 params.ack.gl_frame_data->size = mailbox.size;
255 params.ack.gl_frame_data->sync_point = sync_point;
[email protected]bffc8302014-01-23 20:52:16256 SendCompositorFrameSwappedACKToBrowser(params);
[email protected]c049b2e2013-06-11 04:39:30257 break;
258 }
[email protected]9afdaef2013-09-26 07:24:37259 case SOFTWARE_COMPOSITOR_FRAME:
[email protected]9f39c202013-06-18 16:06:42260 break;
[email protected]c049b2e2013-06-11 04:39:30261 }
[email protected]0d25cb62013-01-21 15:42:21262}
263
[email protected]bffc8302014-01-23 20:52:16264void ChildFrameCompositingHelper::OnContainerDestroy() {
[email protected]0d25cb62013-01-21 15:42:21265 if (container_)
266 container_->setWebLayer(NULL);
267 container_ = NULL;
268
[email protected]b0030b72013-11-15 20:35:53269 if (resource_collection_)
270 resource_collection_->SetClient(NULL);
271
[email protected]7873fe4e2013-11-14 18:35:22272 ack_pending_ = false;
273 software_ack_pending_ = false;
[email protected]b0030b72013-11-15 20:35:53274 resource_collection_ = NULL;
275 frame_provider_ = NULL;
[email protected]0d25cb62013-01-21 15:42:21276 texture_layer_ = NULL;
[email protected]f5b4b0f2013-04-02 18:16:28277 delegated_layer_ = NULL;
[email protected]396fbb72013-01-23 02:33:43278 background_layer_ = NULL;
[email protected]0d25cb62013-01-21 15:42:21279 web_layer_.reset();
280}
281
[email protected]f49722f2014-01-30 17:54:50282void ChildFrameCompositingHelper::ChildFrameGone() {
283 background_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 128, 0));
284 background_layer_->RemoveAllChildren();
285 background_layer_->SetIsDrawable(true);
286 background_layer_->SetContentsOpaque(true);
287}
288
[email protected]bffc8302014-01-23 20:52:16289void ChildFrameCompositingHelper::OnBuffersSwappedPrivate(
[email protected]9f39c202013-06-18 16:06:42290 const SwapBuffersInfo& mailbox,
[email protected]a11e5c22014-01-21 00:34:29291 unsigned sync_point,
[email protected]19fa81a02013-03-04 18:23:32292 float device_scale_factor) {
[email protected]fc72bb12013-06-02 21:13:46293 DCHECK(!delegated_layer_.get());
[email protected]4f7bbdc2013-01-29 02:31:39294 // If these mismatch, we are either just starting up, GPU process crashed or
295 // guest renderer crashed.
296 // In this case, we are communicating with a new image transport
297 // surface and must ACK with the new ID's and an empty mailbox.
[email protected]53b4cc12013-07-18 23:02:30298 if (last_route_id_ != mailbox.route_id ||
299 last_output_surface_id_ != mailbox.output_surface_id ||
300 last_host_id_ != mailbox.host_id)
[email protected]4f7bbdc2013-01-29 02:31:39301 last_mailbox_valid_ = false;
302
[email protected]c049b2e2013-06-11 04:39:30303 last_route_id_ = mailbox.route_id;
[email protected]53b4cc12013-07-18 23:02:30304 last_output_surface_id_ = mailbox.output_surface_id;
[email protected]c049b2e2013-06-11 04:39:30305 last_host_id_ = mailbox.host_id;
[email protected]4f7bbdc2013-01-29 02:31:39306
[email protected]0d25cb62013-01-21 15:42:21307 ack_pending_ = true;
308 // Browser plugin getting destroyed, do a fast ACK.
[email protected]fc72bb12013-06-02 21:13:46309 if (!background_layer_.get()) {
[email protected]c049b2e2013-06-11 04:39:30310 MailboxReleased(mailbox, sync_point, false);
[email protected]0d25cb62013-01-21 15:42:21311 return;
312 }
313
[email protected]fc72bb12013-06-02 21:13:46314 if (!texture_layer_.get()) {
[email protected]e8e4ae232013-04-12 00:26:01315 texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
[email protected]f5b4b0f2013-04-02 18:16:28316 texture_layer_->SetIsDrawable(true);
[email protected]6d3a46e2013-11-25 23:08:53317 SetContentsOpaque(opaque_);
[email protected]f5b4b0f2013-04-02 18:16:28318
319 background_layer_->AddChild(texture_layer_);
320 }
321
[email protected]0d25cb62013-01-21 15:42:21322 // The size of browser plugin container is not always equal to the size
323 // of the buffer that arrives here. This could be for a number of reasons,
324 // including autosize and a resize in progress.
325 // During resize, the container size changes first and then some time
326 // later, a new buffer with updated size will arrive. During this process,
327 // we need to make sure that things are still displayed pixel perfect.
[email protected]396fbb72013-01-23 02:33:43328 // We accomplish this by modifying bounds of the texture layer only
329 // when a new buffer arrives.
330 // Visually, this will either display a smaller part of the buffer
331 // or introduce a gutter around it.
[email protected]bffc8302014-01-23 20:52:16332 CheckSizeAndAdjustLayerProperties(
333 mailbox.size, device_scale_factor, texture_layer_.get());
[email protected]0f21e8582013-01-11 11:06:56334
[email protected]9f39c202013-06-18 16:06:42335 bool is_software_frame = mailbox.type == SOFTWARE_COMPOSITOR_FRAME;
[email protected]bffc8302014-01-23 20:52:16336 bool current_mailbox_valid = is_software_frame ? mailbox.shared_memory != NULL
337 : !mailbox.name.IsZero();
[email protected]9f39c202013-06-18 16:06:42338 if (!is_software_frame && !last_mailbox_valid_) {
339 SwapBuffersInfo empty_info = mailbox;
340 empty_info.name.SetZero();
[email protected]c049b2e2013-06-11 04:39:30341 MailboxReleased(empty_info, 0, false);
[email protected]0d25cb62013-01-21 15:42:21342 if (!current_mailbox_valid)
343 return;
344 }
[email protected]c2bfe4e2013-01-16 01:10:20345
[email protected]9f39c202013-06-18 16:06:42346 cc::TextureMailbox texture_mailbox;
[email protected]9260757f2013-09-17 01:24:16347 scoped_ptr<cc::SingleReleaseCallback> release_callback;
[email protected]c2bfe4e2013-01-16 01:10:20348 if (current_mailbox_valid) {
[email protected]bffc8302014-01-23 20:52:16349 release_callback =
350 cc::SingleReleaseCallback::Create(
351 base::Bind(&ChildFrameCompositingHelper::MailboxReleased,
352 scoped_refptr<ChildFrameCompositingHelper>(this),
353 mailbox)).Pass();
[email protected]a11e5c22014-01-21 00:34:29354 if (is_software_frame)
[email protected]9260757f2013-09-17 01:24:16355 texture_mailbox = cc::TextureMailbox(mailbox.shared_memory, mailbox.size);
[email protected]a11e5c22014-01-21 00:34:29356 else
357 texture_mailbox = cc::TextureMailbox(mailbox.name, sync_point);
[email protected]c2bfe4e2013-01-16 01:10:20358 }
[email protected]9f39c202013-06-18 16:06:42359
360 texture_layer_->SetFlipped(!is_software_frame);
[email protected]9260757f2013-09-17 01:24:16361 texture_layer_->SetTextureMailbox(texture_mailbox, release_callback.Pass());
[email protected]7aba6662013-03-12 10:17:34362 texture_layer_->SetNeedsDisplay();
[email protected]c2bfe4e2013-01-16 01:10:20363 last_mailbox_valid_ = current_mailbox_valid;
364}
365
[email protected]bffc8302014-01-23 20:52:16366void ChildFrameCompositingHelper::OnBuffersSwapped(
[email protected]c049b2e2013-06-11 04:39:30367 const gfx::Size& size,
368 const std::string& mailbox_name,
369 int gpu_route_id,
370 int gpu_host_id,
371 float device_scale_factor) {
[email protected]9f39c202013-06-18 16:06:42372 SwapBuffersInfo swap_info;
[email protected]c049b2e2013-06-11 04:39:30373 swap_info.name.SetName(reinterpret_cast<const int8*>(mailbox_name.data()));
374 swap_info.type = TEXTURE_IMAGE_TRANSPORT;
375 swap_info.size = size;
376 swap_info.route_id = gpu_route_id;
[email protected]53b4cc12013-07-18 23:02:30377 swap_info.output_surface_id = 0;
[email protected]c049b2e2013-06-11 04:39:30378 swap_info.host_id = gpu_host_id;
379 OnBuffersSwappedPrivate(swap_info, 0, device_scale_factor);
380}
381
[email protected]bffc8302014-01-23 20:52:16382void ChildFrameCompositingHelper::OnCompositorFrameSwapped(
[email protected]f5b4b0f2013-04-02 18:16:28383 scoped_ptr<cc::CompositorFrame> frame,
384 int route_id,
[email protected]53b4cc12013-07-18 23:02:30385 uint32 output_surface_id,
[email protected]f5b4b0f2013-04-02 18:16:28386 int host_id) {
[email protected]bffc8302014-01-23 20:52:16387
[email protected]c049b2e2013-06-11 04:39:30388 if (frame->gl_frame_data) {
[email protected]9f39c202013-06-18 16:06:42389 SwapBuffersInfo swap_info;
[email protected]c049b2e2013-06-11 04:39:30390 swap_info.name = frame->gl_frame_data->mailbox;
[email protected]9f39c202013-06-18 16:06:42391 swap_info.type = GL_COMPOSITOR_FRAME;
[email protected]c049b2e2013-06-11 04:39:30392 swap_info.size = frame->gl_frame_data->size;
393 swap_info.route_id = route_id;
[email protected]53b4cc12013-07-18 23:02:30394 swap_info.output_surface_id = output_surface_id;
[email protected]c049b2e2013-06-11 04:39:30395 swap_info.host_id = host_id;
396 OnBuffersSwappedPrivate(swap_info,
397 frame->gl_frame_data->sync_point,
398 frame->metadata.device_scale_factor);
399 return;
400 }
401
[email protected]9f39c202013-06-18 16:06:42402 if (frame->software_frame_data) {
403 cc::SoftwareFrameData* frame_data = frame->software_frame_data.get();
404
405 SwapBuffersInfo swap_info;
406 swap_info.type = SOFTWARE_COMPOSITOR_FRAME;
407 swap_info.size = frame_data->size;
408 swap_info.route_id = route_id;
[email protected]53b4cc12013-07-18 23:02:30409 swap_info.output_surface_id = output_surface_id;
[email protected]9f39c202013-06-18 16:06:42410 swap_info.host_id = host_id;
411 swap_info.software_frame_id = frame_data->id;
412
413 scoped_ptr<base::SharedMemory> shared_memory(
414 new base::SharedMemory(frame_data->handle, true));
415 const size_t size_in_bytes = 4 * frame_data->size.GetArea();
416 if (!shared_memory->Map(size_in_bytes)) {
[email protected]bffc8302014-01-23 20:52:16417 LOG(ERROR) << "Failed to map shared memory of size " << size_in_bytes;
[email protected]9f39c202013-06-18 16:06:42418 // Send ACK right away.
[email protected]9afdaef2013-09-26 07:24:37419 software_ack_pending_ = true;
[email protected]9f39c202013-06-18 16:06:42420 MailboxReleased(swap_info, 0, false);
[email protected]9afdaef2013-09-26 07:24:37421 DidCommitCompositorFrame();
[email protected]9f39c202013-06-18 16:06:42422 return;
423 }
424
425 swap_info.shared_memory = shared_memory.release();
[email protected]bffc8302014-01-23 20:52:16426 OnBuffersSwappedPrivate(swap_info, 0, frame->metadata.device_scale_factor);
[email protected]9afdaef2013-09-26 07:24:37427 software_ack_pending_ = true;
428 last_route_id_ = route_id;
429 last_output_surface_id_ = output_surface_id;
430 last_host_id_ = host_id;
[email protected]9f39c202013-06-18 16:06:42431 return;
432 }
433
[email protected]fc72bb12013-06-02 21:13:46434 DCHECK(!texture_layer_.get());
[email protected]f5b4b0f2013-04-02 18:16:28435
[email protected]09f67382013-10-09 21:03:45436 cc::DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
[email protected]b0030b72013-11-15 20:35:53437 // Do nothing if we are getting destroyed or have no frame data.
438 if (!frame_data || !background_layer_)
[email protected]f5b4b0f2013-04-02 18:16:28439 return;
440
[email protected]09f67382013-10-09 21:03:45441 DCHECK(!frame_data->render_pass_list.empty());
442 cc::RenderPass* root_pass = frame_data->render_pass_list.back();
443 gfx::Size frame_size = root_pass->output_rect.size();
444
[email protected]317f17d2013-11-09 05:03:48445 if (last_route_id_ != route_id ||
446 last_output_surface_id_ != output_surface_id ||
447 last_host_id_ != host_id) {
448 // Resource ids are scoped by the output surface.
449 // If the originating output surface doesn't match the last one, it
450 // indicates the guest's output surface may have been recreated, in which
451 // case we should recreate the DelegatedRendererLayer, to avoid matching
452 // resources from the old one with resources from the new one which would
453 // have the same id.
454 frame_provider_ = NULL;
455
456 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
457 // any resources from the old output surface with the new output surface id.
458 if (resource_collection_) {
[email protected]b0030b72013-11-15 20:35:53459 resource_collection_->SetClient(NULL);
460
461 if (resource_collection_->LoseAllResources())
462 SendReturnedDelegatedResources();
[email protected]317f17d2013-11-09 05:03:48463 resource_collection_ = NULL;
464 }
465 last_output_surface_id_ = output_surface_id;
466 last_route_id_ = route_id;
467 last_host_id_ = host_id;
468 }
[email protected]09f67382013-10-09 21:03:45469 if (!resource_collection_) {
470 resource_collection_ = new cc::DelegatedFrameResourceCollection;
[email protected]b0030b72013-11-15 20:35:53471 resource_collection_->SetClient(this);
[email protected]09f67382013-10-09 21:03:45472 }
473 if (!frame_provider_.get() || frame_provider_->frame_size() != frame_size) {
474 frame_provider_ = new cc::DelegatedFrameProvider(
475 resource_collection_.get(), frame->delegated_frame_data.Pass());
476 if (delegated_layer_.get())
477 delegated_layer_->RemoveFromParent();
478 delegated_layer_ =
[email protected]b59c1612013-12-04 00:56:49479 cc::DelegatedRendererLayer::Create(frame_provider_.get());
[email protected]09f67382013-10-09 21:03:45480 delegated_layer_->SetIsDrawable(true);
[email protected]6d3a46e2013-11-25 23:08:53481 SetContentsOpaque(opaque_);
[email protected]09f67382013-10-09 21:03:45482 background_layer_->AddChild(delegated_layer_);
483 } else {
484 frame_provider_->SetFrameData(frame->delegated_frame_data.Pass());
485 }
486
[email protected]6d3a46e2013-11-25 23:08:53487 CheckSizeAndAdjustLayerProperties(
[email protected]f5b4b0f2013-04-02 18:16:28488 frame_data->render_pass_list.back()->output_rect.size(),
489 frame->metadata.device_scale_factor,
490 delegated_layer_.get());
491
[email protected]f5b4b0f2013-04-02 18:16:28492 ack_pending_ = true;
493}
494
[email protected]bffc8302014-01-23 20:52:16495void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
[email protected]fc72bb12013-06-02 21:13:46496 if (texture_layer_.get())
[email protected]7aba6662013-03-12 10:17:34497 texture_layer_->SetIsDrawable(visible);
[email protected]fc72bb12013-06-02 21:13:46498 if (delegated_layer_.get())
[email protected]f5b4b0f2013-04-02 18:16:28499 delegated_layer_->SetIsDrawable(visible);
[email protected]69b79122013-02-14 19:16:45500}
501
[email protected]bffc8302014-01-23 20:52:16502void ChildFrameCompositingHelper::UnusedResourcesAreAvailable() {
[email protected]b0030b72013-11-15 20:35:53503 if (ack_pending_)
504 return;
505
506 SendReturnedDelegatedResources();
507}
508
[email protected]bffc8302014-01-23 20:52:16509void ChildFrameCompositingHelper::SendReturnedDelegatedResources() {
510 FrameHostMsg_ReclaimCompositorResources_Params params;
[email protected]b0030b72013-11-15 20:35:53511 if (resource_collection_)
[email protected]bffc8302014-01-23 20:52:16512 resource_collection_->TakeUnusedResourcesForChildCompositor(
513 &params.ack.resources);
514 DCHECK(!params.ack.resources.empty());
[email protected]b0030b72013-11-15 20:35:53515
[email protected]bffc8302014-01-23 20:52:16516 params.route_id = last_route_id_;
517 params.output_surface_id = last_output_surface_id_;
518 params.renderer_host_id = last_host_id_;
519 SendReclaimCompositorResourcesToBrowser(params);
[email protected]b0030b72013-11-15 20:35:53520}
521
[email protected]bffc8302014-01-23 20:52:16522void ChildFrameCompositingHelper::SetContentsOpaque(bool opaque) {
[email protected]6d3a46e2013-11-25 23:08:53523 opaque_ = opaque;
524
525 if (texture_layer_.get())
526 texture_layer_->SetContentsOpaque(opaque_);
527 if (delegated_layer_.get())
528 delegated_layer_->SetContentsOpaque(opaque_);
529}
530
[email protected]bffc8302014-01-23 20:52:16531void ChildFrameCompositingHelper::CopyFromCompositingSurfaceHasResult(
[email protected]73405fb2013-12-11 04:59:37532 int request_id,
533 gfx::Size dest_size,
534 scoped_ptr<cc::CopyOutputResult> result) {
535 scoped_ptr<SkBitmap> bitmap;
536 if (result && result->HasBitmap() && !result->size().IsEmpty())
537 bitmap = result->TakeBitmap();
538
539 SkBitmap resized_bitmap;
540 if (bitmap) {
[email protected]bffc8302014-01-23 20:52:16541 resized_bitmap =
542 skia::ImageOperations::Resize(*bitmap,
543 skia::ImageOperations::RESIZE_BEST,
544 dest_size.width(),
545 dest_size.height());
[email protected]73405fb2013-12-11 04:59:37546 }
547 browser_plugin_manager_->Send(
548 new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck(
[email protected]bffc8302014-01-23 20:52:16549 host_routing_id_, instance_id_, request_id, resized_bitmap));
[email protected]73405fb2013-12-11 04:59:37550}
551
[email protected]0f21e8582013-01-11 11:06:56552} // namespace content