Bug 1427668 - Lose context if EnsureDefaultFB fails. - r=daoshengmu

MozReview-Commit-ID: 8OqXYXpUv4I
This commit is contained in:
Jeff Gilbert 2017-12-21 17:14:54 -08:00
Родитель 3331434de7
Коммит 7edc1cd1d7
10 изменённых файлов: 37 добавлений и 51 удалений

Просмотреть файл

@ -1947,18 +1947,6 @@ CanvasRenderingContext2D::TryBasicTarget(RefPtr<gfx::DrawTarget>& aOutDT,
return true;
}
int32_t
CanvasRenderingContext2D::GetWidth() const
{
return mWidth;
}
int32_t
CanvasRenderingContext2D::GetHeight() const
{
return mHeight;
}
NS_IMETHODIMP
CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight)
{

Просмотреть файл

@ -426,9 +426,9 @@ public:
nsresult Redraw();
virtual int32_t GetWidth() const override;
virtual int32_t GetHeight() const override;
gfx::IntSize GetSize() const { return gfx::IntSize(mWidth, mHeight); }
virtual int32_t GetWidth() override { return GetSize().width; }
virtual int32_t GetHeight() override { return GetSize().height; }
// nsICanvasRenderingContextInternal
/**

Просмотреть файл

@ -70,18 +70,6 @@ ImageBitmapRenderingContext::TransferFromImageBitmap(ImageBitmap& aImageBitmap)
Redraw(gfxRect(0, 0, mWidth, mHeight));
}
int32_t
ImageBitmapRenderingContext::GetWidth() const
{
return mWidth;
}
int32_t
ImageBitmapRenderingContext::GetHeight() const
{
return mHeight;
}
NS_IMETHODIMP
ImageBitmapRenderingContext::SetDimensions(int32_t aWidth, int32_t aHeight)
{

Просмотреть файл

@ -50,8 +50,8 @@ public:
void TransferFromImageBitmap(ImageBitmap& aImageBitmap);
// nsICanvasRenderingContextInternal
virtual int32_t GetWidth() const override;
virtual int32_t GetHeight() const override;
virtual int32_t GetWidth() override { return mWidth; }
virtual int32_t GetHeight() override { return mHeight; }
NS_IMETHOD SetDimensions(int32_t aWidth, int32_t aHeight) override;

Просмотреть файл

@ -179,7 +179,7 @@ WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE)
return false; // Not an error, but don't run forward to driver either.
} else {
if (!EnsureDefaultFB())
if (!EnsureDefaultFB(funcName))
return false;
}
DoBindFB(fb, target);

Просмотреть файл

@ -740,7 +740,7 @@ WebGLContext::CreateAndInitGL(bool forceEnabled,
// Fallback for resizes:
bool
WebGLContext::EnsureDefaultFB() const
WebGLContext::EnsureDefaultFB(const char* const funcName)
{
if (mDefaultFB) {
MOZ_ASSERT(mDefaultFB->mSize == mRequestedSize);
@ -776,8 +776,11 @@ WebGLContext::EnsureDefaultFB() const
attemptSize.height /= 2;
}
if (!mDefaultFB)
if (!mDefaultFB) {
GenerateWarning("%s: Backbuffer resize failed. Losing context.", funcName);
ForceLoseContext();
return false;
}
mDefaultFB_IsInvalid = true;
@ -787,6 +790,7 @@ WebGLContext::EnsureDefaultFB() const
mRequestedSize.width, mRequestedSize.height,
mDefaultFB->mSize.width, mDefaultFB->mSize.height);
}
mRequestedSize = mDefaultFB->mSize;
return true;
}
@ -969,7 +973,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(gl);
MOZ_ASSERT_IF(mOptions.alpha, gl->Caps().alpha);
if (mOptions.failIfMajorPerformanceCaveat) {
if (gl->IsWARP()) {
@ -1000,7 +1003,9 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
MOZ_ASSERT(!mDefaultFB);
mRequestedSize = {width, height};
if (!EnsureDefaultFB()) {
if (!EnsureDefaultFB("context initialization")) {
MOZ_ASSERT(!gl);
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
const nsLiteralCString text("Initializing WebGL backbuffer failed.");
ThrowEvent_WebGLContextCreationError(text);
@ -1320,7 +1325,7 @@ WebGLContext::InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder,
}
data.mGLContext = gl;
data.mSize = DrawingBufferSize();
data.mSize = DrawingBufferSize("InitializeCanvasRenderer");
data.mHasAlpha = mOptions.alpha;
data.mIsGLAlphaPremult = IsPremultAlpha() || !data.mHasAlpha;
@ -1961,13 +1966,13 @@ WebGLContext::DidRefresh()
////////////////////////////////////////////////////////////////////////////////
gfx::IntSize
WebGLContext::DrawingBufferSize() const
WebGLContext::DrawingBufferSize(const char* const funcName)
{
const gfx::IntSize zeros{0, 0};
if (IsContextLost())
return zeros;
if (!EnsureDefaultFB())
if (!EnsureDefaultFB(funcName))
return zeros;
return mDefaultFB->mSize;
@ -1980,11 +1985,8 @@ WebGLContext::ValidateAndInitFB(const char* const funcName,
if (fb)
return fb->ValidateAndInitAttachments(funcName);
if (!EnsureDefaultFB()) {
GenerateWarning("%s: Lazy resize failed. Losing context.", funcName);
ForceLoseContext();
if (!EnsureDefaultFB(funcName))
return false;
}
if (mDefaultFB_IsInvalid) {
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mDefaultFB->mFB);

Просмотреть файл

@ -342,8 +342,8 @@ public:
virtual void OnMemoryPressure() override;
// nsICanvasRenderingContextInternal
virtual int32_t GetWidth() const override { return DrawingBufferWidth(); }
virtual int32_t GetHeight() const override { return DrawingBufferHeight(); }
virtual int32_t GetWidth() override { return DrawingBufferWidth("get width"); }
virtual int32_t GetHeight() override { return DrawingBufferHeight("get height"); }
NS_IMETHOD SetDimensions(int32_t width, int32_t height) override;
NS_IMETHOD InitializeWithDrawTarget(nsIDocShell*,
@ -501,10 +501,14 @@ public:
void Commit();
void GetCanvas(Nullable<dom::OwningHTMLCanvasElementOrOffscreenCanvas>& retval);
private:
gfx::IntSize DrawingBufferSize() const;
gfx::IntSize DrawingBufferSize(const char* funcName);
public:
GLsizei DrawingBufferWidth() const { return DrawingBufferSize().width; }
GLsizei DrawingBufferHeight() const { return DrawingBufferSize().height; }
GLsizei DrawingBufferWidth(const char* const funcName = "drawingBufferWidth") {
return DrawingBufferSize(funcName).width;
}
GLsizei DrawingBufferHeight(const char* const funcName = "drawingBufferHeight") {
return DrawingBufferSize(funcName).height;
}
layers::LayersBackend GetCompositorBackendType() const;
@ -1990,14 +1994,14 @@ protected:
// --
const uint8_t mMsaaSamples;
gfx::IntSize mRequestedSize;
mutable gfx::IntSize mRequestedSize;
mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
mutable bool mDefaultFB_IsInvalid;
mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
// --
bool EnsureDefaultFB() const;
bool EnsureDefaultFB(const char* funcName);
bool ValidateAndInitFB(const char* funcName, const WebGLFramebuffer* fb);
void DoBindFB(const WebGLFramebuffer* fb, GLenum target = LOCAL_GL_FRAMEBUFFER) const;

Просмотреть файл

@ -362,7 +362,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
const auto& fb = mBoundDrawFramebuffer;
auto samples = [&]() -> Maybe<uint32_t> {
if (!fb) {
if (!EnsureDefaultFB())
if (!EnsureDefaultFB(funcName))
return Nothing();
return Some(mDefaultFB->mSamples);
}

Просмотреть файл

@ -93,8 +93,8 @@ public:
}
// Dimensions of the canvas, in pixels.
virtual int32_t GetWidth() const = 0;
virtual int32_t GetHeight() const = 0;
virtual int32_t GetWidth() = 0;
virtual int32_t GetHeight() = 0;
// Sets the dimensions of the canvas, in pixels. Called
// whenever the size of the element changes.

Просмотреть файл

@ -6,6 +6,7 @@
#include "MozFramebuffer.h"
#include "GLContext.h"
#include "mozilla/gfx/Logging.h"
#include "ScopedGLHelpers.h"
namespace mozilla {
@ -61,7 +62,10 @@ MozFramebuffer::Create(GLContext* const gl, const gfx::IntSize& size,
const auto err = errorScope.GetError();
if (err) {
MOZ_ASSERT(err == LOCAL_GL_OUT_OF_MEMORY);
if (err != LOCAL_GL_OUT_OF_MEMORY) {
gfxCriticalNote << "Unexpected error: " << gfx::hexa(err) << ": "
<< GLContext::GLErrorToString(err);
}
DeleteByTarget(gl, colorTarget, colorName);
return nullptr;
}