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

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:
Ken Russell (switch to Gerrit) 2013/06/19 03:51:24 Should these ints come from WebGLSharedResources.h
greggman 2013/06/21 19:54:21 Done.
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);
Ken Russell (switch to Gerrit) 2013/06/19 03:51:24 Should there be an ASSERT on the result of this ca
greggman 2013/06/21 19:54:21 Done.
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 = " 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 = " not acquired for exclusive access";
98 return false;
99 }
100
101 if (mustBeBoundSinceLastAcquire && !it->value) {
102 *reason = " 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 String msg(String(typeName()) + " not from this share group");
117 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functio nName, msg.utf8().data());
118 return false;
119 }
120
121 const char* reason;
122 if (!isAcquiredForContext(context, neededMode, mustBeBoundSinceLastAcquire, boundSinceLastAcquire, &reason)) {
123 String msg(String(typeName()) + reason);
124 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functio nName, msg.utf8().data());
125 return false;
126 }
127
128 return true;
129 }
130
131 void WebGLSharedObject::markAsBoundSinceLastAcquireForContext(const WebGLRenderi ngContext* context)
132 {
133 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
134 ASSERT(it != m_acquireContextMap.end());
135 it->value = true;
136 }
137
138 bool WebGLSharedObject::acquire(WebGLSharedObject::AcquireMode desiredMode, cons t WebGLRenderingContext* context)
139 {
140 AcquireContextMap::const_iterator it = m_acquireContextMap.find(context);
141 if (it != m_acquireContextMap.end()) {
142 // How can I get here?
143 return false;
144 }
145
146 bool unacquired = m_acquireMode == WebGLSharedObject::Unacquired;
147 bool bothReadOnly = m_acquireMode == WebGLSharedObject::ReadOnly && desiredM ode == WebGLSharedObject::ReadOnly;
148 if (!unacquired && !bothReadOnly) {
149 return false;
150 }
151
152 // Note: The resource is acquired at this point. The user may still cancel
153 // the request though before it the acquire callback is fired. If it is
154 // cancelled the cancel acts as a call to release.
155 m_acquireMode = desiredMode;
156 m_acquireContextMap.add(context, false);
157 return true;
158 }
159
160 bool WebGLSharedObject::addAcquireRequest(WebGLRenderingContext* context, WebGLS haredObject::AcquireMode desiredMode, PassRefPtr<WebGLAcquireSharedResourceCallb ack> callback, long& id)
161 {
162 switch (desiredMode) {
163 case WebGLSharedObject::ReadOnly:
164 case WebGLSharedObject::Exclusive:
165 break;
166 default:
167 context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "acquireShar edResource", "mode is not READ_ONLY or EXCLUSIVE");
168 return false;
169 }
170
171 // Checks the object belonngs to this group.
Ken Russell (switch to Gerrit) 2013/06/19 03:51:24 Typo: belonngs
greggman 2013/06/21 19:54:21 Done.
172 if (context->contextGroup() != m_contextGroup) {
173 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "object is not from this ShareGroup");
174 return false;
175 }
176
177 // Checks it is not already acquired by this context.
178 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
179 if (it != m_acquireContextMap.end()) {
180 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "object is already acquired in this context");
181 return false;
182 }
183
184 // Checks it is not already in one of the queues.
185 if (isRequestPending(context)) {
186 context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "acquir eSharedResource", "request to acquire this object is already pending in this con text");
187 return false;
188 }
189
190 // Adds the request.
191 m_acquireRequestQueue.append(WebGLAcquireSharedResourceRequest::create(this, callback, desiredMode, context, m_contextGroup->generateAcquireRequestId()));
192 processAcquireRequests();
193 return true;
194 }
195
196 bool WebGLSharedObject::release(WebGLRenderingContext* context)
197 {
198 AcquireContextMap::iterator it = m_acquireContextMap.find(context);
199 if (it == m_acquireContextMap.end()) {
200 return false;
201 }
202
203 m_acquireContextMap.remove(it);
204 if (m_acquireContextMap.isEmpty()) {
205 if (m_acquireMode == WebGLSharedObject::Exclusive) {
206 // 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)
207 // Use sync objects/fences if available.
208 // Use glFinish otherwise.
209 context->flush(); // Using flush for now. So far only certain Androi d devices need a finish.
210 }
211 m_acquireMode = WebGLSharedObject::Unacquired;
212 processAcquireRequests();
213 }
214
215 return true;
216 }
217
218 void WebGLSharedObject::processAcquireRequests()
219 {
220 // Queue all the events that could succeed right now.
221 while (!m_acquireRequestQueue.isEmpty()) {
222 RefPtr<WebGLAcquireSharedResourceRequest> request = m_acquireRequestQueu e.first();
223 if (!acquire(request->acquireMode(), request->context())) {
224 break;
225 }
226
227 m_acquireRequestQueue.removeFirst();
228 m_acquireRequestPostedList.append(request);
229
230 // queue event
231 ScriptExecutionContext* scriptExecutionContext = request->context()->scr iptExecutionContext();
232 if (scriptExecutionContext) {
233 scriptExecutionContext->postTask(adoptPtr(new DispatchCallbackTask(r equest)));
234 }
Ken Russell (switch to Gerrit) 2013/06/19 03:51:24 Are there any race conditions with these acquire c
235 }
236 }
237
238 bool WebGLSharedObject::isRequestPending(const WebGLRenderingContext* context)
239 {
240 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); it != m_acquireRequestQueue.end(); ++it) {
241 if ((*it)->context() == context) {
242 return true;
243 }
244 }
245 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
246 if ((*it)->context() == context) {
247 return true;
248 }
249 }
250 return false;
251 }
252
253 bool WebGLSharedObject::cancelAcquireRequest(const WebGLRenderingContext* contex t, long id)
254 {
255 for (AcquireRequestQueue::iterator it = m_acquireRequestQueue.begin(); it != m_acquireRequestQueue.end(); ++it) {
256 if ((*it)->id() == id) {
257 // Only remove it if it's from this context.
258 if ((*it)->context() == context) {
259 (*it)->cancel();
260 m_acquireRequestQueue.remove(it);
261 processAcquireRequests();
262 }
263 return true;
264 }
265 }
266 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
267 if ((*it)->id() == id) {
268 // Only remove it if it's from this context.
269 if ((*it)->context() == context) {
270 (*it)->cancel();
271 m_acquireRequestPostedList.remove(it);
272 processAcquireRequests();
273 }
274 return true;
275 }
276 }
277 return false;
278 }
279
280 void WebGLSharedObject::removePostedAcquireRequest(const WebGLRenderingContext* context, long id)
281 {
282 for (AcquireRequestList::iterator it = m_acquireRequestPostedList.begin(); i t != m_acquireRequestPostedList.end(); ++it) {
283 if ((*it)->id() == id) {
284 ASSERT((*it)->context() == context);
285 m_acquireRequestPostedList.remove(it);
286 return;
287 }
288 }
289 ASSERT(false); // should never get here.
290 }
291
292 WebGLSharedObject::DispatchCallbackTask::~DispatchCallbackTask()
293 {
294 }
295
296 void WebGLSharedObject::DispatchCallbackTask::performTask(ScriptExecutionContext *)
297 {
298 m_request->run();
299 }
300
301 WebGLAcquireSharedResourceRequest::WebGLAcquireSharedResourceRequest(PassRefPtr< WebGLSharedObject> sharedObject, PassRefPtr<WebGLAcquireSharedResourceCallback> callback, WebGLSharedObject::AcquireMode acquireMode, WebGLRenderingContext* con text, long id)
302 : m_sharedObject(sharedObject)
303 , m_context(context)
304 , m_id(id)
305 , m_acquireMode(acquireMode)
306 , m_callback(callback)
307 {
308 }
309
310 WebGLAcquireSharedResourceRequest::~WebGLAcquireSharedResourceRequest()
311 {
312 }
313
314 PassRefPtr<WebGLAcquireSharedResourceRequest> WebGLAcquireSharedResourceRequest: :create(PassRefPtr<WebGLSharedObject> sharedObject, PassRefPtr<WebGLAcquireShare dResourceCallback> callback, WebGLSharedObject::AcquireMode acquireMode, WebGLRe nderingContext* context, long id)
315 {
316 return adoptRef(new WebGLAcquireSharedResourceRequest(sharedObject, callback , acquireMode, context, id));
317 }
318
319 void WebGLAcquireSharedResourceRequest::cancel()
320 {
321 m_acquireMode = WebGLSharedObject::Unacquired;
322 m_callback.clear();
323 }
324
325 void WebGLAcquireSharedResourceRequest::run()
326 {
327 if (m_callback) {
328 RefPtr<WebGLAcquireSharedResourceRequest> self(this); // Need to keep a reference to ourselves as the next line may remove our last reference.
329 m_sharedObject->removePostedAcquireRequest(context(), id());
330 m_callback->handleEvent(m_sharedObject.get());
331 m_callback.clear();
332 }
333 }
334
335 } // namespace WebCore
336
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698