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

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

Issue 10735010: 3D Compositing in <browser>, first draft. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Major changes to clean up deadlock & other issues Created 8 years, 4 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
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698