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

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

Issue 2379203002: implement getBufferSubDataAsync prototype (Closed)
Patch Set: hide getBufferSubDataAsync behind ExperimentalCanvasFeatures 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 subByteLength, GL_MAP_READ_BIT); 390 subByteLength, GL_MAP_READ_BIT);
380 391
381 if (!mappedData) 392 if (!mappedData)
382 return; 393 return;
383 394
384 memcpy(subBaseAddress, mappedData, subByteLength); 395 memcpy(subBaseAddress, mappedData, subByteLength);
385 396
386 contextGL()->UnmapBuffer(target); 397 contextGL()->UnmapBuffer(target);
387 } 398 }
388 399
400 WebGL2RenderingContextBase::GetBufferSubDataAsyncCallback::
401 GetBufferSubDataAsyncCallback(WebGL2RenderingContextBase* context,
402 DOMArrayBufferView* dstData,
403 ScriptPromiseResolver* resolver,
404 void* subBaseAddress,
405 void* mappedData,
406 long long subByteLength)
407 : context(context),
408 dstData(dstData),
409 resolver(resolver),
410 subBaseAddress(subBaseAddress),
411 mappedData(mappedData),
412 subByteLength(subByteLength) {}
413
414 void WebGL2RenderingContextBase::GetBufferSubDataAsyncCallback::destroy() {
415 context->contextGL()->FreeSharedMemory(mappedData);
416 mappedData = nullptr;
417 DOMException* exception =
418 DOMException::create(InvalidStateError, "context lost or destroyed");
419 this->resolver->reject(exception);
420 }
421
422 void WebGL2RenderingContextBase::GetBufferSubDataAsyncCallback::resolve(
423 GetBufferSubDataAsyncCallback* self) {
424 if (!self->context || !self->mappedData) {
425 DOMException* exception =
426 DOMException::create(InvalidStateError, "context lost or destroyed");
427 self->resolver->reject(exception);
428 return;
429 }
430 if (self->dstData->buffer()->isNeutered()) {
431 // XXX: should this set a GL error? No, according to current spec draft.
432 DOMException* exception = DOMException::create(
433 InvalidStateError, "ArrayBufferView became invalid asynchronously");
434 self->resolver->reject(exception);
435 return;
436 }
437 memcpy(self->subBaseAddress, self->mappedData, self->subByteLength);
438 // XXX: What would happen if the DOM was suspended when the promise
439 // became resolved? Could another JS task happen between the memcpy
440 // and the promise resolution task?
441 self->resolver->resolve(self->dstData);
adamk 2016/10/07 23:00:43 My knowledge of the Blink event loop is a little r
yhirano 2016/10/12 09:32:02 When the window is suspended, ScriptPromiseResolve
tyoshino (SeeGerritForStatus) 2016/10/12 10:00:39 As this looked related to promises, I asked yhiran
442
443 self->destroy();
444 self->context->unregisterGetBufferSubDataAsyncCallback(self);
445 }
446
447 ScriptPromise WebGL2RenderingContextBase::getBufferSubDataAsync(
448 ScriptState* scriptState,
449 GLenum target,
450 GLintptr srcByteOffset,
451 DOMArrayBufferView* dstData,
452 GLuint dstOffset,
453 GLuint length) {
454 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
455 ScriptPromise promise = resolver->promise();
456
457 const char* funcName = "getBufferSubDataAsync";
458 if (isContextLost()) {
459 DOMException* exception =
460 DOMException::create(InvalidStateError, "context lost");
461 resolver->reject(exception);
462 return promise;
463 }
464 if (!validateValueFitNonNegInt32(funcName, "srcByteOffset", srcByteOffset)) {
465 DOMException* exception =
466 DOMException::create(InvalidStateError, "invalid value: srcByteOffset");
467 resolver->reject(exception);
468 return promise;
469 }
470 if (target == GL_TRANSFORM_FEEDBACK_BUFFER && m_transformFeedbackBinding) {
471 // XXX: is this restriction enforced in the original getBufferSubData? Does it need to be added there, or can it be removed here?
472 synthesizeGLError(GL_INVALID_OPERATION, funcName,
473 "targeted transform feedback buffer is bound");
474 DOMException* exception = DOMException::create(
475 InvalidStateError,
476 "invalid operation: targeted transform feedback buffer is bound");
477 resolver->reject(exception);
478 return promise;
479 }
480 WebGLBuffer* buffer = validateBufferDataTarget(funcName, target);
481 if (!buffer) {
482 DOMException* exception = DOMException::create(
483 InvalidStateError, "invalid operation: no buffer bound to target");
484 resolver->reject(exception);
485 return promise;
486 }
487
488 void* subBaseAddress = nullptr;
489 long long subByteLength = 0;
490 if (!validateSubSourceAndGetData(dstData, dstOffset, length, &subBaseAddress,
491 &subByteLength)) {
492 synthesizeGLError(GL_INVALID_VALUE, funcName,
493 "dstOffset and length out of bounds of dstData");
494 DOMException* exception =
495 DOMException::create(InvalidStateError,
496 "invalid value: dstOffset and length "
497 "out of bounds of dstData");
498 resolver->reject(exception);
499 return promise;
500 }
501 if (subByteLength == 0) {
502 resolver->resolve(dstData);
503 return promise;
504 }
505
506 CheckedNumeric<long long> dstEnd = subByteLength;
507 dstEnd += srcByteOffset;
508 if (!dstEnd.IsValid() || dstEnd.ValueOrDie() > buffer->getSize()) {
509 synthesizeGLError(
510 GL_INVALID_VALUE, funcName,
511 "offset + numBytes would extend beyond the end of buffer");
512 DOMException* exception =
513 DOMException::create(InvalidStateError,
514 "invalid value: offset + numBytes would extend "
515 "beyond the end of buffer");
516 resolver->reject(exception);
517 return promise;
518 }
519
520 GLuint queryID;
521 contextGL()->GenQueriesEXT(1, &queryID);
522 contextGL()->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, queryID);
523 void* mappedData = contextGL()->GetBufferSubDataAsyncCHROMIUM(
524 target, srcByteOffset, subByteLength);
525 if (!mappedData) {
526 DOMException* exception =
527 DOMException::create(InvalidStateError, "out of memory");
528 resolver->reject(exception);
529 return promise;
530 }
531 contextGL()->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
532
533 auto callbackObject = adoptRef(new GetBufferSubDataAsyncCallback(
534 this, dstData, resolver, subBaseAddress, mappedData, subByteLength));
535 registerGetBufferSubDataAsyncCallback(callbackObject.get());
536 auto callback =
537 WTF::bind(&GetBufferSubDataAsyncCallback::resolve, callbackObject);
538 drawingBuffer()->contextProvider()->signalQuery(
539 queryID, convertToBaseCallback(std::move(callback)));
540 contextGL()->DeleteQueriesEXT(1, &queryID);
541
542 return promise;
543 }
544
545 void WebGL2RenderingContextBase::registerGetBufferSubDataAsyncCallback(
546 GetBufferSubDataAsyncCallback* callback) {
547 m_getBufferSubDataAsyncCallbacks.insert(callback);
548 }
549
550 void WebGL2RenderingContextBase::unregisterGetBufferSubDataAsyncCallback(
551 GetBufferSubDataAsyncCallback* callback) {
552 m_getBufferSubDataAsyncCallbacks.erase(callback);
553 }
554
389 void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0, 555 void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0,
390 GLint srcY0, 556 GLint srcY0,
391 GLint srcX1, 557 GLint srcX1,
392 GLint srcY1, 558 GLint srcY1,
393 GLint dstX0, 559 GLint dstX0,
394 GLint dstY0, 560 GLint dstY0,
395 GLint dstX1, 561 GLint dstX1,
396 GLint dstY1, 562 GLint dstY1,
397 GLbitfield mask, 563 GLbitfield mask,
398 GLenum filter) { 564 GLenum filter) {
(...skipping 4090 matching lines...) Expand 10 before | Expand all | Expand 10 after
4489 params.skipPixels = m_unpackSkipPixels; 4655 params.skipPixels = m_unpackSkipPixels;
4490 params.skipRows = m_unpackSkipRows; 4656 params.skipRows = m_unpackSkipRows;
4491 if (dimension == Tex3D) { 4657 if (dimension == Tex3D) {
4492 params.imageHeight = m_unpackImageHeight; 4658 params.imageHeight = m_unpackImageHeight;
4493 params.skipImages = m_unpackSkipImages; 4659 params.skipImages = m_unpackSkipImages;
4494 } 4660 }
4495 return params; 4661 return params;
4496 } 4662 }
4497 4663
4498 } // namespace blink 4664 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698