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

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp

Issue 2569863005: Move getBufferSubDataAsync to an extension (Closed)
Patch Set: fixup Created 4 years 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/webgl/WebGL2RenderingContextBase.h" 5 #include "modules/webgl/WebGL2RenderingContextBase.h"
6 6
7 #include "bindings/modules/v8/WebGLAny.h" 7 #include "bindings/modules/v8/WebGLAny.h"
8 #include "core/dom/DOMException.h"
9 #include "core/frame/ImageBitmap.h" 8 #include "core/frame/ImageBitmap.h"
10 #include "core/html/HTMLCanvasElement.h" 9 #include "core/html/HTMLCanvasElement.h"
11 #include "core/html/HTMLImageElement.h" 10 #include "core/html/HTMLImageElement.h"
12 #include "core/html/HTMLVideoElement.h" 11 #include "core/html/HTMLVideoElement.h"
13 #include "core/html/ImageData.h" 12 #include "core/html/ImageData.h"
14 #include "gpu/GLES2/gl2extchromium.h"
15 #include "gpu/command_buffer/client/gles2_interface.h" 13 #include "gpu/command_buffer/client/gles2_interface.h"
16 #include "modules/webgl/WebGLActiveInfo.h" 14 #include "modules/webgl/WebGLActiveInfo.h"
17 #include "modules/webgl/WebGLBuffer.h" 15 #include "modules/webgl/WebGLBuffer.h"
18 #include "modules/webgl/WebGLFenceSync.h" 16 #include "modules/webgl/WebGLFenceSync.h"
19 #include "modules/webgl/WebGLFramebuffer.h" 17 #include "modules/webgl/WebGLFramebuffer.h"
18 #include "modules/webgl/WebGLGetBufferSubDataAsync.h"
20 #include "modules/webgl/WebGLProgram.h" 19 #include "modules/webgl/WebGLProgram.h"
21 #include "modules/webgl/WebGLQuery.h" 20 #include "modules/webgl/WebGLQuery.h"
22 #include "modules/webgl/WebGLRenderbuffer.h" 21 #include "modules/webgl/WebGLRenderbuffer.h"
23 #include "modules/webgl/WebGLSampler.h" 22 #include "modules/webgl/WebGLSampler.h"
24 #include "modules/webgl/WebGLSync.h" 23 #include "modules/webgl/WebGLSync.h"
25 #include "modules/webgl/WebGLTexture.h" 24 #include "modules/webgl/WebGLTexture.h"
26 #include "modules/webgl/WebGLTransformFeedback.h" 25 #include "modules/webgl/WebGLTransformFeedback.h"
27 #include "modules/webgl/WebGLUniformLocation.h" 26 #include "modules/webgl/WebGLUniformLocation.h"
28 #include "modules/webgl/WebGLVertexArrayObject.h" 27 #include "modules/webgl/WebGLVertexArrayObject.h"
29 #include "public/platform/WebGraphicsContext3DProvider.h" 28 #include "public/platform/WebGraphicsContext3DProvider.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 GL_RGBA16I, 133 GL_RGBA16I,
135 GL_RGBA32UI, 134 GL_RGBA32UI,
136 GL_RGBA32I, 135 GL_RGBA32I,
137 GL_DEPTH_COMPONENT16, 136 GL_DEPTH_COMPONENT16,
138 GL_DEPTH_COMPONENT24, 137 GL_DEPTH_COMPONENT24,
139 GL_DEPTH_COMPONENT32F, 138 GL_DEPTH_COMPONENT32F,
140 GL_DEPTH24_STENCIL8, 139 GL_DEPTH24_STENCIL8,
141 GL_DEPTH32F_STENCIL8, 140 GL_DEPTH32F_STENCIL8,
142 }; 141 };
143 142
144 class WebGLGetBufferSubDataAsyncCallback
145 : public GarbageCollected<WebGLGetBufferSubDataAsyncCallback> {
146 public:
147 WebGLGetBufferSubDataAsyncCallback(
148 WebGL2RenderingContextBase* context,
149 ScriptPromiseResolver* promiseResolver,
150 void* shmReadbackResultData,
151 GLuint commandsIssuedQueryID,
152 DOMArrayBufferView* destinationArrayBufferView,
153 void* destinationDataPtr,
154 long long destinationByteLength)
155 : m_context(context),
156 m_promiseResolver(promiseResolver),
157 m_shmReadbackResultData(shmReadbackResultData),
158 m_commandsIssuedQueryID(commandsIssuedQueryID),
159 m_destinationArrayBufferView(destinationArrayBufferView),
160 m_destinationDataPtr(destinationDataPtr),
161 m_destinationByteLength(destinationByteLength) {
162 DCHECK(shmReadbackResultData);
163 DCHECK(destinationDataPtr);
164 }
165
166 void destroy() {
167 DCHECK(m_shmReadbackResultData);
168 m_context->contextGL()->FreeSharedMemory(m_shmReadbackResultData);
169 m_shmReadbackResultData = nullptr;
170 DOMException* exception =
171 DOMException::create(InvalidStateError, "Context lost or destroyed");
172 m_promiseResolver->reject(exception);
173 }
174
175 void resolve() {
176 if (!m_context || !m_shmReadbackResultData) {
177 DOMException* exception =
178 DOMException::create(InvalidStateError, "Context lost or destroyed");
179 m_promiseResolver->reject(exception);
180 return;
181 }
182 if (m_destinationArrayBufferView->buffer()->isNeutered()) {
183 DOMException* exception = DOMException::create(
184 InvalidStateError, "ArrayBufferView became invalid asynchronously");
185 m_promiseResolver->reject(exception);
186 return;
187 }
188 memcpy(m_destinationDataPtr, m_shmReadbackResultData,
189 m_destinationByteLength);
190 // TODO(kainino): What would happen if the DOM was suspended when the
191 // promise became resolved? Could another JS task happen between the memcpy
192 // and the promise resolution task, which would see the wrong data?
193 m_promiseResolver->resolve(m_destinationArrayBufferView);
194
195 m_context->contextGL()->DeleteQueriesEXT(1, &m_commandsIssuedQueryID);
196 this->destroy();
197 m_context->unregisterGetBufferSubDataAsyncCallback(this);
198 }
199
200 DECLARE_TRACE();
201
202 private:
203 WeakMember<WebGL2RenderingContextBase> m_context;
204 Member<ScriptPromiseResolver> m_promiseResolver;
205
206 // Pointer to shared memory where the gpu readback result is stored.
207 void* m_shmReadbackResultData;
208 // ID of the GL query used to call this callback.
209 GLuint m_commandsIssuedQueryID;
210
211 // ArrayBufferView returned from the promise.
212 Member<DOMArrayBufferView> m_destinationArrayBufferView;
213 // Pointer into the offset into destinationArrayBufferView.
214 void* m_destinationDataPtr;
215 // Size in bytes of the copy operation being performed.
216 long long m_destinationByteLength;
217 };
218
219 DEFINE_TRACE(WebGLGetBufferSubDataAsyncCallback) {
220 visitor->trace(m_context);
221 visitor->trace(m_promiseResolver);
222 visitor->trace(m_destinationArrayBufferView);
223 }
224
225 WebGL2RenderingContextBase::WebGL2RenderingContextBase( 143 WebGL2RenderingContextBase::WebGL2RenderingContextBase(
226 HTMLCanvasElement* passedCanvas, 144 HTMLCanvasElement* passedCanvas,
227 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, 145 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
228 const CanvasContextCreationAttributes& requestedAttributes) 146 const CanvasContextCreationAttributes& requestedAttributes)
229 : WebGLRenderingContextBase(passedCanvas, 147 : WebGLRenderingContextBase(passedCanvas,
230 std::move(contextProvider), 148 std::move(contextProvider),
231 requestedAttributes, 149 requestedAttributes,
232 2), 150 2),
233 m_readFramebufferBinding(this, nullptr), 151 m_readFramebufferBinding(this, nullptr),
234 m_transformFeedbackBinding(this, nullptr), 152 m_transformFeedbackBinding(this, nullptr),
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 destinationByteLength, GL_MAP_READ_BIT); 392 destinationByteLength, GL_MAP_READ_BIT);
475 393
476 if (!mappedData) 394 if (!mappedData)
477 return; 395 return;
478 396
479 memcpy(destinationDataPtr, mappedData, destinationByteLength); 397 memcpy(destinationDataPtr, mappedData, destinationByteLength);
480 398
481 contextGL()->UnmapBuffer(target); 399 contextGL()->UnmapBuffer(target);
482 } 400 }
483 401
484 ScriptPromise WebGL2RenderingContextBase::getBufferSubDataAsync(
485 ScriptState* scriptState,
486 GLenum target,
487 GLintptr srcByteOffset,
488 DOMArrayBufferView* dstData,
489 GLuint dstOffset,
490 GLuint length) {
491 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
492 ScriptPromise promise = resolver->promise();
493
494 WebGLBuffer* sourceBuffer = nullptr;
495 void* destinationDataPtr = nullptr;
496 long long destinationByteLength = 0;
497 const char* message = validateGetBufferSubData(
498 __FUNCTION__, target, srcByteOffset, dstData, dstOffset, length,
499 &sourceBuffer, &destinationDataPtr, &destinationByteLength);
500 if (message) {
501 // If there was a GL error, it was already synthesized in
502 // validateGetBufferSubData, so it's not done here.
503 DOMException* exception = DOMException::create(InvalidStateError, message);
504 resolver->reject(exception);
505 return promise;
506 }
507
508 message = validateGetBufferSubDataBounds(
509 __FUNCTION__, sourceBuffer, srcByteOffset, destinationByteLength);
510 if (message) {
511 // If there was a GL error, it was already synthesized in
512 // validateGetBufferSubDataBounds, so it's not done here.
513 DOMException* exception = DOMException::create(InvalidStateError, message);
514 resolver->reject(exception);
515 return promise;
516 }
517
518 // If the length of the copy is zero, this is a no-op.
519 if (!destinationByteLength) {
520 resolver->resolve(dstData);
521 return promise;
522 }
523
524 GLuint queryID;
525 contextGL()->GenQueriesEXT(1, &queryID);
526 contextGL()->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, queryID);
527 void* mappedData = contextGL()->GetBufferSubDataAsyncCHROMIUM(
528 target, srcByteOffset, destinationByteLength);
529 contextGL()->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
530 if (!mappedData) {
531 DOMException* exception =
532 DOMException::create(InvalidStateError, "Out of memory");
533 resolver->reject(exception);
534 return promise;
535 }
536
537 auto callbackObject = new WebGLGetBufferSubDataAsyncCallback(
538 this, resolver, mappedData, queryID, dstData, destinationDataPtr,
539 destinationByteLength);
540 registerGetBufferSubDataAsyncCallback(callbackObject);
541 auto callback = WTF::bind(&WebGLGetBufferSubDataAsyncCallback::resolve,
542 wrapPersistent(callbackObject));
543 drawingBuffer()->contextProvider()->signalQuery(
544 queryID, convertToBaseCallback(std::move(callback)));
545
546 return promise;
547 }
548
549 void WebGL2RenderingContextBase::registerGetBufferSubDataAsyncCallback( 402 void WebGL2RenderingContextBase::registerGetBufferSubDataAsyncCallback(
550 WebGLGetBufferSubDataAsyncCallback* callback) { 403 WebGLGetBufferSubDataAsyncCallback* callback) {
551 m_getBufferSubDataAsyncCallbacks.add(callback); 404 m_getBufferSubDataAsyncCallbacks.add(callback);
552 } 405 }
553 406
554 void WebGL2RenderingContextBase::unregisterGetBufferSubDataAsyncCallback( 407 void WebGL2RenderingContextBase::unregisterGetBufferSubDataAsyncCallback(
555 WebGLGetBufferSubDataAsyncCallback* callback) { 408 WebGLGetBufferSubDataAsyncCallback* callback) {
556 m_getBufferSubDataAsyncCallbacks.remove(callback); 409 m_getBufferSubDataAsyncCallbacks.remove(callback);
557 } 410 }
558 411
(...skipping 4381 matching lines...) Expand 10 before | Expand all | Expand 10 after
4940 4793
4941 void WebGL2RenderingContextBase:: 4794 void WebGL2RenderingContextBase::
4942 DrawingBufferClientRestorePixelUnpackBufferBinding() { 4795 DrawingBufferClientRestorePixelUnpackBufferBinding() {
4943 if (!contextGL()) 4796 if (!contextGL())
4944 return; 4797 return;
4945 contextGL()->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 4798 contextGL()->BindBuffer(GL_PIXEL_UNPACK_BUFFER,
4946 objectOrZero(m_boundPixelUnpackBuffer.get())); 4799 objectOrZero(m_boundPixelUnpackBuffer.get()));
4947 } 4800 }
4948 4801
4949 } // namespace blink 4802 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698