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

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

Issue 2379203002: implement getBufferSubDataAsync prototype (Closed)
Patch Set: rebase + clean up some XXXs Created 4 years, 2 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
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"
8 #include "core/frame/ImageBitmap.h" 9 #include "core/frame/ImageBitmap.h"
9 #include "core/html/HTMLCanvasElement.h" 10 #include "core/html/HTMLCanvasElement.h"
10 #include "core/html/HTMLImageElement.h" 11 #include "core/html/HTMLImageElement.h"
11 #include "core/html/HTMLVideoElement.h" 12 #include "core/html/HTMLVideoElement.h"
12 #include "core/html/ImageData.h" 13 #include "core/html/ImageData.h"
14 #include "gpu/GLES2/gl2extchromium.h"
13 #include "gpu/command_buffer/client/gles2_interface.h" 15 #include "gpu/command_buffer/client/gles2_interface.h"
14 #include "modules/webgl/WebGLActiveInfo.h" 16 #include "modules/webgl/WebGLActiveInfo.h"
15 #include "modules/webgl/WebGLBuffer.h" 17 #include "modules/webgl/WebGLBuffer.h"
16 #include "modules/webgl/WebGLFenceSync.h" 18 #include "modules/webgl/WebGLFenceSync.h"
17 #include "modules/webgl/WebGLFramebuffer.h" 19 #include "modules/webgl/WebGLFramebuffer.h"
18 #include "modules/webgl/WebGLProgram.h" 20 #include "modules/webgl/WebGLProgram.h"
19 #include "modules/webgl/WebGLQuery.h" 21 #include "modules/webgl/WebGLQuery.h"
20 #include "modules/webgl/WebGLRenderbuffer.h" 22 #include "modules/webgl/WebGLRenderbuffer.h"
21 #include "modules/webgl/WebGLSampler.h" 23 #include "modules/webgl/WebGLSampler.h"
22 #include "modules/webgl/WebGLSync.h" 24 #include "modules/webgl/WebGLSync.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 m_boundCopyWriteBuffer = nullptr; 182 m_boundCopyWriteBuffer = nullptr;
181 m_boundPixelPackBuffer = nullptr; 183 m_boundPixelPackBuffer = nullptr;
182 m_boundPixelUnpackBuffer = nullptr; 184 m_boundPixelUnpackBuffer = nullptr;
183 m_boundTransformFeedbackBuffer = nullptr; 185 m_boundTransformFeedbackBuffer = nullptr;
184 m_boundUniformBuffer = nullptr; 186 m_boundUniformBuffer = nullptr;
185 187
186 m_currentBooleanOcclusionQuery = nullptr; 188 m_currentBooleanOcclusionQuery = nullptr;
187 m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr; 189 m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr;
188 } 190 }
189 191
192 void WebGL2RenderingContextBase::destroyContext() {
193 for (auto& callback : m_getBufferSubDataAsyncCallbacks) {
194 callback->destroy();
195 }
196 m_getBufferSubDataAsyncCallbacks.clear();
197
198 WebGLRenderingContextBase::destroyContext();
199 }
200
190 void WebGL2RenderingContextBase::initializeNewContext() { 201 void WebGL2RenderingContextBase::initializeNewContext() {
191 ASSERT(!isContextLost()); 202 ASSERT(!isContextLost());
192 ASSERT(drawingBuffer()); 203 ASSERT(drawingBuffer());
193 204
194 m_readFramebufferBinding = nullptr; 205 m_readFramebufferBinding = nullptr;
195 206
196 m_boundCopyReadBuffer = nullptr; 207 m_boundCopyReadBuffer = nullptr;
197 m_boundCopyWriteBuffer = nullptr; 208 m_boundCopyWriteBuffer = nullptr;
198 m_boundPixelPackBuffer = nullptr; 209 m_boundPixelPackBuffer = nullptr;
199 m_boundPixelUnpackBuffer = nullptr; 210 m_boundPixelUnpackBuffer = nullptr;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 subByteLength, GL_MAP_READ_BIT); 393 subByteLength, GL_MAP_READ_BIT);
383 394
384 if (!mappedData) 395 if (!mappedData)
385 return; 396 return;
386 397
387 memcpy(subBaseAddress, mappedData, subByteLength); 398 memcpy(subBaseAddress, mappedData, subByteLength);
388 399
389 contextGL()->UnmapBuffer(target); 400 contextGL()->UnmapBuffer(target);
390 } 401 }
391 402
403 WebGL2RenderingContextBase::GetBufferSubDataAsyncCallback::
404 GetBufferSubDataAsyncCallback(WebGL2RenderingContextBase* context,
405 DOMArrayBufferView* dstData,
406 ScriptPromiseResolver* resolver,
407 void* subBaseAddress,
408 void* mappedData,
esprehn 2016/10/08 03:02:48 What's the purpose and relationship of these two v
Kai Ninomiya 2016/10/11 01:34:13 I've clarified this a lot and added some DCHECKs.
409 long long subByteLength)
410 : context(context),
411 dstData(dstData),
412 resolver(resolver),
413 subBaseAddress(subBaseAddress),
414 mappedData(mappedData),
415 subByteLength(subByteLength) {}
416
417 void WebGL2RenderingContextBase::GetBufferSubDataAsyncCallback::destroy() {
418 context->contextGL()->FreeSharedMemory(mappedData);
esprehn 2016/10/08 03:02:48 do these fields need to be public?
Kai Ninomiya 2016/10/11 01:34:13 Not sure what you mean. The fields of (WebGL)GetBu
419 mappedData = nullptr;
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 Upon entry please DCHECK(mappedData != NULL). We s
Kai Ninomiya 2016/10/11 01:34:14 Done.
420 DOMException* exception =
421 DOMException::create(InvalidStateError, "context lost or destroyed");
esprehn 2016/10/08 03:02:48 Capitalize error messages. "Context ..."
Kai Ninomiya 2016/10/11 01:34:13 Done.
422 this->resolver->reject(exception);
423 }
424
425 void WebGL2RenderingContextBase::GetBufferSubDataAsyncCallback::resolve(
426 GetBufferSubDataAsyncCallback* self) {
427 if (!self->context || !self->mappedData) {
esprehn 2016/10/08 03:02:48 lets move this into a method instead, you can prox
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 +1. That would make this code more comprehensible.
Kai Ninomiya 2016/10/11 01:34:14 Done.
428 DOMException* exception =
429 DOMException::create(InvalidStateError, "context lost or destroyed");
esprehn 2016/10/08 03:02:48 ditto
Kai Ninomiya 2016/10/11 01:34:14 Done.
430 self->resolver->reject(exception);
431 return;
432 }
433 if (self->dstData->buffer()->isNeutered()) {
434 DOMException* exception = DOMException::create(
435 InvalidStateError, "ArrayBufferView became invalid asynchronously");
436 self->resolver->reject(exception);
437 return;
438 }
439 memcpy(self->subBaseAddress, self->mappedData, self->subByteLength);
440 // XXX: What would happen if the DOM was suspended when the promise
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 It's OK to leave this question in place but please
Kai Ninomiya 2016/10/11 01:34:14 Still working on this issue, will address this com
441 // became resolved? Could another JS task happen between the memcpy
442 // and the promise resolution task?
443 self->resolver->resolve(self->dstData);
444
445 self->destroy();
446 self->context->unregisterGetBufferSubDataAsyncCallback(self);
447 }
448
449 ScriptPromise WebGL2RenderingContextBase::getBufferSubDataAsync(
esprehn 2016/10/08 03:02:49 This function is massive, can we make it into smal
Kai Ninomiya 2016/10/11 01:34:14 Great point, thanks. I will work on this tomorrow.
Kai Ninomiya 2016/10/11 21:54:43 I factored out a lot of common validation between
450 ScriptState* scriptState,
451 GLenum target,
452 GLintptr srcByteOffset,
453 DOMArrayBufferView* dstData,
454 GLuint dstOffset,
455 GLuint length) {
456 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
457 ScriptPromise promise = resolver->promise();
458
459 const char* funcName = "getBufferSubDataAsync";
esprehn 2016/10/08 03:02:48 static ?, probably kFunctionName. Don't abbreviat
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 Thanks Elliott for pointing that out. Kai, it does
Kai Ninomiya 2016/10/11 01:34:14 Done. There is future work to do if we want to rem
460 if (isContextLost()) {
461 DOMException* exception =
462 DOMException::create(InvalidStateError, "context lost");
463 resolver->reject(exception);
464 return promise;
465 }
466 if (!validateValueFitNonNegInt32(funcName, "srcByteOffset", srcByteOffset)) {
467 DOMException* exception =
468 DOMException::create(InvalidStateError, "invalid value: srcByteOffset");
469 resolver->reject(exception);
470 return promise;
471 }
472 if (target == GL_TRANSFORM_FEEDBACK_BUFFER && m_transformFeedbackBinding) {
473 // XXX: is this restriction enforced in the original getBufferSubData? Does
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 It looks like it isn't enforced and it should be.
Kai Ninomiya 2016/10/11 01:34:13 Filed and assigned to myself: http://crbug.com/654
474 // it need to be added there, or can it be removed here?
475 synthesizeGLError(GL_INVALID_OPERATION, funcName,
476 "targeted transform feedback buffer is bound");
477 DOMException* exception = DOMException::create(
478 InvalidStateError,
479 "invalid operation: targeted transform feedback buffer is bound");
480 resolver->reject(exception);
481 return promise;
482 }
483 WebGLBuffer* buffer = validateBufferDataTarget(funcName, target);
484 if (!buffer) {
485 DOMException* exception = DOMException::create(
486 InvalidStateError, "invalid operation: no buffer bound to target");
487 resolver->reject(exception);
488 return promise;
489 }
490
491 void* subBaseAddress = nullptr;
492 long long subByteLength = 0;
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 These "sub" names are confusing, especially when u
Kai Ninomiya 2016/10/11 01:34:14 For dstData and dstOffset, I don't want to change
493 if (!validateSubSourceAndGetData(dstData, dstOffset, length, &subBaseAddress,
494 &subByteLength)) {
495 synthesizeGLError(GL_INVALID_VALUE, funcName,
496 "dstOffset and length out of bounds of dstData");
497 DOMException* exception =
498 DOMException::create(InvalidStateError,
499 "invalid value: dstOffset and length "
500 "out of bounds of dstData");
501 resolver->reject(exception);
502 return promise;
503 }
504 if (subByteLength == 0) {
esprehn 2016/10/08 03:02:48 if (!subByteLength)
Kai Ninomiya 2016/10/11 01:34:14 Done.
505 resolver->resolve(dstData);
506 return promise;
507 }
508
509 CheckedNumeric<long long> dstEnd = subByteLength;
esprehn 2016/10/08 03:02:48 everything down here seems like a separate functio
Kai Ninomiya 2016/10/11 21:54:43 Done.
510 dstEnd += srcByteOffset;
511 if (!dstEnd.IsValid() || dstEnd.ValueOrDie() > buffer->getSize()) {
512 synthesizeGLError(
513 GL_INVALID_VALUE, funcName,
514 "offset + numBytes would extend beyond the end of buffer");
515 DOMException* exception =
516 DOMException::create(InvalidStateError,
517 "invalid value: offset + numBytes would extend "
518 "beyond the end of buffer");
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 end of -> end of the?
Kai Ninomiya 2016/10/11 01:34:14 Done.
519 resolver->reject(exception);
520 return promise;
521 }
522
523 GLuint queryID;
524 contextGL()->GenQueriesEXT(1, &queryID);
525 contextGL()->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, queryID);
526 void* mappedData = contextGL()->GetBufferSubDataAsyncCHROMIUM(
527 target, srcByteOffset, subByteLength);
528 if (!mappedData) {
529 DOMException* exception =
530 DOMException::create(InvalidStateError, "out of memory");
531 resolver->reject(exception);
532 return promise;
533 }
534 contextGL()->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
535
536 auto callbackObject = adoptRef(new GetBufferSubDataAsyncCallback(
537 this, dstData, resolver, subBaseAddress, mappedData, subByteLength));
538 registerGetBufferSubDataAsyncCallback(callbackObject.get());
539 auto callback =
540 WTF::bind(&GetBufferSubDataAsyncCallback::resolve, callbackObject);
541 drawingBuffer()->contextProvider()->signalQuery(
542 queryID, convertToBaseCallback(std::move(callback)));
543 contextGL()->DeleteQueriesEXT(1, &queryID);
Ken Russell (switch to Gerrit) 2016/10/10 22:21:30 It seems incorrect to delete the query here. It se
Kai Ninomiya 2016/10/11 01:34:14 I didn't investigate this previously, but I wrote
544
545 return promise;
546 }
547
548 void WebGL2RenderingContextBase::registerGetBufferSubDataAsyncCallback(
549 GetBufferSubDataAsyncCallback* callback) {
550 m_getBufferSubDataAsyncCallbacks.insert(callback);
551 }
552
553 void WebGL2RenderingContextBase::unregisterGetBufferSubDataAsyncCallback(
554 GetBufferSubDataAsyncCallback* callback) {
555 m_getBufferSubDataAsyncCallbacks.erase(callback);
556 }
557
392 void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0, 558 void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0,
393 GLint srcY0, 559 GLint srcY0,
394 GLint srcX1, 560 GLint srcX1,
395 GLint srcY1, 561 GLint srcY1,
396 GLint dstX0, 562 GLint dstX0,
397 GLint dstY0, 563 GLint dstY0,
398 GLint dstX1, 564 GLint dstX1,
399 GLint dstY1, 565 GLint dstY1,
400 GLbitfield mask, 566 GLbitfield mask,
401 GLenum filter) { 567 GLenum filter) {
(...skipping 4103 matching lines...) Expand 10 before | Expand all | Expand 10 after
4505 params.skipPixels = m_unpackSkipPixels; 4671 params.skipPixels = m_unpackSkipPixels;
4506 params.skipRows = m_unpackSkipRows; 4672 params.skipRows = m_unpackSkipRows;
4507 if (dimension == Tex3D) { 4673 if (dimension == Tex3D) {
4508 params.imageHeight = m_unpackImageHeight; 4674 params.imageHeight = m_unpackImageHeight;
4509 params.skipImages = m_unpackSkipImages; 4675 params.skipImages = m_unpackSkipImages;
4510 } 4676 }
4511 return params; 4677 return params;
4512 } 4678 }
4513 4679
4514 } // namespace blink 4680 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698