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));
}
示例#2
0
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);
}
示例#3
0
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);
}