summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/canvas/WebGLBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/canvas/WebGLBuffer.cpp')
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp142
1 files changed, 113 insertions, 29 deletions
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
index 3421e979c..bc914a4a7 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,28 +24,24 @@
*/
#include "config.h"
+#include "WebGLBuffer.h"
#if ENABLE(WEBGL)
-#include "WebGLBuffer.h"
-
#include "WebGLContextGroup.h"
-#include "WebGLRenderingContext.h"
+#include "WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+Ref<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContextBase& ctx)
{
- return adoptRef(new WebGLBuffer(ctx));
+ return adoptRef(*new WebGLBuffer(ctx));
}
-WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase& ctx)
: WebGLSharedObject(ctx)
- , m_target(0)
- , m_byteLength(0)
- , m_nextAvailableCacheEntry(0)
{
- setObject(ctx->graphicsContext3D()->createBuffer());
+ setObject(ctx.graphicsContext3D()->createBuffer());
clearCachedMaxIndices();
}
@@ -56,7 +52,7 @@ WebGLBuffer::~WebGLBuffer()
void WebGLBuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
- context3d->deleteBuffer(object);
+ context3d->deleteBuffer(object);
}
bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLength)
@@ -69,7 +65,7 @@ bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLen
m_byteLength = byteLength;
clearCachedMaxIndices();
if (byteLength) {
- m_elementArrayBuffer = ArrayBuffer::create(byteLength, 1);
+ m_elementArrayBuffer = ArrayBuffer::tryCreate(byteLength, 1);
if (!m_elementArrayBuffer) {
m_byteLength = 0;
return false;
@@ -81,19 +77,31 @@ bool WebGLBuffer::associateBufferDataImpl(const void* data, GC3Dsizeiptr byteLen
memcpy(m_elementArrayBuffer->data(), data, byteLength);
}
} else
- m_elementArrayBuffer = 0;
+ m_elementArrayBuffer = nullptr;
return true;
case GraphicsContext3D::ARRAY_BUFFER:
m_byteLength = byteLength;
return true;
default:
+#if ENABLE(WEBGL2)
+ switch (m_target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ m_byteLength = byteLength;
+ return true;
+ }
+#endif
return false;
}
}
bool WebGLBuffer::associateBufferData(GC3Dsizeiptr size)
{
- return associateBufferDataImpl(0, size);
+ return associateBufferDataImpl(nullptr, size);
}
bool WebGLBuffer::associateBufferData(ArrayBuffer* array)
@@ -135,6 +143,17 @@ bool WebGLBuffer::associateBufferSubDataImpl(GC3Dintptr offset, const void* data
case GraphicsContext3D::ARRAY_BUFFER:
return true;
default:
+#if ENABLE(WEBGL2)
+ switch (m_target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ return true;
+ }
+#endif
return false;
}
}
@@ -153,39 +172,104 @@ bool WebGLBuffer::associateBufferSubData(GC3Dintptr offset, ArrayBufferView* arr
return associateBufferSubDataImpl(offset, array->baseAddress(), array->byteLength());
}
+bool WebGLBuffer::associateCopyBufferSubData(const WebGLBuffer& readBuffer, GC3Dintptr readOffset, GC3Dintptr writeOffset, GC3Dsizeiptr size)
+{
+ if (readOffset < 0 || writeOffset < 0 || size < 0)
+ return false;
+
+ if (size) {
+ Checked<GC3Dintptr, RecordOverflow> checkedReadBufferOffset(readOffset);
+ Checked<GC3Dsizeiptr, RecordOverflow> checkedDataLength(size);
+ Checked<GC3Dintptr, RecordOverflow> checkedReadBufferMax = checkedReadBufferOffset + checkedDataLength;
+ if (checkedReadBufferMax.hasOverflowed() || readOffset > readBuffer.byteLength() || checkedReadBufferMax.unsafeGet() > readBuffer.byteLength())
+ return false;
+
+ Checked<GC3Dintptr, RecordOverflow> checkedWriteBufferOffset(writeOffset);
+ Checked<GC3Dintptr, RecordOverflow> checkedWriteBufferMax = checkedWriteBufferOffset + checkedDataLength;
+ if (checkedWriteBufferMax.hasOverflowed() || writeOffset > m_byteLength || checkedWriteBufferMax.unsafeGet() > m_byteLength)
+ return false;
+ }
+
+ switch (m_target) {
+ case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
+ clearCachedMaxIndices();
+ if (size) {
+ if (!m_elementArrayBuffer)
+ return false;
+ memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + writeOffset, static_cast<const unsigned char*>(readBuffer.elementArrayBuffer()->data()) + readOffset, size);
+ }
+ return true;
+ case GraphicsContext3D::ARRAY_BUFFER:
+ return true;
+ default:
+#if ENABLE(WEBGL2)
+ switch (m_target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ return true;
+ }
+#endif
+ return false;
+ }
+}
+
+void WebGLBuffer::disassociateBufferData()
+{
+ m_byteLength = 0;
+ clearCachedMaxIndices();
+}
+
GC3Dsizeiptr WebGLBuffer::byteLength() const
{
return m_byteLength;
}
-int WebGLBuffer::getCachedMaxIndex(GC3Denum type)
+std::optional<unsigned> WebGLBuffer::getCachedMaxIndex(GC3Denum type)
{
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_maxIndexCache); ++i)
- if (m_maxIndexCache[i].type == type)
- return m_maxIndexCache[i].maxIndex;
- return -1;
+ for (auto& cache : m_maxIndexCache) {
+ if (cache.type == type)
+ return cache.maxIndex;
+ }
+ return std::nullopt;
}
-void WebGLBuffer::setCachedMaxIndex(GC3Denum type, int value)
+void WebGLBuffer::setCachedMaxIndex(GC3Denum type, unsigned value)
{
- size_t numEntries = WTF_ARRAY_LENGTH(m_maxIndexCache);
- for (size_t i = 0; i < numEntries; ++i)
- if (m_maxIndexCache[i].type == type) {
- m_maxIndexCache[i].maxIndex = value;
+ for (auto& cache : m_maxIndexCache) {
+ if (cache.type == type) {
+ cache.maxIndex = value;
return;
}
+ }
m_maxIndexCache[m_nextAvailableCacheEntry].type = type;
m_maxIndexCache[m_nextAvailableCacheEntry].maxIndex = value;
- m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % numEntries;
+ m_nextAvailableCacheEntry = (m_nextAvailableCacheEntry + 1) % WTF_ARRAY_LENGTH(m_maxIndexCache);
}
-void WebGLBuffer::setTarget(GC3Denum target)
+void WebGLBuffer::setTarget(GC3Denum target, bool forWebGL2)
{
// In WebGL, a buffer is bound to one target in its lifetime
if (m_target)
return;
if (target == GraphicsContext3D::ARRAY_BUFFER || target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
m_target = target;
+ else if (forWebGL2) {
+#if ENABLE(WEBGL2)
+ switch (target) {
+ case GraphicsContext3D::COPY_READ_BUFFER:
+ case GraphicsContext3D::COPY_WRITE_BUFFER:
+ case GraphicsContext3D::PIXEL_PACK_BUFFER:
+ case GraphicsContext3D::PIXEL_UNPACK_BUFFER:
+ case GraphicsContext3D::TRANSFORM_FEEDBACK_BUFFER:
+ case GraphicsContext3D::UNIFORM_BUFFER:
+ m_target = target;
+ }
+#endif
+ }
}
void WebGLBuffer::clearCachedMaxIndices()