Exemplo n.º 1
0
void
WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
    const char funcName[] = "drawArraysInstanced";
    if (IsContextLost())
        return;

    if (!ValidateDrawModeEnum(mode, funcName))
        return;

    MakeContextCurrent();

    bool error;
    ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
    if (error)
        return;

    if (!DrawArrays_check(first, count, primcount, funcName))
        return;

    if (!DrawInstanced_check(funcName))
        return;

    RunContextLossTimer();

    {
        ScopedMaskWorkaround autoMask(*this);
        gl->fDrawArraysInstanced(mode, first, count, primcount);
    }

    Draw_cleanup(funcName);
}
Exemplo n.º 2
0
bool
WebGLContext::DrawArrays_check(const char* funcName, GLenum mode, GLint first,
                               GLsizei vertCount, GLsizei instanceCount)
{
    if (!ValidateDrawModeEnum(mode, funcName))
        return false;

    if (!ValidateNonNegative(funcName, "first", first) ||
        !ValidateNonNegative(funcName, "vertCount", vertCount) ||
        !ValidateNonNegative(funcName, "instanceCount", instanceCount))
    {
        return false;
    }

    if (!ValidateStencilParamsForDrawCall())
        return false;

    if (IsWebGL2() && !gl->IsSupported(gl::GLFeature::prim_restart_fixed)) {
        MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart));
        if (mPrimRestartTypeBytes != 0) {
            mPrimRestartTypeBytes = 0;

            // OSX appears to have severe perf issues with leaving this enabled.
            gl->fDisable(LOCAL_GL_PRIMITIVE_RESTART);
        }
    }

    if (!vertCount || !instanceCount)
        return false; // No error, just early out.

    if (!ValidateBufferFetching(funcName))
        return false;

    const auto checked_firstPlusCount = CheckedInt<GLsizei>(first) + vertCount;
    if (!checked_firstPlusCount.isValid()) {
        ErrorInvalidOperation("%s: overflow in first+vertCount", funcName);
        return false;
    }

    if (uint32_t(checked_firstPlusCount.value()) > mMaxFetchedVertices) {
        ErrorInvalidOperation("%s: Bound vertex attribute buffers do not have sufficient"
                              " size for given first and count.",
                              funcName);
        return false;
    }

    return true;
}
Exemplo n.º 3
0
void
WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
                           WebGLintptr byteOffset)
{
    const char funcName[] = "drawElements";
    if (IsContextLost())
        return;

    if (!ValidateDrawModeEnum(mode, funcName))
        return;

    MakeContextCurrent();

    bool error;
    ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
    if (error)
        return;

    GLuint upperBound = 0;
    if (!DrawElements_check(count, type, byteOffset, 1, funcName, &upperBound))
        return;

    RunContextLossTimer();

    {
        ScopedMaskWorkaround autoMask(*this);

        if (gl->IsSupported(gl::GLFeature::draw_range_elements)) {
            gl->fDrawRangeElements(mode, 0, upperBound, count, type,
                                   reinterpret_cast<GLvoid*>(byteOffset));
        } else {
            gl->fDrawElements(mode, count, type,
                              reinterpret_cast<GLvoid*>(byteOffset));
        }
    }

    Draw_cleanup(funcName);
}
Exemplo n.º 4
0
void
WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
                                    WebGLintptr byteOffset, GLsizei primcount)
{
    const char funcName[] = "drawElementsInstanced";
    if (IsContextLost())
        return;

    if (!ValidateDrawModeEnum(mode, funcName))
        return;

    MakeContextCurrent();

    bool error;
    ScopedResolveTexturesForDraw scopedResolve(this, funcName, &error);
    if (error)
        return;

    GLuint upperBound = 0;
    if (!DrawElements_check(count, type, byteOffset, primcount, funcName, &upperBound))
        return;

    if (!DrawInstanced_check(funcName))
        return;

    RunContextLossTimer();

    {
        ScopedMaskWorkaround autoMask(*this);
        gl->fDrawElementsInstanced(mode, count, type,
                                   reinterpret_cast<GLvoid*>(byteOffset),
                                   primcount);
    }

    Draw_cleanup(funcName);
}
Exemplo n.º 5
0
bool
WebGLContext::DrawElements_check(const char* funcName, GLenum mode, GLsizei vertCount,
                                 GLenum type, WebGLintptr byteOffset,
                                 GLsizei instanceCount)
{
    if (!ValidateDrawModeEnum(mode, funcName))
        return false;

    if (mBoundTransformFeedback &&
        mBoundTransformFeedback->mIsActive &&
        !mBoundTransformFeedback->mIsPaused)
    {
        ErrorInvalidOperation("%s: DrawElements* functions are incompatible with"
                              " transform feedback.",
                              funcName);
        return false;
    }

    if (!ValidateNonNegative(funcName, "vertCount", vertCount) ||
        !ValidateNonNegative(funcName, "byteOffset", byteOffset) ||
        !ValidateNonNegative(funcName, "instanceCount", instanceCount))
    {
        return false;
    }

    if (!ValidateStencilParamsForDrawCall())
        return false;

    if (!vertCount || !instanceCount)
        return false; // No error, just early out.

    uint8_t bytesPerElem = 0;
    switch (type) {
    case LOCAL_GL_UNSIGNED_BYTE:
        bytesPerElem = 1;
        break;

    case LOCAL_GL_UNSIGNED_SHORT:
        bytesPerElem = 2;
        break;

    case LOCAL_GL_UNSIGNED_INT:
        if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_element_index_uint)) {
            bytesPerElem = 4;
        }
        break;
    }

    if (!bytesPerElem) {
        ErrorInvalidEnum("%s: Invalid `type`: 0x%04x", funcName, type);
        return false;
    }

    if (byteOffset % bytesPerElem != 0) {
        ErrorInvalidOperation("%s: `byteOffset` must be a multiple of the size of `type`",
                              funcName);
        return false;
    }

    ////

    if (IsWebGL2() && !gl->IsSupported(gl::GLFeature::prim_restart_fixed)) {
        MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart));
        if (mPrimRestartTypeBytes != bytesPerElem) {
            mPrimRestartTypeBytes = bytesPerElem;

            const uint32_t ones = UINT32_MAX >> (32 - 8*mPrimRestartTypeBytes);
            gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART);
            gl->fPrimitiveRestartIndex(ones);
        }