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

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
36 bool WebGLSharedObject::IntToAcquireMode(unsigned value, AcquireMode* mode)
37 {
38 switch (value) {
39 case 0:
40 *mode = WebGLSharedObject::Unacquired;
41 return true;
42 case 1:
43 *mode = WebGLSharedObject::ReadOnly;
44 return true;
45 case 4:
46 *mode = WebGLSharedObject::Exclusive;
47 return true;
48 default:
49 return false;
50 }
51 }
52
35 WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context) 53 WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
36 : WebGLObject(context), 54 : WebGLObject(context)
37 m_contextGroup(context->contextGroup()) 55 , m_contextGroup(context->contextGroup())
56 , m_acquireMode(WebGLSharedObject::Unacquired)
38 { 57 {
58 acquire(WebGLSharedObject::Exclusive, context);
59
60 // We need to mark shaders and programs as bound as there is no way to easy way to bind/attach them.
61 markAsBoundSinceLastAcquireForContext(context);
39 } 62 }
40 63
41 WebGLSharedObject::~WebGLSharedObject() 64 WebGLSharedObject::~WebGLSharedObject()
42 { 65 {
43 if (m_contextGroup) 66 if (m_contextGroup) {
44 m_contextGroup->removeObject(this); 67 m_contextGroup->removeObject(this);
68 }
45 } 69 }
46 70
47 void WebGLSharedObject::detachContextGroup() 71 void WebGLSharedObject::detachContextGroup()
48 { 72 {
49 detach(); 73 detach();
50 if (m_contextGroup) { 74 if (m_contextGroup) {
51 deleteObject(0); 75 deleteObject(0);
52 m_contextGroup->removeObject(this); 76 m_contextGroup->removeObject(this);
53 m_contextGroup = 0; 77 m_contextGroup = 0;
54 } 78 }
55 } 79 }
56 80
57 GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const 81 GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const
58 { 82 {
59 return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0; 83 return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0;
60 } 84 }
61 85
62 } 86 bool WebGLSharedObject::isAcquiredForContext(const WebGLRenderingContext* contex t, WebGLSharedObject::AcquireMode neededMode, bool mustBeBoundSinceLastAcquire, bool* hasBeenBoundSinceLastAcquire, const char** reason) const
87 {
88 AcquireContextMap::const_iterator it = m_acquireContextMap.find(context);
89 if (it == m_acquireContextMap.end()) {
90 *reason = "object not acquired in this context";
91 return false;
92 }
93
94 bool sameMode = m_acquireMode == neededMode;
95 bool validCombo = m_acquireMode == WebGLSharedObject::Exclusive && neededMod e == WebGLSharedObject::ReadOnly;
96 if (!sameMode && !validCombo) {
97 *reason = "object not acquired for exclusive access";
98 return false;
99 }
100
101 if (mustBeBoundSinceLastAcquire && !it->value) {
102 *reason = "object has not been bound since last acquired";
103 return false;
104 }
105
106 if (hasBeenBoundSinceLastAcquire) {
107 *hasBeenBoundSinceLastAcquire = it->value;
108 }
109
110 return true;
111 }
112
113 bool WebGLSharedObject::validate(const char* functionName, WebGLRenderingContext * context, WebGLSharedObject::AcquireMode neededMode, bool mustBeBoundSinceLastA cquire, bool* boundSinceLastAcquire) const
114 {
115 if (context->contextGroup() != m_contextGroup) {
116 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functio nName, "object not from this share group");
117 return false;
118 }
119
120 const char* reason;
121 if (!isAcquiredForContext(context, neededMode, mustBeBoundSinceLastAcquire, boundSinceLastAcquire, &reason)) {
122 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functio nName, reason);
123 return false;
124 }
125
126 return true;
127 }
128
129 void WebGLSharedObject::markAsBoundSinceLastAcquireForContext(const WebGLRenderi ngContext* context)
130 {
131 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
132 ASSERT(it != m_acquireContextMap.end());
133 it->value = true;
134 }
135
136 bool WebGLSharedObject::acquire(WebGLSharedObject::AcquireMode desiredMode, cons t WebGLRenderingContext* context)
137 {
138 AcquireContextMap::const_iterator it = m_acquireContextMap.find(context);
139 if (it != m_acquireContextMap.end()) {
140 // How can I get here?
141 return false;
142 }
143
144 bool unacquired = m_acquireMode == WebGLSharedObject::Unacquired;
145 bool bothReadOnly = m_acquireMode == WebGLSharedObject::ReadOnly && desiredM ode == WebGLSharedObject::ReadOnly;
146 if (!unacquired && !bothReadOnly) {
147 return false;
148 }
149
150 // Note: The resource is acquired at this point. The user may still cancel
151 // the request though before it the acquire callback is fired. If it is
152 // cancelled the cancel acts as a call to release.
153 m_acquireMode = desiredMode;
154 m_acquireContextMap.add(context, false);
155 return true;
156 }
157
158 bool WebGLSharedObject::addAcquireRequest(WebGLRenderingContext* context, WebGLS haredObject::AcquireMode desiredMode, PassRefPtr<WebGLAcquireSharedResourceCallb ack> callback, long& id)
159 {
160 switch (desiredMode) {
161 case WebGLSharedObject::ReadOnly:
162 case WebGLSharedObject::Exclusive:
163 break;
164 default:
165 context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "acquireShar edResource", "mode is not READ_ONLY or EXCLUSIVE");
166 return false;
167 }
168
169 // Checks the object belonngs to this group.
170 if (context->contextGroup() != m_contextGroup) {
171 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "object is not from this ShareGroup");
172 return false;
173 }
174
175 // Checks it is not already acquired by this context.
176 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
177 if (it != m_acquireContextMap.end()) {
178 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "object is already acquired in this context");
179 return false;
180 }
181
182 // Checks it is not already in one of the queues.
183 if (isRequestPending(context)) {
184 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "request to acquire this object is already pending in this con text");
185 return false;
186 }
187
188 // Adds the request.
189 m_acquireRequestQueue.append(WebGLAcquireSharedResourceRequest::create(this, callback, desiredMode, context, m_contextGroup->generateAcquireRequestId()));
190 processAcquireRequests();
191 return true;
192 }
193
194 bool WebGLSharedObject::release(WebGLRenderingContext* context)
195 {
196 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
197 if (it == m_acquireContextMap.end()) {
198 return false;
199 }
200
201 m_acquireContextMap.remove(it);
202 if (m_acquireContextMap.isEmpty()) {
203 if (m_acquireMode == WebGLSharedObject::Exclusive) {
204 // 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)
205 // Use sync objects/fences if available.
206 // Use glFinish otherwise.
207 context->flush(); // Using flush for now. So far only certain Androi d devices need a finish.
208 }
209 m_acquireMode = WebGLSharedObject::Unacquired;
210 processAcquireRequests();
211 }
212
213 return true;
214 }
215
216 void WebGLSharedObject::processAcquireRequests()
217 {
218 // Queue all the events that could succeed right now.
219 while (!m_acquireRequestQueue.isEmpty()) {
220 RefPtr<WebGLAcquireSharedResourceRequest> request = m_acquireRequestQueu e.first();
221 if (!acquire(request->acquireMode(), request->context())) {
222 break;
223 }
224
225 m_acquireRequestQueue.removeFirst();
226 m_acquireRequestPostedList.append(request);
227
228 // queue event
229 ScriptExecutionContext* scriptExecutionContext = request->context()->scr iptExecutionContext();
230 if (scriptExecutionContext) {
231 scriptExecutionContext->postTask(adoptPtr(new DispatchCallbackTask(r equest)));
232 }
233 }
234 }
235
236 bool WebGLSharedObject::isRequestPending(const WebGLRenderingContext* context)
237 {
238 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); it != m_acquireRequestQueue.end(); ++it) {
239 if ((*it)->context() == context) {
240 return true;
241 }
242 }
243 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
244 if ((*it)->context() == context) {
245 return true;
246 }
247 }
248 return false;
249 }
250
251 bool WebGLSharedObject::cancelAcquireRequest(const WebGLRenderingContext* contex t, long id)
252 {
253 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); it != m_acquireRequestQueue.end(); ++it) {
254 if ((*it)->id() == id) {
255 // Only remove it if it's from this context.
256 if ((*it)->context() == context) {
257 (*it)->cancel();
258 m_acquireRequestQueue.remove(it);
259 processAcquireRequests();
260 }
261 return true;
262 }
263 }
264 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
265 if ((*it)->id() == id) {
266 // Only remove it if it's from this context.
267 if ((*it)->context() == context) {
268 (*it)->cancel();
269 m_acquireRequestPostedList.remove(it);
270 processAcquireRequests();
271 }
272 return true;
273 }
274 }
275 return false;
276 }
277
278 void WebGLSharedObject::removePostedAcquireRequest(const WebGLRenderingContext* context, long id)
279 {
280 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
281 if ((*it)->id() == id) {
282 ASSERT((*it)->context() == context);
283 m_acquireRequestPostedList.remove(it);
284 return;
285 }
286 }
287 ASSERT(false); // should never get here.
288 }
289
290 WebGLSharedObject::DispatchCallbackTask::~DispatchCallbackTask()
291 {
292 }
293
294 void WebGLSharedObject::DispatchCallbackTask::performTask(ScriptExecutionContext *)
295 {
296 m_request->run();
297 }
298
299 WebGLAcquireSharedResourceRequest::WebGLAcquireSharedResourceRequest(PassRefPtr< WebGLSharedObject> sharedObject, PassRefPtr<WebGLAcquireSharedResourceCallback> callback, WebGLSharedObject::AcquireMode acquireMode, WebGLRenderingContext* con text, long id)
300 : m_sharedObject(sharedObject)
301 , m_context(context)
302 , m_id(id)
303 , m_acquireMode(acquireMode)
304 , m_callback(callback)
305 {
306 }
307
308 WebGLAcquireSharedResourceRequest::~WebGLAcquireSharedResourceRequest()
309 {
310 }
311
312 PassRefPtr<WebGLAcquireSharedResourceRequest> WebGLAcquireSharedResourceRequest: :create(PassRefPtr<WebGLSharedObject> sharedObject, PassRefPtr<WebGLAcquireShare dResourceCallback> callback, WebGLSharedObject::AcquireMode acquireMode, WebGLRe nderingContext* context, long id)
313 {
314 return adoptRef(new WebGLAcquireSharedResourceRequest(sharedObject, callback , acquireMode, context, id));
315 }
316
317 void WebGLAcquireSharedResourceRequest::cancel()
318 {
319 m_acquireMode = WebGLSharedObject::Unacquired;
320 m_callback.clear();
321 }
322
323 void WebGLAcquireSharedResourceRequest::run()
324 {
325 if (m_callback) {
326 RefPtr<WebGLAcquireSharedResourceRequest> self(this); // Need to keep a reference to ourselves as the next line may remove our last reference.
327 m_sharedObject->removePostedAcquireRequest(context(), id());
328 m_callback->handleEvent(m_sharedObject.get());
329 m_callback.clear();
330 }
331 }
332
333 } // namespace WebCore
334
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698