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

Unified Diff: third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp

Issue 2266563002: Implement buffer{Sub}Data overloads with sub source. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index b3eabd11b014fe35add63b9d0e4bf2b2c390d7cd..9a84f98e2777968e04385952256419bf1a4b64b9 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -41,6 +41,62 @@ GLsync syncObjectOrZero(const WebGLSync* object)
return object ? object->object() : nullptr;
}
+size_t getViewTypeSize(WTF::ArrayBufferView::ViewType viewType)
+{
+ switch (viewType) {
+ case WTF::ArrayBufferView::TypeInt8:
+ case WTF::ArrayBufferView::TypeUint8:
+ case WTF::ArrayBufferView::TypeUint8Clamped:
+ return 1;
+ case WTF::ArrayBufferView::TypeInt16:
+ case WTF::ArrayBufferView::TypeUint16:
+ return 2;
+ case WTF::ArrayBufferView::TypeInt32:
+ case WTF::ArrayBufferView::TypeUint32:
+ case WTF::ArrayBufferView::TypeFloat32:
+ return 4;
+ case WTF::ArrayBufferView::TypeFloat64:
+ return 8;
+ case WTF::ArrayBufferView::TypeDataView:
+ return 1;
+ default:
+ NOTREACHED();
+ return 0;
+ }
+}
+
+bool validateSubSourceAndGetData(DOMArrayBufferView* view, GLuint subOffset, GLuint subLength, void** outBaseAddress, long long* outByteLength)
+{
+ // This is guaranteed to be non-null by DOM.
+ DCHECK(view);
+
+ size_t typeSize = getViewTypeSize(view->type());
+ DCHECK_GE(8u, typeSize);
+ long long byteLength = 0;
+ if (subLength) {
+ // type size is at most 8, so no overflow.
+ byteLength = subLength * typeSize;
+ }
+ long long byteOffset = 0;
+ if (subOffset) {
+ // type size is at most 8, so no overflow.
+ byteOffset = subOffset * typeSize;
+ }
+ CheckedInt<long long> total = byteOffset;
+ total += byteLength;
+ if (!total.isValid() || total.value() > view->byteLength()) {
+ return false;
+ }
+ if (!byteLength) {
+ byteLength = view->byteLength() - byteOffset;
+ }
+ uint8_t* data = static_cast<uint8_t*>(view->baseAddress());
+ data += byteOffset;
+ *outBaseAddress = data;
+ *outByteLength = byteLength;
+ return true;
+}
+
} // namespace
// These enums are from manual pages for glTexStorage2D/glTexStorage3D.
@@ -183,6 +239,57 @@ void WebGL2RenderingContextBase::initializeNewContext()
WebGLRenderingContextBase::initializeNewContext();
}
+void WebGL2RenderingContextBase::bufferData(GLenum target, DOMArrayBufferView* srcData, GLenum usage, GLuint srcOffset, GLuint length)
+{
+ if (isContextLost())
+ return;
+ void* subBaseAddress = nullptr;
+ long long subByteLength = 0;
+ if (!validateSubSourceAndGetData(srcData, srcOffset, length, &subBaseAddress, &subByteLength)) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "srcOffset + length too large");
+ return;
+ }
+ bufferDataImpl(target, subByteLength, subBaseAddress, usage);
+}
+
+void WebGL2RenderingContextBase::bufferData(GLenum target, long long size, GLenum usage)
+{
+ WebGLRenderingContextBase::bufferData(target, size, usage);
+}
+
+void WebGL2RenderingContextBase::bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage)
+{
+ WebGLRenderingContextBase::bufferData(target, data, usage);
+}
+
+void WebGL2RenderingContextBase::bufferData(GLenum target, DOMArrayBufferView* data, GLenum usage)
+{
+ WebGLRenderingContextBase::bufferData(target, data, usage);
+}
+
+void WebGL2RenderingContextBase::bufferSubData(GLenum target, GLintptr dstByteOffset, DOMArrayBufferView* srcData, GLuint srcOffset, GLuint length)
+{
+ if (isContextLost())
+ return;
+ void* subBaseAddress = nullptr;
+ long long subByteLength = 0;
+ if (!validateSubSourceAndGetData(srcData, srcOffset, length, &subBaseAddress, &subByteLength)) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "srcOffset + length too large");
+ return;
+ }
+ bufferSubDataImpl(target, dstByteOffset, subByteLength, subBaseAddress);
+}
+
+void WebGL2RenderingContextBase::bufferSubData(GLenum target, long long offset, DOMArrayBuffer* data)
+{
+ WebGLRenderingContextBase::bufferSubData(target, offset, data);
+}
+
+void WebGL2RenderingContextBase::bufferSubData(GLenum target, long long offset, const FlexibleArrayBufferView& data)
+{
+ WebGLRenderingContextBase::bufferSubData(target, offset, data);
+}
+
void WebGL2RenderingContextBase::copyBufferSubData(GLenum readTarget, GLenum writeTarget, long long readOffset, long long writeOffset, long long size)
{
if (isContextLost())
@@ -219,38 +326,62 @@ void WebGL2RenderingContextBase::copyBufferSubData(GLenum readTarget, GLenum wri
contextGL()->CopyBufferSubData(readTarget, writeTarget, static_cast<GLintptr>(readOffset), static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size));
}
-void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offset, DOMArrayBuffer* returnedData)
+void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long srcByteOffset, DOMArrayBufferView* dstData, GLuint dstOffset, GLuint length)
{
+ const char* funcName = "getBufferSubData";
if (isContextLost())
return;
-
- if (!returnedData) {
- synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "ArrayBuffer cannot be null");
- return;
- }
-
- if (!validateValueFitNonNegInt32("getBufferSubData", "offset", offset)) {
+ if (!validateValueFitNonNegInt32(funcName, "srcByteOffset", srcByteOffset)) {
return;
}
-
- WebGLBuffer* buffer = validateBufferDataTarget("getBufferSubData", target);
+ WebGLBuffer* buffer = validateBufferDataTarget(funcName, target);
if (!buffer)
return;
- if (offset + returnedData->byteLength() > buffer->getSize()) {
- synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "buffer overflow");
+ void* subBaseAddress = nullptr;
+ long long subByteLength = 0;
+ if (!validateSubSourceAndGetData(dstData, dstOffset, length, &subBaseAddress, &subByteLength)) {
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "buffer overflow");
return;
}
- void* mappedData = contextGL()->MapBufferRange(target, static_cast<GLintptr>(offset), returnedData->byteLength(), GL_MAP_READ_BIT);
+ void* mappedData = contextGL()->MapBufferRange(target, static_cast<GLintptr>(srcByteOffset), subByteLength, GL_MAP_READ_BIT);
if (!mappedData)
return;
- memcpy(returnedData->data(), mappedData, returnedData->byteLength());
+ memcpy(subBaseAddress, mappedData, subByteLength);
contextGL()->UnmapBuffer(target);
}
+void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long srcByteOffset, DOMArrayBuffer* dstData)
+{
+ const char* funcName = "getBufferSubData";
+ if (isContextLost())
+ return;
+
+ if (!dstData) {
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "ArrayBuffer can not be null");
+ return;
+ }
+ if (!validateValueFitNonNegInt32(funcName, "srcByteOffset", srcByteOffset)) {
+ return;
+ }
+ WebGLBuffer* buffer = validateBufferDataTarget(funcName, target);
+ if (!buffer)
+ return;
+ if (srcByteOffset + dstData->byteLength() > buffer->getSize()) {
+ synthesizeGLError(GL_INVALID_VALUE, funcName, "buffer overflow");
+ return;
+ }
+
+ void* mappedData = contextGL()->MapBufferRange(target, static_cast<GLintptr>(srcByteOffset), dstData->byteLength(), GL_MAP_READ_BIT);
+ if (!mappedData)
+ return;
+ memcpy(dstData->data(), mappedData, dstData->byteLength());
+ contextGL()->UnmapBuffer(target);
+}
+
void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
if (isContextLost())

Powered by Google App Engine
This is Rietveld 408576698