Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 10 matching lines...) Expand all Loading... | |
| 33 using WTF::String; | 35 using WTF::String; |
| 34 | 36 |
| 35 namespace blink { | 37 namespace blink { |
| 36 | 38 |
| 37 namespace { | 39 namespace { |
| 38 | 40 |
| 39 GLsync syncObjectOrZero(const WebGLSync* object) { | 41 GLsync syncObjectOrZero(const WebGLSync* object) { |
| 40 return object ? object->object() : nullptr; | 42 return object ? object->object() : nullptr; |
| 41 } | 43 } |
| 42 | 44 |
| 45 // TODO(kainino): Change outByteLength to GLuint and change the associated | |
| 46 // range checking (and all uses) - overflow becomes possible in cases below | |
| 43 bool validateSubSourceAndGetData(DOMArrayBufferView* view, | 47 bool validateSubSourceAndGetData(DOMArrayBufferView* view, |
| 44 GLuint subOffset, | 48 GLuint subOffset, |
| 45 GLuint subLength, | 49 GLuint subLength, |
| 46 void** outBaseAddress, | 50 void** outBaseAddress, |
| 47 long long* outByteLength) { | 51 long long* outByteLength) { |
| 48 // This is guaranteed to be non-null by DOM. | 52 // This is guaranteed to be non-null by DOM. |
| 49 DCHECK(view); | 53 DCHECK(view); |
| 50 | 54 |
| 51 size_t typeSize = view->typeSize(); | 55 size_t typeSize = view->typeSize(); |
| 52 DCHECK_GE(8u, typeSize); | 56 DCHECK_GE(8u, typeSize); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 GL_COMPRESSED_RG11_EAC, | 145 GL_COMPRESSED_RG11_EAC, |
| 142 GL_COMPRESSED_SIGNED_RG11_EAC, | 146 GL_COMPRESSED_SIGNED_RG11_EAC, |
| 143 GL_COMPRESSED_RGB8_ETC2, | 147 GL_COMPRESSED_RGB8_ETC2, |
| 144 GL_COMPRESSED_SRGB8_ETC2, | 148 GL_COMPRESSED_SRGB8_ETC2, |
| 145 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, | 149 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| 146 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, | 150 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| 147 GL_COMPRESSED_RGBA8_ETC2_EAC, | 151 GL_COMPRESSED_RGBA8_ETC2_EAC, |
| 148 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, | 152 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, |
| 149 }; | 153 }; |
| 150 | 154 |
| 155 class WebGLGetBufferSubDataAsyncCallback | |
|
esprehn
2016/10/18 01:44:16
This should be garbage collected, and use a HeapHa
Kai Ninomiya
2016/10/19 18:17:49
Done.
| |
| 156 : public RefCounted<WebGLGetBufferSubDataAsyncCallback> { | |
| 157 public: | |
| 158 WebGLGetBufferSubDataAsyncCallback( | |
| 159 WebGL2RenderingContextBase* context, | |
| 160 ScriptPromiseResolver* promiseResolver, | |
| 161 void* shmReadbackResultData, | |
| 162 GLuint commandsIssuedQueryID, | |
| 163 DOMArrayBufferView* destinationArrayBufferView, | |
| 164 void* destinationDataPtr, | |
| 165 long long destinationByteLength) | |
| 166 : context(context), | |
| 167 promiseResolver(promiseResolver), | |
| 168 shmReadbackResultData(shmReadbackResultData), | |
| 169 commandsIssuedQueryID(commandsIssuedQueryID), | |
| 170 destinationArrayBufferView(destinationArrayBufferView), | |
| 171 destinationDataPtr(destinationDataPtr), | |
| 172 destinationByteLength(destinationByteLength) { | |
| 173 DCHECK(shmReadbackResultData); | |
| 174 DCHECK(destinationDataPtr); | |
| 175 } | |
| 176 | |
| 177 void destroy() { | |
| 178 DCHECK(shmReadbackResultData); | |
| 179 context->contextGL()->FreeSharedMemory(shmReadbackResultData); | |
| 180 shmReadbackResultData = nullptr; | |
| 181 DOMException* exception = | |
| 182 DOMException::create(InvalidStateError, "Context lost or destroyed"); | |
| 183 this->promiseResolver->reject(exception); | |
| 184 } | |
| 185 | |
| 186 void resolve() { | |
| 187 if (!this->context || !this->shmReadbackResultData) { | |
| 188 DOMException* exception = | |
| 189 DOMException::create(InvalidStateError, "Context lost or destroyed"); | |
| 190 this->promiseResolver->reject(exception); | |
| 191 return; | |
| 192 } | |
| 193 if (this->destinationArrayBufferView->buffer()->isNeutered()) { | |
| 194 DOMException* exception = DOMException::create( | |
| 195 InvalidStateError, "ArrayBufferView became invalid asynchronously"); | |
| 196 this->promiseResolver->reject(exception); | |
| 197 return; | |
| 198 } | |
| 199 memcpy(this->destinationDataPtr, this->shmReadbackResultData, | |
| 200 this->destinationByteLength); | |
| 201 // TODO(kainino): What would happen if the DOM was suspended when the | |
| 202 // promise became resolved? Could another JS task happen between the memcpy | |
| 203 // and the promise resolution task, which would see the wrong data? | |
| 204 this->promiseResolver->resolve(this->destinationArrayBufferView); | |
|
esprehn
2016/10/18 01:44:16
remove this-> and use m_
Kai Ninomiya
2016/10/19 17:54:10
Done.
| |
| 205 | |
| 206 context->contextGL()->DeleteQueriesEXT(1, &commandsIssuedQueryID); | |
| 207 this->destroy(); | |
| 208 this->context->unregisterGetBufferSubDataAsyncCallback(this); | |
| 209 } | |
| 210 | |
| 211 private: | |
| 212 WeakPersistent<WebGL2RenderingContextBase> context; | |
| 213 Persistent<ScriptPromiseResolver> promiseResolver; | |
| 214 | |
| 215 // Pointer to shared memory where the gpu readback result is stored. | |
| 216 void* shmReadbackResultData; | |
|
esprehn
2016/10/18 01:44:16
m_ for all the private fields
Kai Ninomiya
2016/10/19 17:54:10
Done.
| |
| 217 // ID of the GL query used to call this callback. | |
| 218 GLuint commandsIssuedQueryID; | |
| 219 | |
| 220 // ArrayBufferView returned from the promise. | |
| 221 Persistent<DOMArrayBufferView> destinationArrayBufferView; | |
| 222 // Pointer into the offset into destinationArrayBufferView. | |
| 223 void* destinationDataPtr; | |
| 224 // Size in bytes of the copy operation being performed. | |
| 225 long long destinationByteLength; | |
| 226 }; | |
| 227 | |
| 151 WebGL2RenderingContextBase::WebGL2RenderingContextBase( | 228 WebGL2RenderingContextBase::WebGL2RenderingContextBase( |
| 152 HTMLCanvasElement* passedCanvas, | 229 HTMLCanvasElement* passedCanvas, |
| 153 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 230 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, |
| 154 const CanvasContextCreationAttributes& requestedAttributes) | 231 const CanvasContextCreationAttributes& requestedAttributes) |
| 155 : WebGLRenderingContextBase(passedCanvas, | 232 : WebGLRenderingContextBase(passedCanvas, |
| 156 std::move(contextProvider), | 233 std::move(contextProvider), |
| 157 requestedAttributes, | 234 requestedAttributes, |
| 158 2) { | 235 2) { |
| 159 m_supportedInternalFormatsStorage.insert( | 236 m_supportedInternalFormatsStorage.insert( |
| 160 kSupportedInternalFormatsStorage, | 237 kSupportedInternalFormatsStorage, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 180 m_boundCopyWriteBuffer = nullptr; | 257 m_boundCopyWriteBuffer = nullptr; |
| 181 m_boundPixelPackBuffer = nullptr; | 258 m_boundPixelPackBuffer = nullptr; |
| 182 m_boundPixelUnpackBuffer = nullptr; | 259 m_boundPixelUnpackBuffer = nullptr; |
| 183 m_boundTransformFeedbackBuffer = nullptr; | 260 m_boundTransformFeedbackBuffer = nullptr; |
| 184 m_boundUniformBuffer = nullptr; | 261 m_boundUniformBuffer = nullptr; |
| 185 | 262 |
| 186 m_currentBooleanOcclusionQuery = nullptr; | 263 m_currentBooleanOcclusionQuery = nullptr; |
| 187 m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr; | 264 m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr; |
| 188 } | 265 } |
| 189 | 266 |
| 267 void WebGL2RenderingContextBase::destroyContext() { | |
| 268 for (auto& callback : m_getBufferSubDataAsyncCallbacks) { | |
| 269 callback->destroy(); | |
| 270 } | |
| 271 m_getBufferSubDataAsyncCallbacks.clear(); | |
| 272 | |
| 273 WebGLRenderingContextBase::destroyContext(); | |
| 274 } | |
| 275 | |
| 190 void WebGL2RenderingContextBase::initializeNewContext() { | 276 void WebGL2RenderingContextBase::initializeNewContext() { |
| 191 ASSERT(!isContextLost()); | 277 ASSERT(!isContextLost()); |
| 192 ASSERT(drawingBuffer()); | 278 ASSERT(drawingBuffer()); |
| 193 | 279 |
| 194 m_readFramebufferBinding = nullptr; | 280 m_readFramebufferBinding = nullptr; |
| 195 | 281 |
| 196 m_boundCopyReadBuffer = nullptr; | 282 m_boundCopyReadBuffer = nullptr; |
| 197 m_boundCopyWriteBuffer = nullptr; | 283 m_boundCopyWriteBuffer = nullptr; |
| 198 m_boundPixelPackBuffer = nullptr; | 284 m_boundPixelPackBuffer = nullptr; |
| 199 m_boundPixelUnpackBuffer = nullptr; | 285 m_boundPixelUnpackBuffer = nullptr; |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 contextGL()->CopyBufferSubData( | 436 contextGL()->CopyBufferSubData( |
| 351 readTarget, writeTarget, static_cast<GLintptr>(readOffset), | 437 readTarget, writeTarget, static_cast<GLintptr>(readOffset), |
| 352 static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size)); | 438 static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size)); |
| 353 } | 439 } |
| 354 | 440 |
| 355 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, | 441 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, |
| 356 long long srcByteOffset, | 442 long long srcByteOffset, |
| 357 DOMArrayBufferView* dstData, | 443 DOMArrayBufferView* dstData, |
| 358 GLuint dstOffset, | 444 GLuint dstOffset, |
| 359 GLuint length) { | 445 GLuint length) { |
| 360 const char* funcName = "getBufferSubData"; | 446 WebGLBuffer* sourceBuffer = nullptr; |
| 361 if (isContextLost()) | 447 void* destinationDataPtr = nullptr; |
| 362 return; | 448 long long destinationByteLength = 0; |
| 363 if (!validateValueFitNonNegInt32(funcName, "srcByteOffset", srcByteOffset)) { | 449 const char* message = validateGetBufferSubData( |
| 450 __FUNCTION__, target, srcByteOffset, dstData, dstOffset, length, | |
| 451 &sourceBuffer, &destinationDataPtr, &destinationByteLength); | |
| 452 if (message) { | |
|
esprehn
2016/10/18 01:44:16
You drop the message on the floor here, should you
Kai Ninomiya
2016/10/19 17:54:10
Yeah, it's an already specified API and the spec d
| |
| 364 return; | 453 return; |
| 365 } | 454 } |
| 366 WebGLBuffer* buffer = validateBufferDataTarget(funcName, target); | 455 |
| 367 if (!buffer) | 456 // If the length of the copy is zero, this is a no-op. |
| 368 return; | 457 if (!destinationByteLength) { |
| 369 void* subBaseAddress = nullptr; | |
| 370 long long subByteLength = 0; | |
| 371 if (!validateSubSourceAndGetData(dstData, dstOffset, length, &subBaseAddress, | |
| 372 &subByteLength)) { | |
| 373 synthesizeGLError(GL_INVALID_VALUE, funcName, "buffer overflow"); | |
| 374 return; | |
| 375 } | |
| 376 if (subByteLength == 0) { | |
| 377 return; | 458 return; |
| 378 } | 459 } |
| 379 | 460 |
| 380 void* mappedData = | 461 void* mappedData = |
| 381 contextGL()->MapBufferRange(target, static_cast<GLintptr>(srcByteOffset), | 462 contextGL()->MapBufferRange(target, static_cast<GLintptr>(srcByteOffset), |
| 382 subByteLength, GL_MAP_READ_BIT); | 463 destinationByteLength, GL_MAP_READ_BIT); |
| 383 | 464 |
| 384 if (!mappedData) | 465 if (!mappedData) |
| 385 return; | 466 return; |
| 386 | 467 |
| 387 memcpy(subBaseAddress, mappedData, subByteLength); | 468 memcpy(destinationDataPtr, mappedData, destinationByteLength); |
| 388 | 469 |
| 389 contextGL()->UnmapBuffer(target); | 470 contextGL()->UnmapBuffer(target); |
| 390 } | 471 } |
| 391 | 472 |
| 473 ScriptPromise WebGL2RenderingContextBase::getBufferSubDataAsync( | |
| 474 ScriptState* scriptState, | |
| 475 GLenum target, | |
| 476 GLintptr srcByteOffset, | |
| 477 DOMArrayBufferView* dstData, | |
| 478 GLuint dstOffset, | |
| 479 GLuint length) { | |
| 480 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | |
| 481 ScriptPromise promise = resolver->promise(); | |
| 482 | |
| 483 WebGLBuffer* sourceBuffer = nullptr; | |
| 484 void* destinationDataPtr = nullptr; | |
| 485 long long destinationByteLength = 0; | |
| 486 const char* message = validateGetBufferSubData( | |
| 487 __FUNCTION__, target, srcByteOffset, dstData, dstOffset, length, | |
| 488 &sourceBuffer, &destinationDataPtr, &destinationByteLength); | |
| 489 if (message) { | |
| 490 DOMException* exception = DOMException::create(InvalidStateError, message); | |
| 491 resolver->reject(exception); | |
| 492 return promise; | |
| 493 } | |
| 494 | |
| 495 message = validateGetBufferSubDataBounds( | |
| 496 __FUNCTION__, sourceBuffer, srcByteOffset, destinationByteLength); | |
| 497 if (message) { | |
| 498 DOMException* exception = DOMException::create(InvalidStateError, message); | |
| 499 resolver->reject(exception); | |
| 500 return promise; | |
| 501 } | |
| 502 | |
| 503 // If the length of the copy is zero, this is a no-op. | |
| 504 if (!destinationByteLength) { | |
| 505 resolver->resolve(dstData); | |
| 506 return promise; | |
| 507 } | |
| 508 | |
| 509 GLuint queryID; | |
| 510 contextGL()->GenQueriesEXT(1, &queryID); | |
| 511 contextGL()->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, queryID); | |
| 512 void* mappedData = contextGL()->GetBufferSubDataAsyncCHROMIUM( | |
| 513 target, srcByteOffset, destinationByteLength); | |
| 514 contextGL()->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); | |
| 515 if (!mappedData) { | |
| 516 DOMException* exception = | |
| 517 DOMException::create(InvalidStateError, "Out of memory"); | |
| 518 resolver->reject(exception); | |
| 519 return promise; | |
| 520 } | |
| 521 | |
| 522 auto callbackObject = adoptRef(new WebGLGetBufferSubDataAsyncCallback( | |
| 523 this, resolver, mappedData, queryID, dstData, destinationDataPtr, | |
| 524 destinationByteLength)); | |
| 525 registerGetBufferSubDataAsyncCallback(callbackObject.get()); | |
| 526 auto callback = | |
| 527 WTF::bind(&WebGLGetBufferSubDataAsyncCallback::resolve, callbackObject); | |
| 528 drawingBuffer()->contextProvider()->signalQuery( | |
| 529 queryID, convertToBaseCallback(std::move(callback))); | |
| 530 | |
| 531 return promise; | |
| 532 } | |
| 533 | |
| 534 void WebGL2RenderingContextBase::registerGetBufferSubDataAsyncCallback( | |
| 535 WebGLGetBufferSubDataAsyncCallback* callback) { | |
| 536 m_getBufferSubDataAsyncCallbacks.insert(callback); | |
| 537 } | |
| 538 | |
| 539 void WebGL2RenderingContextBase::unregisterGetBufferSubDataAsyncCallback( | |
| 540 WebGLGetBufferSubDataAsyncCallback* callback) { | |
| 541 m_getBufferSubDataAsyncCallbacks.erase(callback); | |
| 542 } | |
| 543 | |
| 392 void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0, | 544 void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0, |
| 393 GLint srcY0, | 545 GLint srcY0, |
| 394 GLint srcX1, | 546 GLint srcX1, |
| 395 GLint srcY1, | 547 GLint srcY1, |
| 396 GLint dstX0, | 548 GLint dstX0, |
| 397 GLint dstY0, | 549 GLint dstY0, |
| 398 GLint dstX1, | 550 GLint dstX1, |
| 399 GLint dstY1, | 551 GLint dstY1, |
| 400 GLbitfield mask, | 552 GLbitfield mask, |
| 401 GLenum filter) { | 553 GLenum filter) { |
| (...skipping 4010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4412 case GL_STATIC_COPY: | 4564 case GL_STATIC_COPY: |
| 4413 case GL_DYNAMIC_READ: | 4565 case GL_DYNAMIC_READ: |
| 4414 case GL_DYNAMIC_COPY: | 4566 case GL_DYNAMIC_COPY: |
| 4415 return true; | 4567 return true; |
| 4416 default: | 4568 default: |
| 4417 return WebGLRenderingContextBase::validateBufferDataUsage(functionName, | 4569 return WebGLRenderingContextBase::validateBufferDataUsage(functionName, |
| 4418 usage); | 4570 usage); |
| 4419 } | 4571 } |
| 4420 } | 4572 } |
| 4421 | 4573 |
| 4574 const char* WebGL2RenderingContextBase::validateGetBufferSubData( | |
| 4575 const char* functionName, | |
| 4576 GLenum target, | |
| 4577 GLintptr sourceByteOffset, | |
| 4578 DOMArrayBufferView* destinationArrayBufferView, | |
| 4579 GLuint destinationOffset, | |
| 4580 GLuint length, | |
| 4581 WebGLBuffer** outSourceBuffer, | |
| 4582 void** outDestinationDataPtr, | |
| 4583 long long* outDestinationByteLength) { | |
| 4584 if (isContextLost()) { | |
| 4585 return "Context lost"; | |
| 4586 } | |
| 4587 | |
| 4588 if (!validateValueFitNonNegInt32(functionName, "srcByteOffset", | |
| 4589 sourceByteOffset)) { | |
| 4590 return "Invalid value: srcByteOffset"; | |
| 4591 } | |
| 4592 | |
| 4593 if (target == GL_TRANSFORM_FEEDBACK_BUFFER && m_transformFeedbackBinding) { | |
| 4594 synthesizeGLError(GL_INVALID_OPERATION, functionName, | |
| 4595 "targeted transform feedback buffer is bound"); | |
| 4596 return "Invalid operation: targeted transform feedback buffer is bound"; | |
| 4597 } | |
| 4598 | |
| 4599 WebGLBuffer* sourceBuffer = validateBufferDataTarget(functionName, target); | |
| 4600 if (!sourceBuffer) { | |
| 4601 return "Invalid operation: no buffer bound to target"; | |
| 4602 } | |
| 4603 *outSourceBuffer = sourceBuffer; | |
| 4604 | |
| 4605 if (!validateSubSourceAndGetData( | |
| 4606 destinationArrayBufferView, destinationOffset, length, | |
| 4607 outDestinationDataPtr, outDestinationByteLength)) { | |
| 4608 synthesizeGLError(GL_INVALID_VALUE, functionName, "overflow of dstData"); | |
| 4609 return "Invalid value: overflow of dstData"; | |
| 4610 } | |
| 4611 | |
| 4612 return nullptr; | |
| 4613 } | |
| 4614 | |
| 4615 const char* WebGL2RenderingContextBase::validateGetBufferSubDataBounds( | |
| 4616 const char* functionName, | |
| 4617 WebGLBuffer* sourceBuffer, | |
| 4618 GLintptr srcByteOffset, | |
| 4619 long long subByteLength) { | |
| 4620 CheckedNumeric<long long> srcEnd = srcByteOffset; | |
| 4621 srcEnd += subByteLength; | |
| 4622 if (!srcEnd.IsValid() || srcEnd.ValueOrDie() > sourceBuffer->getSize()) { | |
| 4623 synthesizeGLError(GL_INVALID_VALUE, functionName, | |
| 4624 "overflow of bound buffer"); | |
| 4625 return "Invalid value: overflow of bound buffer"; | |
| 4626 } | |
| 4627 | |
| 4628 return nullptr; | |
| 4629 } | |
| 4630 | |
| 4422 void WebGL2RenderingContextBase::removeBoundBuffer(WebGLBuffer* buffer) { | 4631 void WebGL2RenderingContextBase::removeBoundBuffer(WebGLBuffer* buffer) { |
| 4423 if (m_boundCopyReadBuffer == buffer) | 4632 if (m_boundCopyReadBuffer == buffer) |
| 4424 m_boundCopyReadBuffer = nullptr; | 4633 m_boundCopyReadBuffer = nullptr; |
| 4425 if (m_boundCopyWriteBuffer == buffer) | 4634 if (m_boundCopyWriteBuffer == buffer) |
| 4426 m_boundCopyWriteBuffer = nullptr; | 4635 m_boundCopyWriteBuffer = nullptr; |
| 4427 if (m_boundPixelPackBuffer == buffer) | 4636 if (m_boundPixelPackBuffer == buffer) |
| 4428 m_boundPixelPackBuffer = nullptr; | 4637 m_boundPixelPackBuffer = nullptr; |
| 4429 if (m_boundPixelUnpackBuffer == buffer) | 4638 if (m_boundPixelUnpackBuffer == buffer) |
| 4430 m_boundPixelUnpackBuffer = nullptr; | 4639 m_boundPixelUnpackBuffer = nullptr; |
| 4431 if (m_boundTransformFeedbackBuffer == buffer) | 4640 if (m_boundTransformFeedbackBuffer == buffer) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4505 params.skipPixels = m_unpackSkipPixels; | 4714 params.skipPixels = m_unpackSkipPixels; |
| 4506 params.skipRows = m_unpackSkipRows; | 4715 params.skipRows = m_unpackSkipRows; |
| 4507 if (dimension == Tex3D) { | 4716 if (dimension == Tex3D) { |
| 4508 params.imageHeight = m_unpackImageHeight; | 4717 params.imageHeight = m_unpackImageHeight; |
| 4509 params.skipImages = m_unpackSkipImages; | 4718 params.skipImages = m_unpackSkipImages; |
| 4510 } | 4719 } |
| 4511 return params; | 4720 return params; |
| 4512 } | 4721 } |
| 4513 | 4722 |
| 4514 } // namespace blink | 4723 } // namespace blink |
| OLD | NEW |