Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/renderer/browser_plugin/browser_plugin_texture_provider.h" | |
| 6 | |
| 7 #include "base/message_loop.h" | |
| 8 #include "content/common/browser_plugin_messages.h" | |
| 9 #include "content/renderer/browser_plugin/browser_plugin_manager.h" | |
| 10 #include "content/renderer/browser_plugin/browser_plugin_manager_impl.h" | |
| 11 #include "content/renderer/render_view_impl.h" | |
| 12 #include "content/renderer/render_thread_impl.h" | |
| 13 | |
| 14 using WebKit::WebFloatRect; | |
| 15 | |
| 16 namespace { | |
| 17 bool MessageHasInstanceId(int instance_id, const IPC::Message& message) { | |
| 18 int message_instance; | |
| 19 DCHECK(!message.is_sync()); | |
| 20 PickleIterator iter(message); | |
| 21 // TODO(scshunt): is there a way to do this that doesn't rely on an int | |
| 22 // to work? | |
| 23 bool success = iter.ReadInt(&message_instance); | |
| 24 DCHECK(success); | |
| 25 return instance_id == message_instance; | |
| 26 } | |
| 27 } | |
| 28 | |
|
scshunt
2012/08/12 01:42:45
Explanation of the key sequences here would probab
| |
| 29 namespace content { | |
| 30 | |
| 31 // Called on main thread | |
| 32 BrowserPluginTextureProvider::BrowserPluginTextureProvider( | |
| 33 int instance_id, | |
| 34 RenderViewImpl* render_view) | |
| 35 : client_(0), | |
| 36 texture_id_(0), | |
| 37 filter_(0), | |
| 38 instance_id_(instance_id), | |
| 39 main_loop_( | |
| 40 RenderThreadImpl::current()->GetMessageLoop()->message_loop_proxy()), | |
| 41 channel_proxy_(RenderThread::Get()->GetChannel()), | |
| 42 render_view_(render_view) { | |
| 43 } | |
| 44 | |
| 45 // Called on impl thread if we have one, main thread otherwise | |
| 46 BrowserPluginTextureProvider::~BrowserPluginTextureProvider() { | |
| 47 #ifndef NDBEUG | |
| 48 // Destroy() ends our lifetime on the main thread, so this should | |
| 49 // not be in use. | |
| 50 bool locked = lock_.Try(); | |
| 51 DCHECK(locked); | |
| 52 lock_.Release(); | |
| 53 #endif | |
| 54 | |
| 55 if (client_) | |
| 56 client_->stopUsingProvider(); | |
| 57 channel_proxy_->RemoveFilter(filter_); | |
| 58 } | |
| 59 | |
| 60 // Called on the main thread; ends the lifetime on this thread | |
| 61 void BrowserPluginTextureProvider::Destroy() { | |
| 62 base::AutoLock scoped_lock(lock_); | |
| 63 | |
| 64 if (impl_loop_) | |
| 65 impl_loop_->PostTask(FROM_HERE, base::Bind( | |
| 66 &BrowserPluginTextureProvider::DestroyImpl, | |
| 67 base::Unretained(this))); | |
| 68 else | |
| 69 DestroyImpl(); | |
| 70 } | |
| 71 | |
| 72 // Called on impl thread if we have one, main thread otherwise | |
| 73 void BrowserPluginTextureProvider::DestroyImpl() { | |
| 74 delete this; | |
| 75 } | |
| 76 | |
| 77 // Called on impl thread (we store our impl thread loop here) | |
| 78 void BrowserPluginTextureProvider::setTextureProviderClient(Client* client) { | |
| 79 static const uint32 messages[] = { | |
| 80 BrowserPluginMsg_BuffersSwapped::ID, | |
| 81 BrowserPluginMsg_SurfaceResize::ID, | |
| 82 }; | |
| 83 | |
| 84 base::AutoLock scoped_lock(lock_); | |
| 85 | |
| 86 if (client_) { | |
| 87 client_->stopUsingProvider(); | |
| 88 } | |
| 89 | |
| 90 if (client) { | |
| 91 if (!impl_loop_) { | |
| 92 impl_loop_ = base::MessageLoopProxy::current(); | |
| 93 | |
| 94 filter_ = new IPC::ForwardingMessageFilter( | |
| 95 messages, | |
| 96 arraysize(messages), | |
| 97 impl_loop_, | |
| 98 base::Bind( | |
| 99 &BrowserPluginTextureProvider::OnMessageReceived, | |
| 100 base::Unretained(this))); | |
| 101 filter_->AddRoute(MSG_ROUTING_CONTROL); | |
| 102 filter_->SetPredicate(base::Bind(&MessageHasInstanceId, instance_id_)); | |
| 103 channel_proxy_->AddFilter(filter_); | |
| 104 main_loop_->PostTask(FROM_HERE, base::Bind( | |
| 105 &BrowserPluginTextureProvider::SignalReady, | |
| 106 instance_id_)); | |
| 107 } | |
| 108 // This is tautological if we took the above branch, but | |
| 109 // if we already had a loop, we want to verify that we should be | |
| 110 // on the same one. | |
| 111 DCHECK(impl_loop_ == base::MessageLoopProxy::current()); | |
| 112 | |
| 113 if (has_delayed_swap_) { | |
| 114 impl_loop_->PostTask(FROM_HERE, base::Bind( | |
| 115 &BrowserPluginTextureProvider::OnBuffersSwapped, | |
| 116 base::Unretained(this), | |
| 117 instance_id_, | |
| 118 texture_id_, | |
| 119 delayed_swap_info_)); | |
| 120 } | |
| 121 } else { | |
| 122 if (impl_loop_) { | |
| 123 channel_proxy_->RemoveFilter(filter_); | |
| 124 } | |
| 125 | |
| 126 impl_loop_ = 0; | |
| 127 } | |
| 128 | |
| 129 client_ = client; | |
| 130 } | |
| 131 | |
| 132 // Called on main thread | |
| 133 void BrowserPluginTextureProvider::SignalReady(int instance_id) { | |
| 134 BrowserPluginManagerImpl::Get()->TextureProviderIsReady(instance_id); | |
| 135 } | |
| 136 | |
| 137 // Called on impl thread | |
| 138 unsigned BrowserPluginTextureProvider::textureId() const { | |
| 139 return texture_id_; | |
| 140 } | |
| 141 | |
| 142 // Called on impl thread | |
| 143 bool BrowserPluginTextureProvider::premultipliedAlpha() const { | |
| 144 return true; | |
| 145 } | |
| 146 | |
| 147 // Called on impl thread | |
| 148 bool BrowserPluginTextureProvider::flipped() const { | |
| 149 return true; | |
| 150 } | |
| 151 | |
| 152 // Called on impl thread | |
| 153 WebFloatRect BrowserPluginTextureProvider::uvRect() const { | |
| 154 if (texture_size_.width() == 0 || texture_size_.height() == 0) | |
| 155 return WebFloatRect(0, 0, 1, 1); | |
| 156 | |
| 157 return WebFloatRect( | |
| 158 0, | |
| 159 0, | |
| 160 ((long double)(size_.width())) / texture_size_.width(), | |
| 161 ((long double)(size_.height())) / texture_size_.height()); | |
| 162 } | |
| 163 | |
| 164 // Called on impl thread | |
| 165 void BrowserPluginTextureProvider::OnMessageReceived( | |
| 166 const IPC::Message& message) { | |
| 167 IPC_BEGIN_MESSAGE_MAP(BrowserPluginTextureProvider, message) | |
| 168 IPC_MESSAGE_HANDLER(BrowserPluginMsg_BuffersSwapped, OnBuffersSwapped) | |
| 169 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SurfaceResize, OnSurfaceResize) | |
| 170 IPC_END_MESSAGE_MAP() | |
| 171 } | |
| 172 | |
| 173 // Called on impl thread | |
| 174 void BrowserPluginTextureProvider::OnBuffersSwapped( | |
| 175 int instance_id, | |
| 176 uint64 surface_handle, | |
| 177 const BrowserPlugin_SwapInfo& info) { | |
| 178 DCHECK(surface_handle != 0); | |
| 179 DCHECK(client_); | |
| 180 DCHECK(instance_id == instance_id_); | |
| 181 | |
| 182 texture_id_ = surface_handle; | |
| 183 client_->didReceiveFrame(); | |
| 184 channel_proxy_->Send(new BrowserPluginHostMsg_BuffersSwappedACK( | |
| 185 render_view_->GetRoutingID(), | |
| 186 info, | |
| 187 client_->insertSyncPoint())); | |
| 188 } | |
| 189 | |
| 190 // Called on impl thread | |
| 191 void BrowserPluginTextureProvider::OnSurfaceResize( | |
| 192 int instance_id, | |
| 193 const gfx::Size& size) { | |
| 194 DCHECK(instance_id == instance_id_); | |
| 195 texture_size_ = size; | |
| 196 } | |
| 197 | |
| 198 // Called on main thread prior to attaching client | |
| 199 void BrowserPluginTextureProvider::SurfaceResize(const gfx::Size& size) { | |
| 200 DCHECK(!client_); | |
| 201 DCHECK(!impl_loop_); | |
| 202 size_ = size; | |
| 203 } | |
| 204 | |
| 205 // Called on any thread | |
| 206 void BrowserPluginTextureProvider::Resize(const gfx::Size& size) { | |
| 207 base::AutoLock scoped_lock(lock_); | |
| 208 | |
| 209 if (impl_loop_) | |
| 210 impl_loop_->PostTask(FROM_HERE, base::Bind( | |
| 211 &BrowserPluginTextureProvider::ResizeImpl, | |
| 212 base::Unretained(this), | |
| 213 size)); | |
| 214 else | |
| 215 ResizeImpl(size); | |
| 216 } | |
| 217 | |
| 218 // Called on main thread | |
| 219 void BrowserPluginTextureProvider::SetDelayedSwap( | |
| 220 uint64 surface_handle, | |
| 221 const BrowserPlugin_SwapInfo& info) { | |
| 222 base::AutoLock scoped_lock(lock_); | |
| 223 | |
| 224 if (impl_loop_) { | |
| 225 impl_loop_->PostTask(FROM_HERE, base::Bind( | |
| 226 &BrowserPluginTextureProvider::OnBuffersSwapped, | |
| 227 base::Unretained(this), | |
| 228 instance_id_, | |
| 229 surface_handle, | |
| 230 info)); | |
| 231 } else { | |
| 232 has_delayed_swap_ = true; | |
| 233 delayed_swap_info_ = info; | |
| 234 texture_id_ = surface_handle; | |
| 235 // TODO(scshunt): Fix this | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 // Called on impl thread if we have one, otherwise main thread | |
| 240 void BrowserPluginTextureProvider::ResizeImpl(const gfx::Size& size) { | |
| 241 size_ = size; | |
| 242 } | |
| 243 | |
| 244 } // namespace content | |
| OLD | NEW |