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 "config.h" | 5 #include "config.h" |
6 #include "modules/webgl/WebGL2RenderingContextBase.h" | 6 #include "modules/webgl/WebGL2RenderingContextBase.h" |
7 | 7 |
8 #include "bindings/modules/v8/WebGLAny.h" | 8 #include "bindings/modules/v8/WebGLAny.h" |
9 #include "core/html/HTMLCanvasElement.h" | 9 #include "core/html/HTMLCanvasElement.h" |
10 #include "core/html/HTMLImageElement.h" | 10 #include "core/html/HTMLImageElement.h" |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 } | 111 } |
112 | 112 |
113 WebGLBuffer* readBuffer = validateBufferDataTarget("copyBufferSubData", read
Target); | 113 WebGLBuffer* readBuffer = validateBufferDataTarget("copyBufferSubData", read
Target); |
114 if (!readBuffer) | 114 if (!readBuffer) |
115 return; | 115 return; |
116 | 116 |
117 WebGLBuffer* writeBuffer = validateBufferDataTarget("copyBufferSubData", wri
teTarget); | 117 WebGLBuffer* writeBuffer = validateBufferDataTarget("copyBufferSubData", wri
teTarget); |
118 if (!writeBuffer) | 118 if (!writeBuffer) |
119 return; | 119 return; |
120 | 120 |
| 121 if (readOffset + size > readBuffer->getSize() || writeOffset + size > writeB
uffer->getSize()) { |
| 122 synthesizeGLError(GL_INVALID_VALUE, "copyBufferSubData", "buffer overflo
w"); |
| 123 return; |
| 124 } |
| 125 |
121 if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffe
r->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER) | 126 if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffe
r->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER) |
122 || (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBu
ffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) { | 127 || (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBu
ffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) { |
123 synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot cop
y into an element buffer destination from a non-element buffer source"); | 128 synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot cop
y into an element buffer destination from a non-element buffer source"); |
124 return; | 129 return; |
125 } | 130 } |
126 | 131 |
127 if (writeBuffer->getInitialTarget() == 0) | 132 if (writeBuffer->getInitialTarget() == 0) |
128 writeBuffer->setInitialTarget(readBuffer->getInitialTarget()); | 133 writeBuffer->setInitialTarget(readBuffer->getInitialTarget()); |
129 | 134 |
130 webContext()->copyBufferSubData(readTarget, writeTarget, static_cast<GLintpt
r>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size
)); | 135 webContext()->copyBufferSubData(readTarget, writeTarget, static_cast<GLintpt
r>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size
)); |
131 } | 136 } |
132 | 137 |
133 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse
t, DOMArrayBuffer* returnedData) | 138 void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse
t, DOMArrayBuffer* returnedData) |
134 { | 139 { |
135 if (isContextLost()) | 140 if (isContextLost()) |
136 return; | 141 return; |
137 | 142 |
138 if (!returnedData) { | 143 if (!returnedData) { |
139 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer can
not be null"); | 144 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer can
not be null"); |
140 return; | 145 return; |
141 } | 146 } |
142 | 147 |
143 if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) { | 148 if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) { |
144 return; | 149 return; |
145 } | 150 } |
146 | 151 |
| 152 WebGLBuffer* buffer = validateBufferDataTarget("getBufferSubData", target); |
| 153 if (!buffer) |
| 154 return; |
| 155 if (offset + returnedData->byteLength() > buffer->getSize()) { |
| 156 synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "buffer overflow
"); |
| 157 return; |
| 158 } |
| 159 |
147 void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr
>(offset), returnedData->byteLength(), GL_MAP_READ_BIT); | 160 void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr
>(offset), returnedData->byteLength(), GL_MAP_READ_BIT); |
148 | 161 |
149 if (!mappedData) | 162 if (!mappedData) |
150 return; | 163 return; |
151 | 164 |
152 memcpy(returnedData->data(), mappedData, returnedData->byteLength()); | 165 memcpy(returnedData->data(), mappedData, returnedData->byteLength()); |
153 | 166 |
154 webContext()->unmapBuffer(target); | 167 webContext()->unmapBuffer(target); |
155 } | 168 } |
156 | 169 |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 return false; | 515 return false; |
503 } | 516 } |
504 | 517 |
505 WebGLTexture* tex = validateTextureBinding(functionName, target, false); | 518 WebGLTexture* tex = validateTextureBinding(functionName, target, false); |
506 if (!tex) | 519 if (!tex) |
507 return false; | 520 return false; |
508 | 521 |
509 if (!validateTexFuncLevel(functionName, target, level)) | 522 if (!validateTexFuncLevel(functionName, target, level)) |
510 return false; | 523 return false; |
511 | 524 |
512 if (width - xoffset > tex->getWidth(target, level) | 525 // Before checking if it is in the range, check if overflow happens first. |
513 || height - yoffset > tex->getHeight(target, level) | 526 Checked<GLint, RecordOverflow> maxX = xoffset, maxY = yoffset, maxZ = zoffse
t; |
514 || depth - zoffset > tex->getDepth(target, level)) { | 527 maxX += width; |
515 synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of
range"); | 528 maxY += height; |
| 529 maxZ += depth; |
| 530 if (maxX.hasOverflowed() || maxY.hasOverflowed() || maxZ.hasOverflowed() |
| 531 || maxX.unsafeGet() > tex->getWidth(target, level) |
| 532 || maxY.unsafeGet() > tex->getHeight(target, level) |
| 533 || maxZ.unsafeGet() > tex->getDepth(target, level)) { |
| 534 synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of ran
ge"); |
516 return false; | 535 return false; |
517 } | 536 } |
518 | 537 |
519 GLenum internalformat = tex->getInternalFormat(target, level); | 538 GLenum internalformat = tex->getInternalFormat(target, level); |
520 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type
, level)) | 539 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type
, level)) |
521 return false; | 540 return false; |
522 | 541 |
523 return true; | 542 return true; |
524 } | 543 } |
525 | 544 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 } | 621 } |
603 if (m_unpackAlignment != 1) | 622 if (m_unpackAlignment != 1) |
604 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1); | 623 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1); |
605 webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels
->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pix
els->data()->data()); | 624 webContext()->texSubImage3D(target, level, xoffset, yoffset, zoffset, pixels
->width(), pixels->height(), 1, format, type, needConversion ? data.data() : pix
els->data()->data()); |
606 if (m_unpackAlignment != 1) | 625 if (m_unpackAlignment != 1) |
607 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); | 626 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); |
608 } | 627 } |
609 | 628 |
610 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageEle
ment* image, ExceptionState& exceptionState) | 629 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageEle
ment* image, ExceptionState& exceptionState) |
611 { | 630 { |
612 if (isContextLost() || !image || !validateTexSubImage3D("texSubImage3D", tar
get, level, xoffset, yoffset, zoffset, format, type, image->width(), image->heig
ht(), 1)) | 631 if (isContextLost() || !image || !validateHTMLImageElement("texSubImage3D",
image, exceptionState)) |
613 return; | |
614 | |
615 if (isContextLost() || !validateHTMLImageElement("texSubImage3D", image, exc
eptionState)) | |
616 return; | 632 return; |
617 | 633 |
618 RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(im
age->layoutObject()); | 634 RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(im
age->layoutObject()); |
619 if (imageForRender->isSVGImage()) | 635 if (imageForRender->isSVGImage()) |
620 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(
), image->height(), "texSubImage3D"); | 636 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(
), image->height(), "texSubImage3D"); |
621 | 637 |
622 texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, im
ageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackP
remultiplyAlpha); | 638 texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, im
ageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackP
remultiplyAlpha); |
623 } | 639 } |
624 | 640 |
625 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasEl
ement* canvas, ExceptionState& exceptionState) | 641 void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLCanvasEl
ement* canvas, ExceptionState& exceptionState) |
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1674 bool deleted; | 1690 bool deleted; |
1675 if (!checkObjectToBeBound("bindBufferRange", buffer, deleted)) | 1691 if (!checkObjectToBeBound("bindBufferRange", buffer, deleted)) |
1676 return; | 1692 return; |
1677 if (deleted) | 1693 if (deleted) |
1678 buffer = 0; | 1694 buffer = 0; |
1679 if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset) | 1695 if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset) |
1680 || !validateValueFitNonNegInt32("bindBufferRange", "size", size)) { | 1696 || !validateValueFitNonNegInt32("bindBufferRange", "size", size)) { |
1681 return; | 1697 return; |
1682 } | 1698 } |
1683 | 1699 |
1684 if (!validateAndUpdateBufferBindBaseTarget("bindBufferRange", target, index,
buffer)) | 1700 if (buffer && (offset + size > buffer->getSize())) { |
| 1701 synthesizeGLError(GL_INVALID_VALUE, "bindBufferRange", "buffer overflow"
); |
1685 return; | 1702 return; |
| 1703 } |
1686 | 1704 |
1687 webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_ca
st<GLintptr>(offset), static_cast<GLsizeiptr>(size)); | 1705 webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_ca
st<GLintptr>(offset), static_cast<GLsizeiptr>(size)); |
1688 } | 1706 } |
1689 | 1707 |
1690 ScriptValue WebGL2RenderingContextBase::getIndexedParameter(ScriptState* scriptS
tate, GLenum target, GLuint index) | 1708 ScriptValue WebGL2RenderingContextBase::getIndexedParameter(ScriptState* scriptS
tate, GLenum target, GLuint index) |
1691 { | 1709 { |
1692 if (isContextLost()) | 1710 if (isContextLost()) |
1693 return ScriptValue::createNull(scriptState); | 1711 return ScriptValue::createNull(scriptState); |
1694 | 1712 |
1695 switch (target) { | 1713 switch (target) { |
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2723 GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat() | 2741 GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat() |
2724 { | 2742 { |
2725 if (m_readFramebufferBinding && m_readFramebufferBinding->object()) | 2743 if (m_readFramebufferBinding && m_readFramebufferBinding->object()) |
2726 return m_readFramebufferBinding->colorBufferFormat(); | 2744 return m_readFramebufferBinding->colorBufferFormat(); |
2727 if (m_requestedAttributes.alpha()) | 2745 if (m_requestedAttributes.alpha()) |
2728 return GL_RGBA; | 2746 return GL_RGBA; |
2729 return GL_RGB; | 2747 return GL_RGB; |
2730 } | 2748 } |
2731 | 2749 |
2732 } // namespace blink | 2750 } // namespace blink |
OLD | NEW |