Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: content/renderer/browser_plugin/browser_plugin_compositing_helper.cc

Issue 11967013: Fixes issues when switching between software and compositing. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h" 5 #include "content/renderer/browser_plugin/browser_plugin_compositing_helper.h"
6 6
7 #include "cc/texture_layer.h" 7 #include "cc/texture_layer.h"
8 #include "content/common/browser_plugin_messages.h" 8 #include "content/common/browser_plugin_messages.h"
9 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
9 #include "content/renderer/render_thread_impl.h" 10 #include "content/renderer/render_thread_impl.h"
11 #include "third_party/khronos/GLES2/gl2.h"
12 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h"
13 #include "third_party/WebKit/Source/Platform/chromium/public/WebSharedGraphicsCo ntext3D.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
11 #include "webkit/compositor_bindings/web_layer_impl.h" 15 #include "webkit/compositor_bindings/web_layer_impl.h"
12 16
13 namespace content { 17 namespace content {
14 18
15 static void SendACK(const std::string& mailbox_name,
16 int host_route_id,
17 int gpu_route_id,
18 int gpu_host_id,
19 unsigned sync_point) {
20 RenderThread::Get()->Send(
21 new BrowserPluginHostMsg_BuffersSwappedACK(
22 host_route_id,
23 gpu_route_id,
24 gpu_host_id,
25 mailbox_name,
26 sync_point));
27 }
28
29 BrowserPluginCompositingHelper::BrowserPluginCompositingHelper( 19 BrowserPluginCompositingHelper::BrowserPluginCompositingHelper(
30 WebKit::WebPluginContainer* container, 20 WebKit::WebPluginContainer* container,
21 BrowserPluginManager* manager,
31 int host_routing_id) 22 int host_routing_id)
32 : host_routing_id_(host_routing_id), 23 : host_routing_id_(host_routing_id),
33 last_mailbox_valid_(false), 24 last_mailbox_valid_(false),
34 container_(container) { 25 ack_pending_(true),
26 container_(container),
27 browser_plugin_manager_(manager) {
35 } 28 }
36 29
37 BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() { 30 BrowserPluginCompositingHelper::~BrowserPluginCompositingHelper() {
38 container_->setWebLayer(NULL);
39 } 31 }
40 32
41 void BrowserPluginCompositingHelper::EnableCompositing(bool enable) { 33 void BrowserPluginCompositingHelper::EnableCompositing(bool enable) {
42 if (enable && !texture_layer_) { 34 if (enable && !texture_layer_) {
43 texture_layer_ = cc::TextureLayer::createForMailbox(); 35 texture_layer_ = cc::TextureLayer::createForMailbox();
44 web_layer_.reset(new WebKit::WebLayerImpl(texture_layer_)); 36 web_layer_.reset(new WebKit::WebLayerImpl(texture_layer_));
45 } 37 }
46 38
47 container_->setWebLayer(enable ? web_layer_.get() : NULL); 39 container_->setWebLayer(enable ? web_layer_.get() : NULL);
48 } 40 }
49 41
42 // If we have a mailbox that was freed up from the compositor,
43 // but we are not expected to return it to the guest renderer
44 // via an ACK, we should free it because we now own it.
45 // To free the mailbox memory, we need a context to consume it
46 // into a texture ID and then delete this texture ID.
47 // We use a shared graphics context accessible from the main
48 // thread to do it.
49 void BrowserPluginCompositingHelper::FreeMailboxMemory(
50 const std::string& mailbox_name,
51 unsigned sync_point) {
52 if (mailbox_name.empty())
53 return;
54
55 WebKit::WebGraphicsContext3D *context =
56 WebKit::WebSharedGraphicsContext3D::mainThreadContext();
57 DCHECK(context);
58 // When a buffer is released from the compositor, we also get a
59 // sync point that specifies when in the command buffer
60 // it's safe to use it again.
61 // If the sync point is non-zero, we need to tell our context
62 // to wait until this sync point is reached before we can safely
63 // delete the buffer.
64 if (sync_point)
65 context->waitSyncPoint(sync_point);
66
67 unsigned texture_id = context->createTexture();
68 context->bindTexture(GL_TEXTURE_2D, texture_id);
69 context->consumeTextureCHROMIUM(
70 GL_TEXTURE_2D,
71 reinterpret_cast<const int8*>(mailbox_name.data()));
72 context->deleteTexture(texture_id);
73 }
74
75 void BrowserPluginCompositingHelper::MailboxReleased(
76 const std::string& mailbox_name,
77 int gpu_route_id,
78 int gpu_host_id,
79 unsigned sync_point) {
80 // We need to send an ACK to TextureImageTransportSurface
81 // for every buffer it sends us. However, if a buffer is freed up from
82 // the compositor in cases like switching back to SW mode without a new
83 // buffer arriving, no ACK is needed and we destroy this buffer.
84 if (!ack_pending_) {
85 FreeMailboxMemory(mailbox_name, sync_point);
86 last_mailbox_valid_ = false;
87 return;
88 }
89 ack_pending_ = false;
90 browser_plugin_manager_->Send(
91 new BrowserPluginHostMsg_BuffersSwappedACK(
92 host_routing_id_,
93 gpu_route_id,
94 gpu_host_id,
95 mailbox_name,
96 sync_point));
97 }
98
99 void BrowserPluginCompositingHelper::OnContainerDestroy() {
100 if (container_)
101 container_->setWebLayer(NULL);
102 container_ = NULL;
103
104 texture_layer_ = NULL;
105 web_layer_.reset();
106 }
107
50 void BrowserPluginCompositingHelper::OnBuffersSwapped( 108 void BrowserPluginCompositingHelper::OnBuffersSwapped(
51 const gfx::Size& size, 109 const gfx::Size& size,
52 const std::string& mailbox_name, 110 const std::string& mailbox_name,
53 int gpu_route_id, 111 int gpu_route_id,
54 int gpu_host_id) { 112 int gpu_host_id) {
113 ack_pending_ = true;
114 // Browser plugin getting destroyed, do a fast ACK.
115 if (!texture_layer_) {
116 MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0);
117 return;
118 }
119
120 // The size of browser plugin container is not always equal to the size
121 // of the buffer that arrives here. This could be for a number of reasons,
122 // including autosize and a resize in process.
Fady Samuel 2013/01/18 20:07:47 ..in progress.
123 // During resize, the container size changes first and then some time
124 // later, a new buffer with updated size will arrive. During this process
Fady Samuel 2013/01/18 20:07:47 During this process,
125 // we need to make sure that things are still displayed pixel perfect.
126 // We accoplish this by modifying texture coordinates in the layer,
Fady Samuel 2013/01/18 20:07:47 We accomplish
127 // and either buffer size or container size change triggers the need
128 // to also update texture coordinates.
Fady Samuel 2013/01/18 20:07:47 What does this do visually? This is for gutter rig
55 if (buffer_size_ != size) { 129 if (buffer_size_ != size) {
56 buffer_size_ = size; 130 buffer_size_ = size;
57 UpdateUVRect(); 131 UpdateUVRect();
58 } 132 }
59 if (!last_mailbox_valid_)
60 SendACK(std::string(), host_routing_id_, gpu_route_id, gpu_host_id, 0);
61 133
62 bool current_mailbox_valid = !mailbox_name.empty(); 134 bool current_mailbox_valid = !mailbox_name.empty();
63 if (!current_mailbox_valid && !last_mailbox_valid_) 135 if (!last_mailbox_valid_) {
64 return; 136 MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0);
137 if (!current_mailbox_valid)
138 return;
139 }
65 140
66 cc::TextureLayer::MailboxCallback callback; 141 cc::TextureLayer::MailboxCallback callback;
67 if (current_mailbox_valid) { 142 if (current_mailbox_valid) {
68 callback = base::Bind(&SendACK, 143 callback = base::Bind(&BrowserPluginCompositingHelper::MailboxReleased,
144 scoped_refptr<BrowserPluginCompositingHelper>(this),
69 mailbox_name, 145 mailbox_name,
70 host_routing_id_,
71 gpu_route_id, 146 gpu_route_id,
72 gpu_host_id); 147 gpu_host_id);
73 } 148 }
149
74 texture_layer_->setTextureMailbox(mailbox_name, callback); 150 texture_layer_->setTextureMailbox(mailbox_name, callback);
75 last_mailbox_valid_ = current_mailbox_valid; 151 last_mailbox_valid_ = current_mailbox_valid;
76 } 152 }
77 153
78 void BrowserPluginCompositingHelper::SetContainerSize(const gfx::Size& size) { 154 void BrowserPluginCompositingHelper::SetContainerSize(const gfx::Size& size) {
79 if (container_size_ == size) 155 if (container_size_ == size)
80 return; 156 return;
81 157
82 container_size_ = size; 158 container_size_ = size;
83 UpdateUVRect(); 159 UpdateUVRect();
84 } 160 }
85 161
86 void BrowserPluginCompositingHelper::UpdateUVRect() { 162 void BrowserPluginCompositingHelper::UpdateUVRect() {
87 if (!texture_layer_) 163 if (!texture_layer_)
88 return; 164 return;
89 165
90 gfx::RectF uv_rect(0, 0, 1, 1); 166 gfx::RectF uv_rect(0, 0, 1, 1);
91 if (!buffer_size_.IsEmpty() && !container_size_.IsEmpty()) { 167 if (!buffer_size_.IsEmpty() && !container_size_.IsEmpty()) {
92 uv_rect.set_width(static_cast<float>(container_size_.width()) / 168 uv_rect.set_width(static_cast<float>(container_size_.width()) /
93 static_cast<float>(buffer_size_.width())); 169 static_cast<float>(buffer_size_.width()));
94 uv_rect.set_height(static_cast<float>(container_size_.height()) / 170 uv_rect.set_height(static_cast<float>(container_size_.height()) /
95 static_cast<float>(buffer_size_.height())); 171 static_cast<float>(buffer_size_.height()));
96 } 172 }
97 texture_layer_->setUVRect(uv_rect); 173 texture_layer_->setUVRect(uv_rect);
98 } 174 }
99 175
100 } // namespace content 176 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698