Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 if (sync_point) | |
|
Fady Samuel
2013/01/18 18:57:01
This sync point represents when it's safe to consu
alexst (slow to review)
2013/01/18 19:15:42
Done.
| |
| 59 context->waitSyncPoint(sync_point); | |
| 60 | |
| 61 unsigned texture_id = context->createTexture(); | |
| 62 context->bindTexture(GL_TEXTURE_2D, texture_id); | |
| 63 context->consumeTextureCHROMIUM( | |
| 64 GL_TEXTURE_2D, | |
| 65 reinterpret_cast<const int8*>(mailbox_name.data())); | |
| 66 context->deleteTexture(texture_id); | |
| 67 } | |
| 68 | |
| 69 void BrowserPluginCompositingHelper::MailboxReleased( | |
| 70 const std::string& mailbox_name, | |
| 71 int gpu_route_id, | |
| 72 int gpu_host_id, | |
| 73 unsigned sync_point) { | |
| 74 // We need to send an ACK to TextureImageTransportSurface | |
| 75 // for every buffer it sends us. However, if a buffer is freed up from | |
| 76 // the compositor in cases like switching back to SW mode without a new | |
| 77 // buffer arriving, no ACK is needed and we destroy this buffer. | |
| 78 if (!ack_pending_) { | |
| 79 FreeMailboxMemory(mailbox_name, sync_point); | |
| 80 last_mailbox_valid_ = false; | |
| 81 return; | |
| 82 } | |
| 83 ack_pending_ = false; | |
| 84 browser_plugin_manager_->Send( | |
| 85 new BrowserPluginHostMsg_BuffersSwappedACK( | |
| 86 host_routing_id_, | |
| 87 gpu_route_id, | |
| 88 gpu_host_id, | |
| 89 mailbox_name, | |
| 90 sync_point)); | |
| 91 } | |
| 92 | |
| 93 void BrowserPluginCompositingHelper::OnContainerDestroy() { | |
| 94 if (container_) | |
| 95 container_->setWebLayer(NULL); | |
| 96 container_ = NULL; | |
| 97 | |
| 98 texture_layer_ = NULL; | |
| 99 web_layer_.reset(); | |
| 100 } | |
| 101 | |
| 50 void BrowserPluginCompositingHelper::OnBuffersSwapped( | 102 void BrowserPluginCompositingHelper::OnBuffersSwapped( |
| 51 const gfx::Size& size, | 103 const gfx::Size& size, |
| 52 const std::string& mailbox_name, | 104 const std::string& mailbox_name, |
| 53 int gpu_route_id, | 105 int gpu_route_id, |
| 54 int gpu_host_id) { | 106 int gpu_host_id) { |
| 107 ack_pending_ = true; | |
| 108 // Browser plugin getting destroyed, do a fast ACK. | |
| 109 if (!texture_layer_) { | |
| 110 MailboxReleased(mailbox_name, gpu_route_id, gpu_host_id, 0); | |
| 111 return; | |
| 112 } | |
| 113 | |
| 55 if (buffer_size_ != size) { | 114 if (buffer_size_ != size) { |
|
Fady Samuel
2013/01/18 18:57:01
I realize this is already upstream but could you p
alexst (slow to review)
2013/01/18 19:15:42
Done.
| |
| 56 buffer_size_ = size; | 115 buffer_size_ = size; |
| 57 UpdateUVRect(); | 116 UpdateUVRect(); |
| 58 } | 117 } |
| 59 if (!last_mailbox_valid_) | |
| 60 SendACK(std::string(), host_routing_id_, gpu_route_id, gpu_host_id, 0); | |
| 61 | 118 |
| 62 bool current_mailbox_valid = !mailbox_name.empty(); | 119 bool current_mailbox_valid = !mailbox_name.empty(); |
| 63 if (!current_mailbox_valid && !last_mailbox_valid_) | 120 if (!last_mailbox_valid_) { |
| 64 return; | 121 MailboxReleased(std::string(), gpu_route_id, gpu_host_id, 0); |
| 122 if (!current_mailbox_valid) | |
| 123 return; | |
| 124 } | |
| 65 | 125 |
| 66 cc::TextureLayer::MailboxCallback callback; | 126 cc::TextureLayer::MailboxCallback callback; |
| 67 if (current_mailbox_valid) { | 127 if (current_mailbox_valid) { |
| 68 callback = base::Bind(&SendACK, | 128 callback = base::Bind(&BrowserPluginCompositingHelper::MailboxReleased, |
| 129 scoped_refptr<BrowserPluginCompositingHelper>(this), | |
| 69 mailbox_name, | 130 mailbox_name, |
| 70 host_routing_id_, | |
| 71 gpu_route_id, | 131 gpu_route_id, |
| 72 gpu_host_id); | 132 gpu_host_id); |
| 73 } | 133 } |
| 134 | |
| 74 texture_layer_->setTextureMailbox(mailbox_name, callback); | 135 texture_layer_->setTextureMailbox(mailbox_name, callback); |
| 75 last_mailbox_valid_ = current_mailbox_valid; | 136 last_mailbox_valid_ = current_mailbox_valid; |
| 76 } | 137 } |
| 77 | 138 |
| 78 void BrowserPluginCompositingHelper::SetContainerSize(const gfx::Size& size) { | 139 void BrowserPluginCompositingHelper::SetContainerSize(const gfx::Size& size) { |
| 79 if (container_size_ == size) | 140 if (container_size_ == size) |
| 80 return; | 141 return; |
| 81 | 142 |
| 82 container_size_ = size; | 143 container_size_ = size; |
| 83 UpdateUVRect(); | 144 UpdateUVRect(); |
| 84 } | 145 } |
| 85 | 146 |
| 86 void BrowserPluginCompositingHelper::UpdateUVRect() { | 147 void BrowserPluginCompositingHelper::UpdateUVRect() { |
| 87 if (!texture_layer_) | 148 if (!texture_layer_) |
| 88 return; | 149 return; |
| 89 | 150 |
| 90 gfx::RectF uv_rect(0, 0, 1, 1); | 151 gfx::RectF uv_rect(0, 0, 1, 1); |
| 91 if (!buffer_size_.IsEmpty() && !container_size_.IsEmpty()) { | 152 if (!buffer_size_.IsEmpty() && !container_size_.IsEmpty()) { |
| 92 uv_rect.set_width(static_cast<float>(container_size_.width()) / | 153 uv_rect.set_width(static_cast<float>(container_size_.width()) / |
| 93 static_cast<float>(buffer_size_.width())); | 154 static_cast<float>(buffer_size_.width())); |
| 94 uv_rect.set_height(static_cast<float>(container_size_.height()) / | 155 uv_rect.set_height(static_cast<float>(container_size_.height()) / |
| 95 static_cast<float>(buffer_size_.height())); | 156 static_cast<float>(buffer_size_.height())); |
| 96 } | 157 } |
| 97 texture_layer_->setUVRect(uv_rect); | 158 texture_layer_->setUVRect(uv_rect); |
| 98 } | 159 } |
| 99 | 160 |
| 100 } // namespace content | 161 } // namespace content |
| OLD | NEW |