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

Side by Side Diff: Source/core/html/canvas/WebGLSharedObject.cpp

Issue 17230006: Implement WEBGL_shared_resources Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "config.h" 26 #include "config.h"
27 27
28 #include "core/html/canvas/WebGLSharedObject.h" 28 #include "core/html/canvas/WebGLSharedObject.h"
29 29
30 #include "core/html/canvas/WebGLAcquireSharedResourceCallback.h"
30 #include "core/html/canvas/WebGLContextGroup.h" 31 #include "core/html/canvas/WebGLContextGroup.h"
31 #include "core/html/canvas/WebGLRenderingContext.h" 32 #include "core/html/canvas/WebGLRenderingContext.h"
32 33
33 namespace WebCore { 34 namespace WebCore {
34 35
35 WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context) 36 WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
36 : WebGLObject(context), 37 : WebGLObject(context)
37 m_contextGroup(context->contextGroup()) 38 , m_contextGroup(context->contextGroup())
39 , m_acquireMode(WebGLSharedObject::Unacquired)
38 { 40 {
41 bool success = acquire(WebGLSharedObject::Exclusive, context);
42 ASSERT(success);
43
44 // We need to mark shaders and programs as bound as there is no way to easy way to bind/attach them.
45 markAsBoundSinceLastAcquireForContext(context);
39 } 46 }
40 47
41 WebGLSharedObject::~WebGLSharedObject() 48 WebGLSharedObject::~WebGLSharedObject()
42 { 49 {
43 if (m_contextGroup) 50 if (m_contextGroup) {
44 m_contextGroup->removeObject(this); 51 m_contextGroup->removeObject(this);
52 }
45 } 53 }
46 54
47 void WebGLSharedObject::detachContextGroup() 55 void WebGLSharedObject::detachContextGroup()
48 { 56 {
49 detach(); 57 detach();
50 if (m_contextGroup) { 58 if (m_contextGroup) {
51 deleteObject(0); 59 deleteObject(0);
52 m_contextGroup->removeObject(this); 60 m_contextGroup->removeObject(this);
53 m_contextGroup = 0; 61 m_contextGroup = 0;
54 } 62 }
55 } 63 }
56 64
57 GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const 65 GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const
58 { 66 {
59 return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0; 67 return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0;
60 } 68 }
61 69
62 } 70 bool WebGLSharedObject::isAcquiredForContext(const WebGLRenderingContext* contex t, WebGLSharedObject::AcquireMode neededMode, bool mustBeBoundSinceLastAcquire, bool* hasBeenBoundSinceLastAcquire, const char** reason) const
71 {
72 AcquireContextMap::const_iterator it = m_acquireContextMap.find(context);
73 if (it == m_acquireContextMap.end()) {
74 *reason = " not acquired in this context";
75 return false;
76 }
77
78 bool sameMode = m_acquireMode == neededMode;
79 bool validCombo = m_acquireMode == WebGLSharedObject::Exclusive && neededMod e == WebGLSharedObject::ReadOnly;
80 if (!sameMode && !validCombo) {
81 *reason = " not acquired for exclusive access";
82 return false;
83 }
84
85 if (mustBeBoundSinceLastAcquire && !it->value) {
86 *reason = " has not been bound since last acquired";
87 return false;
88 }
89
90 if (hasBeenBoundSinceLastAcquire) {
91 *hasBeenBoundSinceLastAcquire = it->value;
92 }
93
94 return true;
95 }
96
97 bool WebGLSharedObject::validate(const char* functionName, WebGLRenderingContext * context, WebGLSharedObject::AcquireMode neededMode, bool mustBeBoundSinceLastA cquire, bool* boundSinceLastAcquire) const
98 {
99 if (context->contextGroup() != m_contextGroup) {
100 String msg(String(typeName()) + " not from this share group");
101 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functio nName, msg.utf8().data());
102 return false;
103 }
104
105 const char* reason;
106 if (!isAcquiredForContext(context, neededMode, mustBeBoundSinceLastAcquire, boundSinceLastAcquire, &reason)) {
107 String msg(String(typeName()) + reason);
108 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functio nName, msg.utf8().data());
109 return false;
110 }
111
112 return true;
113 }
114
115 void WebGLSharedObject::markAsBoundSinceLastAcquireForContext(const WebGLRenderi ngContext* context)
116 {
117 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
118 ASSERT(it != m_acquireContextMap.end());
119 it->value = true;
120 }
121
122 bool WebGLSharedObject::acquire(WebGLSharedObject::AcquireMode desiredMode, cons t WebGLRenderingContext* context)
123 {
124 AcquireContextMap::const_iterator it = m_acquireContextMap.find(context);
125 if (it != m_acquireContextMap.end()) {
126 // How can I get here?
127 return false;
128 }
129
130 bool unacquired = m_acquireMode == WebGLSharedObject::Unacquired;
131 bool bothReadOnly = m_acquireMode == WebGLSharedObject::ReadOnly && desiredM ode == WebGLSharedObject::ReadOnly;
132 if (!unacquired && !bothReadOnly) {
133 return false;
134 }
135
136 // Note: The resource is acquired at this point. The user may still cancel
137 // the request though before it the acquire callback is fired. If it is
138 // cancelled the cancel acts as a call to release.
139 m_acquireMode = desiredMode;
140 m_acquireContextMap.add(context, false);
141 return true;
142 }
143
144 bool WebGLSharedObject::addAcquireRequest(WebGLRenderingContext* context, WebGLS haredObject::AcquireMode desiredMode, PassRefPtr<WebGLAcquireSharedResourceCallb ack> callback, long& id)
145 {
146 switch (desiredMode) {
147 case WebGLSharedObject::ReadOnly:
148 case WebGLSharedObject::Exclusive:
149 break;
150 default:
151 context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "acquireShar edResource", "mode is not READ_ONLY or EXCLUSIVE");
152 return false;
153 }
154
155 // Checks the object belongs to this group.
156 // Note: We let lost objects go through here.
157 if (context->contextGroup() != m_contextGroup && !isLost()) {
158 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "object is not from this ShareGroup");
159 return false;
160 }
161
162 // Checks it is not already acquired by this context.
163 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
164 if (it != m_acquireContextMap.end()) {
165 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "object is already acquired in this context");
166 return false;
167 }
168
169 // Checks it is not already in one of the queues.
170 if (isRequestPending(context)) {
171 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "request to acquire this object is already pending in this con text");
172 return false;
173 }
174
175 // Adds the request.
176 id = generateAcquireRequestId();
177 m_acquireRequestQueue.append(WebGLAcquireSharedResourceRequest::create(this, callback, desiredMode, context, id));
178 processAcquireRequests();
179 return true;
180 }
181
182 bool WebGLSharedObject::release(WebGLRenderingContext* context)
183 {
184 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
185 if (it == m_acquireContextMap.end()) {
186 return false;
187 }
188
189 m_acquireContextMap.remove(it);
190 if (m_acquireContextMap.isEmpty()) {
191 if (m_acquireMode == WebGLSharedObject::Exclusive) {
192 // TODO: Use flush if on top of virtual contexts (maybe we should ha ve an extension GL_CHROMIUM_flush_sync to mark that only flush is needed)
193 // Use sync objects/fences if available.
194 // Use glFinish otherwise.
195 context->flush(); // Using flush for now. So far only certain Androi d devices need a finish.
196 }
197 m_acquireMode = WebGLSharedObject::Unacquired;
198 processAcquireRequests();
199 }
200
201 return true;
202 }
203
204 void WebGLSharedObject::processAcquireRequests()
205 {
206 // Queue all the events that could succeed right now.
207 while (!m_acquireRequestQueue.isEmpty()) {
208 RefPtr<WebGLAcquireSharedResourceRequest> request = m_acquireRequestQueu e.first();
209 if (!acquire(request->acquireMode(), request->context())) {
210 break;
211 }
212
213 m_acquireRequestQueue.removeFirst();
214 m_acquireRequestPostedList.append(request);
215
216 // queue event
217 ScriptExecutionContext* scriptExecutionContext = request->context()->scr iptExecutionContext();
218 if (scriptExecutionContext) {
219 scriptExecutionContext->postTask(adoptPtr(new DispatchCallbackTask(r equest)));
220 }
221 }
222 }
223
224 bool WebGLSharedObject::isRequestPending(const WebGLRenderingContext* context)
225 {
226 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); it != m_acquireRequestQueue.end(); ++it) {
227 if ((*it)->context() == context) {
228 return true;
229 }
230 }
231 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
232 if ((*it)->context() == context) {
233 return true;
234 }
235 }
236 return false;
237 }
238
239 bool WebGLSharedObject::cancelAcquireRequest(const WebGLRenderingContext* contex t, long id)
240 {
241 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); it != m_acquireRequestQueue.end(); ++it) {
242 if ((*it)->id() == id) {
243 // Only remove it if it's from this context.
244 if ((*it)->context() == context) {
245 (*it)->cancel();
246 m_acquireRequestQueue.remove(it);
247 processAcquireRequests();
248 }
249 return true;
250 }
251 }
252 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
253 if ((*it)->id() == id) {
254 // Only remove it if it's from this context.
255 if ((*it)->context() == context) {
256 (*it)->cancel();
257 m_acquireRequestPostedList.remove(it);
258 processAcquireRequests();
259 }
260 return true;
261 }
262 }
263 return false;
264 }
265
266 void WebGLSharedObject::cancelAllPendingRequestsForContext(const WebGLRenderingC ontext* context)
267 {
268 bool done = false;
269 while (!done) {
270 done = true;
271 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); i t != m_acquireRequestQueue.end(); ++it) {
272 if ((*it)->context() == context) {
273 cancelAcquireRequest(context, (*it)->id());
274 done = false;
275 break;
276 }
277 }
278 }
279
280 done = false;
281 while (!done) {
282 done = true;
283 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin( ); it != m_acquireRequestPostedList.end(); ++it) {
284 if ((*it)->context() == context) {
285 cancelAcquireRequest(context, (*it)->id());
286 done = false;
287 break;
288 }
289 }
290 }
291 }
292
293 void WebGLSharedObject::removePostedAcquireRequest(const WebGLRenderingContext* context, long id)
294 {
295 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
296 if ((*it)->id() == id) {
297 ASSERT((*it)->context() == context);
298 m_acquireRequestPostedList.remove(it);
299 return;
300 }
301 }
302 ASSERT(false); // should never get here.
303 }
304
305 int WebGLSharedObject::generateAcquireRequestId()
306 {
307 AtomicallyInitializedStatic(int, acquireRequestId = 0);
308 return atomicIncrement(&acquireRequestId);
309 }
310
311 WebGLSharedObject::DispatchCallbackTask::~DispatchCallbackTask()
312 {
313 }
314
315 void WebGLSharedObject::DispatchCallbackTask::performTask(ScriptExecutionContext *)
316 {
317 m_request->run();
318 }
319
320 WebGLAcquireSharedResourceRequest::WebGLAcquireSharedResourceRequest(PassRefPtr< WebGLSharedObject> sharedObject, PassRefPtr<WebGLAcquireSharedResourceCallback> callback, WebGLSharedObject::AcquireMode acquireMode, WebGLRenderingContext* con text, long id)
321 : m_sharedObject(sharedObject)
322 , m_context(context)
323 , m_id(id)
324 , m_acquireMode(acquireMode)
325 , m_callback(callback)
326 {
327 }
328
329 WebGLAcquireSharedResourceRequest::~WebGLAcquireSharedResourceRequest()
330 {
331 }
332
333 PassRefPtr<WebGLAcquireSharedResourceRequest> WebGLAcquireSharedResourceRequest: :create(PassRefPtr<WebGLSharedObject> sharedObject, PassRefPtr<WebGLAcquireShare dResourceCallback> callback, WebGLSharedObject::AcquireMode acquireMode, WebGLRe nderingContext* context, long id)
334 {
335 return adoptRef(new WebGLAcquireSharedResourceRequest(sharedObject, callback , acquireMode, context, id));
336 }
337
338 void WebGLAcquireSharedResourceRequest::cancel()
339 {
340 m_acquireMode = WebGLSharedObject::Unacquired;
341 m_callback.clear();
342 }
343
344 void WebGLAcquireSharedResourceRequest::run()
345 {
346 if (m_callback) {
347 RefPtr<WebGLAcquireSharedResourceRequest> self(this); // Need to keep a reference to ourselves as the next line may remove our last reference.
348 m_sharedObject->removePostedAcquireRequest(context(), id());
349 m_callback->handleEvent();
350 m_callback.clear();
351 }
352 }
353
354 } // namespace WebCore
355
OLDNEW
« no previous file with comments | « Source/core/html/canvas/WebGLSharedObject.h ('k') | Source/core/html/canvas/WebGLSharedObject.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698