void JSGlobalObjectInspectorController::reportAPIException(ExecState* exec, Exception* exception)
{
    if (isTerminatedExecutionException(exception))
        return;

    ErrorHandlingScope errorScope(exec->vm());

    RefPtr<ScriptCallStack> callStack = createScriptCallStackFromException(exec, exception, ScriptCallStack::maxCallStackSizeToCapture);
    if (includesNativeCallStackWhenReportingExceptions())
        appendAPIBacktrace(callStack.get());

    // FIXME: <http://webkit.org/b/115087> Web Inspector: Should not evaluate JavaScript handling exceptions
    // If this is a custom exception object, call toString on it to try and get a nice string representation for the exception.
    String errorMessage = exception->value().toString(exec)->value(exec);
    exec->clearException();

    if (JSGlobalObjectConsoleClient::logToSystemConsole()) {
        if (callStack->size()) {
            const ScriptCallFrame& callFrame = callStack->at(0);
            ConsoleClient::printConsoleMessage(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callFrame.sourceURL(), callFrame.lineNumber(), callFrame.columnNumber());
        } else
            ConsoleClient::printConsoleMessage(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, String(), 0, 0);
    }

    m_consoleAgent->addMessageToConsole(std::make_unique<ConsoleMessage>(MessageSource::JS, MessageType::Log, MessageLevel::Error, errorMessage, callStack));
}
예제 #2
0
void
WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usage)
{
    const char funcName[] = "bufferData";

    if (!ValidateBufferUsageEnum(mContext, funcName, usage))
        return;

    if (mNumActiveTFOs) {
        mContext->ErrorInvalidOperation("%s: Buffer is bound to an active transform"
                                        " feedback object.",
                                        funcName);
        return;
    }

    const auto& gl = mContext->gl;
    gl->MakeCurrent();
    const ScopedLazyBind lazyBind(gl, target, this);
    mContext->InvalidateBufferFetching();

#ifdef XP_MACOSX
    // bug 790879
    if (gl->WorkAroundDriverBugs() &&
        size > INT32_MAX)
    {
        mContext->ErrorOutOfMemory("%s: Allocation size too large.", funcName);
        return;
    }
#endif

    const bool sizeChanges = (size != ByteLength());
    if (sizeChanges) {
        gl::GLContext::LocalErrorScope errorScope(*gl);
        gl->fBufferData(target, size, data, usage);
        const auto error = errorScope.GetError();

        if (error) {
            MOZ_ASSERT(error == LOCAL_GL_OUT_OF_MEMORY);
            mContext->ErrorOutOfMemory("%s: Error from driver: 0x%04x", funcName, error);
            return;
        }
    } else {
        gl->fBufferData(target, size, data, usage);
    }

    mUsage = usage;
    mByteLength = size;

    // Warning: Possibly shared memory.  See bug 1225033.
    if (!ElementArrayCacheBufferData(data, size)) {
        mByteLength = 0;
        mContext->ErrorOutOfMemory("%s: Failed update index buffer cache.", funcName);
    }
}
예제 #3
0
void WebGLContext::AssertCachedBindings() const {
#ifdef DEBUG
  gl::GLContext::LocalErrorScope errorScope(*gl);

  if (IsWebGL2() ||
      IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
    AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING,
                           mBoundVertexArray->mGLName);
  }

  GLint stencilBits = 0;
  if (GetStencilBits(&stencilBits)) {  // Depends on current draw framebuffer.
    const GLuint stencilRefMask = (1 << stencilBits) - 1;

    AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask,
                                 mStencilRefFront);
    AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask,
                                 mStencilRefBack);
  }

  // Program
  GLuint bound = mCurrentProgram ? mCurrentProgram->mGLName : 0;
  AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound);

  // Textures
  GLenum activeTexture = mActiveTexture + LOCAL_GL_TEXTURE0;
  AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture);

  WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
  bound = curTex ? curTex->mGLName : 0;
  AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound);

  curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP);
  bound = curTex ? curTex->mGLName : 0;
  AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound);

  // Buffers
  bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0;
  AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound);

  MOZ_ASSERT(mBoundVertexArray);
  WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer;
  bound = curBuff ? curBuff->mGLName : 0;
  AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound);

  MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError()));
#endif

  // We do not check the renderbuffer binding, because we never rely on it
  // matching.
}
예제 #4
0
static GLenum
DoRenderbufferStorageMaybeMultisample(gl::GLContext* gl, GLsizei samples,
                                      GLenum internalFormat, GLsizei width,
                                      GLsizei height)
{
    MOZ_ASSERT_IF(samples >= 1, gl->IsSupported(gl::GLFeature::framebuffer_multisample));

    // Certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL.
    switch (internalFormat) {
    case LOCAL_GL_RGBA4:
    case LOCAL_GL_RGB5_A1:
        // 16-bit RGBA formats are not supported on desktop GL.
        if (!gl->IsGLES())
            internalFormat = LOCAL_GL_RGBA8;
        break;

    case LOCAL_GL_RGB565:
        // RGB565 is not supported on desktop GL.
        if (!gl->IsGLES())
            internalFormat = LOCAL_GL_RGB8;
        break;

    case LOCAL_GL_DEPTH_COMPONENT16:
        if (!gl->IsGLES() || gl->IsExtensionSupported(gl::GLContext::OES_depth24))
            internalFormat = LOCAL_GL_DEPTH_COMPONENT24;
        else if (gl->IsSupported(gl::GLFeature::packed_depth_stencil))
            internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
        break;

    case LOCAL_GL_DEPTH_STENCIL:
        MOZ_CRASH("GFX: GL_DEPTH_STENCIL is not valid here.");
        break;

    default:
        break;
    }

    gl::GLContext::LocalErrorScope errorScope(*gl);

    if (samples > 0) {
        gl->fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER, samples,
                                            internalFormat, width, height);
    } else {
        gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, internalFormat, width, height);
    }

    return errorScope.GetError();
}
예제 #5
0
JSObject* throwTerminatedExecutionException(ExecState* exec)
{
    VM& vm = exec->vm();
    ErrorHandlingScope errorScope(vm);
    return vm.throwException(exec, createTerminatedExecutionException(&vm));
}
예제 #6
0
JSObject* throwStackOverflowError(ExecState* exec)
{
    VM& vm = exec->vm();
    ErrorHandlingScope errorScope(vm);
    return vm.throwException(exec, createStackOverflowError(exec));
}
예제 #7
0
bool
TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
                              WebGLTexture* tex, TexImageTarget target, GLint level,
                              const webgl::DriverUnpackInfo* dui, GLint xOffset,
                              GLint yOffset, GLint zOffset, const webgl::PackingInfo& pi,
                              GLenum* const out_error) const
{
    MOZ_ASSERT_IF(needsRespec, !isSubImage);

    WebGLContext* webgl = tex->mContext;

    gl::GLContext* gl = webgl->GL();
    gl->MakeCurrent();

    if (needsRespec) {
        *out_error = DoTexOrSubImage(isSubImage, gl, target.get(), level, dui, xOffset,
                                     yOffset, zOffset, mWidth, mHeight, mDepth,
                                     nullptr);
        if (*out_error)
            return true;
    }

    const char* fallbackReason;
    do {
        if (mDepth != 1) {
            fallbackReason = "depth is not 1";
            break;
        }

        if (webgl->mPixelStore_UnpackSkipPixels ||
            webgl->mPixelStore_UnpackSkipRows ||
            webgl->mPixelStore_UnpackSkipImages)
        {
            fallbackReason = "non-zero UNPACK_SKIP_* not yet supported";
            break;
        }

        const auto fnHasPremultMismatch = [&]() {
            if (mSrcAlphaType == gfxAlphaType::Opaque)
                return false;

            const bool srcIsPremult = (mSrcAlphaType == gfxAlphaType::Premult);
            const auto& dstIsPremult = webgl->mPixelStore_PremultiplyAlpha;
            if (srcIsPremult == dstIsPremult)
                return false;

            if (dstIsPremult) {
                fallbackReason = "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not true";
            } else {
                fallbackReason = "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not false";
            }
            return true;
        };
        if (fnHasPremultMismatch())
            break;

        if (dui->unpackFormat != LOCAL_GL_RGB && dui->unpackFormat != LOCAL_GL_RGBA) {
            fallbackReason = "`format` is not RGB or RGBA";
            break;
        }

        if (dui->unpackType != LOCAL_GL_UNSIGNED_BYTE) {
            fallbackReason = "`type` is not UNSIGNED_BYTE";
            break;
        }

        gl::ScopedFramebuffer scopedFB(gl);
        gl::ScopedBindFramebuffer bindFB(gl, scopedFB.FB());

        {
            gl::GLContext::LocalErrorScope errorScope(*gl);

            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
                                      target.get(), tex->mGLName, level);

            if (errorScope.GetError()) {
                fallbackReason = "bug: failed to attach to FB for blit";
                break;
            }
        }

        const GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
        if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
            fallbackReason = "bug: failed to confirm FB for blit";
            break;
        }

        const gfx::IntSize destSize(mWidth, mHeight);
        const auto dstOrigin = (webgl->mPixelStore_FlipY ? gl::OriginPos::TopLeft
                                                         : gl::OriginPos::BottomLeft);
        if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, scopedFB.FB(),
                                                      dstOrigin))
        {
            fallbackReason = "likely bug: failed to blit";
            break;
        }

        // Blitting was successful, so we're done!
        *out_error = 0;
        return true;
    } while (false);

    const nsPrintfCString perfMsg("%s: Failed to hit GPU-copy fast-path: %s (src type %u)",
                                  funcName, fallbackReason, uint32_t(mImage->GetFormat()));

    if (webgl->mPixelStore_RequireFastPath) {
        webgl->ErrorInvalidOperation("%s", perfMsg.BeginReading());
        return false;
    }

    webgl->GeneratePerfWarning("%s Falling back to CPU upload.",
                               perfMsg.BeginReading());

    const RefPtr<gfx::SourceSurface> surf = mImage->GetAsSourceSurface();

    RefPtr<gfx::DataSourceSurface> dataSurf;
    if (surf) {
        // WARNING: OSX can lose our MakeCurrent here.
        dataSurf = surf->GetDataSurface();
    }
    if (!dataSurf) {
        webgl->ErrorOutOfMemory("%s: GetAsSourceSurface or GetDataSurface failed after"
                                " blit failed for TexUnpackImage.",
                                funcName);
        return false;
    }

    const TexUnpackSurface surfBlob(webgl, target, mWidth, mHeight, mDepth, dataSurf,
                                    mSrcAlphaType);

    return surfBlob.TexOrSubImage(isSubImage, needsRespec, funcName, tex, target, level,
                                  dui, xOffset, yOffset, zOffset, pi, out_error);
}
예제 #8
0
bool
TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
                              WebGLTexture* tex, TexImageTarget target, GLint level,
                              const webgl::DriverUnpackInfo* dui, GLint xOffset,
                              GLint yOffset, GLint zOffset, GLenum* const out_error) const
{
    MOZ_ASSERT_IF(needsRespec, !isSubImage);

    WebGLContext* webgl = tex->mContext;

    gl::GLContext* gl = webgl->GL();
    gl->MakeCurrent();

    if (needsRespec) {
        *out_error = DoTexOrSubImage(isSubImage, gl, target.get(), level, dui, xOffset,
                                     yOffset, zOffset, mWidth, mHeight, mDepth,
                                     nullptr);
        if (*out_error)
            return false;
    }

    do {
        if (mDepth != 1)
            break;

        const bool isDstPremult = webgl->mPixelStore_PremultiplyAlpha;
        if (mIsSrcPremult != isDstPremult)
            break;

        if (dui->unpackFormat != LOCAL_GL_RGB && dui->unpackFormat != LOCAL_GL_RGBA)
            break;

        if (dui->unpackType != LOCAL_GL_UNSIGNED_BYTE)
            break;

        gl::ScopedFramebuffer scopedFB(gl);
        gl::ScopedBindFramebuffer bindFB(gl, scopedFB.FB());

        {
            gl::GLContext::LocalErrorScope errorScope(*gl);

            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
                                      target.get(), tex->mGLName, level);

            if (errorScope.GetError())
                break;
        }

        const GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
        if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
            break;

        const gfx::IntSize destSize(mWidth, mHeight);
        const auto dstOrigin = (webgl->mPixelStore_FlipY ? gl::OriginPos::TopLeft
                                                         : gl::OriginPos::BottomLeft);
        if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, scopedFB.FB(),
                                                      dstOrigin))
        {
            break;
        }

        // Blitting was successful, so we're done!
        *out_error = 0;
        return true;
    } while (false);

    webgl->GenerateWarning("%s: Failed to hit GPU-copy fast-path. Falling back to CPU"
                           " upload.",
                           funcName);

    const RefPtr<gfx::SourceSurface> surf = mImage->GetAsSourceSurface();

    RefPtr<gfx::DataSourceSurface> dataSurf;
    if (surf) {
        // WARNING: OSX can lose our MakeCurrent here.
        dataSurf = surf->GetDataSurface();
    }
    if (!dataSurf) {
        webgl->ErrorOutOfMemory("%s: GetAsSourceSurface or GetDataSurface failed after"
                                " blit failed for TexUnpackImage.",
                                funcName);
        return false;
    }

    const TexUnpackSurface surfBlob(webgl, target, mWidth, mHeight, mDepth, dataSurf,
                                    mIsSrcPremult);

    return surfBlob.TexOrSubImage(isSubImage, needsRespec, funcName, tex, target, level,
                                  dui, xOffset, yOffset, zOffset, out_error);
}
예제 #9
0
void
TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, const char* funcName,
                              WebGLTexture* tex, TexImageTarget target, GLint level,
                              const webgl::DriverUnpackInfo* dui, GLint xOffset,
                              GLint yOffset, GLint zOffset, GLenum* const out_glError)
{
    MOZ_ASSERT_IF(needsRespec, !isSubImage);
    *out_glError = 0;

    WebGLContext* webgl = tex->mContext;

    gl::GLContext* gl = webgl->GL();
    gl->MakeCurrent();

    if (needsRespec) {
        GLenum error = DoTexOrSubImage(isSubImage, gl, target.get(), level, dui, xOffset,
                                       yOffset, zOffset, mWidth, mHeight, mDepth,
                                       nullptr);
        if (error) {
            MOZ_ASSERT(!error);
            *out_glError = LOCAL_GL_OUT_OF_MEMORY;
            return;
        }
    }

    do {
        if (dui->unpackFormat != LOCAL_GL_RGB && dui->unpackFormat != LOCAL_GL_RGBA)
            break;

        if (dui->unpackType != LOCAL_GL_UNSIGNED_BYTE)
            break;

        gl::ScopedFramebuffer scopedFB(gl);
        gl::ScopedBindFramebuffer bindFB(gl, scopedFB.FB());

        {
            gl::GLContext::LocalErrorScope errorScope(*gl);

            gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
                                      target.get(), tex->mGLName, level);

            if (errorScope.GetError())
                break;
        }

        const GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
        if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
            break;

        gl::OriginPos srcOrigin, dstOrigin;
        OriginsForDOM(webgl, &srcOrigin, &dstOrigin);

        const gfx::IntSize destSize(mWidth, mHeight);
        if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, destSize, scopedFB.FB(),
                                                      dstOrigin))
        {
            break;
        }

        return; // Blitting was successful, so we're done!
    } while (false);

    TexUnpackSurface surfBlob(mImage->GetAsSourceSurface(), mIsAlphaPremult);

    surfBlob.TexOrSubImage(isSubImage, needsRespec, funcName, tex, target, level, dui,
                           xOffset, yOffset, zOffset, out_glError);
}
예제 #10
0
void
WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usage)
{
    // Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
    // is like intptr_t.
    if (!CheckedInt<GLsizeiptr>(size).isValid())
        return mContext->ErrorOutOfMemory("bad size");

    if (!ValidateBufferUsageEnum(mContext, usage))
        return;

#ifdef XP_MACOSX
    // bug 790879
    if (mContext->gl->WorkAroundDriverBugs() &&
        size > INT32_MAX)
    {
        mContext->ErrorOutOfMemory("Allocation size too large.");
        return;
    }
#endif

    const void* uploadData = data;

    UniqueBuffer newIndexCache;
    if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER &&
        mContext->mNeedsIndexValidation)
    {
        newIndexCache = malloc(size);
        if (!newIndexCache) {
            mContext->ErrorOutOfMemory("Failed to alloc index cache.");
            return;
        }
        memcpy(newIndexCache.get(), data, size);
        uploadData = newIndexCache.get();
    }

    const auto& gl = mContext->gl;
    const ScopedLazyBind lazyBind(gl, target, this);

    const bool sizeChanges = (size != ByteLength());
    if (sizeChanges) {
        gl::GLContext::LocalErrorScope errorScope(*gl);
        gl->fBufferData(target, size, uploadData, usage);
        const auto error = errorScope.GetError();

        if (error) {
            MOZ_ASSERT(error == LOCAL_GL_OUT_OF_MEMORY);
            mContext->ErrorOutOfMemory("Error from driver: 0x%04x", error);
            return;
        }
    } else {
        gl->fBufferData(target, size, uploadData, usage);
    }

    mContext->OnDataAllocCall();

    mUsage = usage;
    mByteLength = size;
    mFetchInvalidator.InvalidateCaches();
    mIndexCache = std::move(newIndexCache);

    if (mIndexCache) {
        if (!mIndexRanges.empty()) {
            mContext->GeneratePerfWarning("[%p] Invalidating %u ranges.", this,
                                          uint32_t(mIndexRanges.size()));
            mIndexRanges.clear();
        }
    }

    ResetLastUpdateFenceId();
}
예제 #11
0
void WebGLContext::AssertCachedGlobalState() const {
#ifdef DEBUG
  gl::GLContext::LocalErrorScope errorScope(*gl);

  ////////////////

  // Draw state
  MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled);
  MOZ_ASSERT_IF(IsWebGL2(), gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) ==
                                mRasterizerDiscardEnabled);
  MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled);

  // Cannot trivially check COLOR_CLEAR_VALUE, since in old GL versions glGet
  // may clamp based on whether the current framebuffer is floating-point or
  // not. This also means COLOR_CLEAR_VALUE save+restore is dangerous!

  realGLboolean depthWriteMask = 0;
  gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
  MOZ_ASSERT(depthWriteMask == mDepthWriteMask);

  GLfloat depthClearValue = 0.0f;
  gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
  MOZ_ASSERT(IsCacheCorrect(mDepthClearValue, depthClearValue));

  const int maxStencilBits = 8;
  const GLuint maxStencilBitsMask = (1 << maxStencilBits) - 1;
  AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE,
                               maxStencilBitsMask, mStencilClearValue);

  // GLES 3.0.4, $4.1.4, p177:
  //   [...] the front and back stencil mask are both set to the value `2^s -
  //   1`, where `s` is greater than or equal to the number of bits in the
  //   deepest stencil buffer supported by the GL implementation.
  AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK,
                               maxStencilBitsMask, mStencilValueMaskFront);
  AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK,
                               maxStencilBitsMask, mStencilValueMaskBack);

  AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK,
                               maxStencilBitsMask, mStencilWriteMaskFront);
  AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK,
                               maxStencilBitsMask, mStencilWriteMaskBack);

  // Viewport
  GLint int4[4] = {0, 0, 0, 0};
  gl->fGetIntegerv(LOCAL_GL_VIEWPORT, int4);
  MOZ_ASSERT(int4[0] == mViewportX && int4[1] == mViewportY &&
             int4[2] == mViewportWidth && int4[3] == mViewportHeight);

  AssertUintParamCorrect(gl, LOCAL_GL_PACK_ALIGNMENT,
                         mPixelStore_PackAlignment);
  AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ALIGNMENT,
                         mPixelStore_UnpackAlignment);

  if (IsWebGL2()) {
    AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_IMAGE_HEIGHT,
                           mPixelStore_UnpackImageHeight);
    AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_IMAGES,
                           mPixelStore_UnpackSkipImages);
    AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ROW_LENGTH,
                           mPixelStore_UnpackRowLength);
    AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_ROWS,
                           mPixelStore_UnpackSkipRows);
    AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_PIXELS,
                           mPixelStore_UnpackSkipPixels);
    AssertUintParamCorrect(gl, LOCAL_GL_PACK_ROW_LENGTH,
                           mPixelStore_PackRowLength);
    AssertUintParamCorrect(gl, LOCAL_GL_PACK_SKIP_ROWS,
                           mPixelStore_PackSkipRows);
    AssertUintParamCorrect(gl, LOCAL_GL_PACK_SKIP_PIXELS,
                           mPixelStore_PackSkipPixels);
  }

  MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError()));
#endif
}