void WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset, size_t dataLen, const uint8_t* data) { const char funcName[] = "bufferSubData"; if (!ValidateNonNegative(funcName, "byteOffset", dstByteOffset)) return; const auto& buffer = ValidateBufferSelection(funcName, target); if (!buffer) return; if (!buffer->ValidateRange(funcName, dstByteOffset, dataLen)) return; if (!CheckedInt<GLintptr>(dataLen).isValid()) { ErrorOutOfMemory("%s: Size too large.", funcName); return; } const GLintptr glDataLen(dataLen); //// MakeContextCurrent(); const ScopedLazyBind lazyBind(gl, target, buffer); // Warning: Possibly shared memory. See bug 1225033. gl->fBufferSubData(target, dstByteOffset, glDataLen, data); // Warning: Possibly shared memory. See bug 1225033. buffer->ElementArrayCacheBufferSubData(dstByteOffset, data, size_t(glDataLen)); }
void WebGLContext::BufferDataImpl(GLenum target, uint64_t dataLen, const uint8_t* data, GLenum usage) { const auto& buffer = ValidateBufferSelection(target); if (!buffer) return; buffer->BufferData(target, dataLen, data, usage); }
void WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset, uint64_t dataLen, const uint8_t* data) { const FuncScope funcScope(*this, "bufferSubData"); if (!ValidateNonNegative("byteOffset", dstByteOffset)) return; const auto& buffer = ValidateBufferSelection(target); if (!buffer) return; buffer->BufferSubData(target, uint64_t(dstByteOffset), dataLen, data); }
void WebGLContext::BufferDataImpl(GLenum target, size_t dataLen, const uint8_t* data, GLenum usage) { const char funcName[] = "bufferData"; const auto& buffer = ValidateBufferSelection(funcName, target); if (!buffer) return; buffer->BufferData(target, dataLen, data, usage); }
void WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBufferView& data) { const char funcName[] = "getBufferSubData"; if (IsContextLost()) return; if (!ValidateNonNegative(funcName, "offset", offset)) return; const auto& buffer = ValidateBufferSelection(funcName, target); if (!buffer) return; //// // If offset + returnedData.byteLength would extend beyond the end // of the buffer an INVALID_VALUE error is generated. data.ComputeLengthAndData(); const auto neededByteLength = CheckedInt<size_t>(offset) + data.LengthAllowShared(); if (!neededByteLength.isValid()) { ErrorInvalidValue("%s: Integer overflow computing the needed byte length.", funcName); return; } if (neededByteLength.value() > buffer->ByteLength()) { ErrorInvalidValue("%s: Not enough data. Operation requires %d bytes, but buffer" " only has %d bytes.", funcName, neededByteLength.value(), buffer->ByteLength()); return; } //// if (buffer->mNumActiveTFOs) { ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" " object.", funcName); return; } if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER && mBoundTransformFeedback->mIsActive) { ErrorInvalidOperation("%s: Currently bound transform feedback is active.", funcName); return; } //// gl->MakeCurrent(); const auto ptr = gl->fMapBufferRange(target, offset, data.LengthAllowShared(), LOCAL_GL_MAP_READ_BIT); // Warning: Possibly shared memory. See bug 1225033. memcpy(data.DataAllowShared(), ptr, data.LengthAllowShared()); gl->fUnmapBuffer(target); }
void WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { const char funcName[] = "copyBufferSubData"; if (IsContextLost()) return; const auto& readBuffer = ValidateBufferSelection(funcName, readTarget); if (!readBuffer) return; const auto& writeBuffer = ValidateBufferSelection(funcName, writeTarget); if (!writeBuffer) return; if (readBuffer->mNumActiveTFOs || writeBuffer->mNumActiveTFOs) { ErrorInvalidOperation("%s: Buffer is bound to an active transform feedback" " object.", funcName); return; } if (!ValidateNonNegative(funcName, "readOffset", readOffset) || !ValidateNonNegative(funcName, "writeOffset", writeOffset) || !ValidateNonNegative(funcName, "size", size)) { return; } const auto fnValidateOffsetSize = [&](const char* info, GLintptr offset, const WebGLBuffer* buffer) { const auto neededBytes = CheckedInt<size_t>(offset) + size; if (!neededBytes.isValid() || neededBytes.value() > buffer->ByteLength()) { ErrorInvalidValue("%s: Invalid %s range.", funcName, info); return false; } return true; }; if (!fnValidateOffsetSize("read", readOffset, readBuffer) || !fnValidateOffsetSize("write", writeOffset, writeBuffer)) { return; } if (readBuffer == writeBuffer && !ValidateDataRanges(readOffset, writeOffset, size, funcName)) { return; } const auto& readType = readBuffer->Content(); const auto& writeType = writeBuffer->Content(); MOZ_ASSERT(readType != WebGLBuffer::Kind::Undefined); MOZ_ASSERT(writeType != WebGLBuffer::Kind::Undefined); if (writeType != readType) { ErrorInvalidOperation("%s: Can't copy %s data to %s data.", funcName, (readType == WebGLBuffer::Kind::OtherData) ? "other" : "element", (writeType == WebGLBuffer::Kind::OtherData) ? "other" : "element"); return; } gl->MakeCurrent(); gl->fCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); }