commit 27689c413b0b9e5fb1f3c12a0962e2a034ee8fea
parent f6ad3a8d24a95f8bebb1ac58760dc393641abed5
Author: Narcis Beleuzu <nbeleuzu@mozilla.com>
Date: Fri, 17 Oct 2025 03:56:38 +0300
Revert "Bug 1927289: More strongly enforce WebGL context continuity. r=ahale" for webgl failures on /test_conformance__context__context-lost-restored.html
This reverts commit fe0b47dff33c30892b2ecc7585b4bcc14d2f6094.
Diffstat:
1 file changed, 126 insertions(+), 237 deletions(-)
diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp
@@ -276,9 +276,8 @@ void ClientWebGLContext::OnContextLoss(
const webgl::ContextLossReason reason) const {
JsWarning("WebGL context was lost.");
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (notLost) {
- for (const auto& ext : notLost->extensions) {
+ if (mNotLost) {
+ for (const auto& ext : mNotLost->extensions) {
if (!ext) continue;
ext->mContext = nullptr; // Detach.
}
@@ -422,12 +421,14 @@ template <typename MethodT, typename... Args>
void ClientWebGLContext::Run_WithDestArgTypes(
std::optional<JS::AutoCheckCannotGC>&& noGc, const MethodT method,
const size_t id, const Args&... args) const {
+ const auto notLost =
+ mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
+
// `AutoCheckCannotGC` must be reset after the GC data is done being used but
// *before* the `notLost` destructor runs, since the latter can GC.
const auto cleanup = MakeScopeExit([&]() { noGc.reset(); });
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
+ if (IsContextLost()) {
return;
}
@@ -801,8 +802,7 @@ ClientWebGLContext::SetDimensions(const int32_t signedWidth,
mResetLayer = true; // Always treat this as resize.
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (notLost) {
+ if (mNotLost) {
auto& state = State();
auto curSize = prevRequestedSize;
@@ -1012,7 +1012,8 @@ std::unordered_map<GLenum, bool> webgl::MakeIsEnabledMap(const bool webgl2) {
uvec2 ClientWebGLContext::DrawingBufferSize() {
if (IsContextLost()) return {};
- RefPtr<webgl::NotLostData> notLost(mNotLost);
+ RefPtr<webgl::NotLostData> notLost(
+ mNotLost); // Hold a strong-ref to prevent LoseContext=>UAF.
auto& state = State();
auto& size = state.mDrawingBufferSize;
@@ -1033,19 +1034,14 @@ uvec2 ClientWebGLContext::DrawingBufferSize() {
}
void ClientWebGLContext::OnMemoryPressure() {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
+ if (IsContextLost()) return;
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->OnMemoryPressure();
}
- const auto& child = notLost->outOfProcess;
- if (child) {
- (void)child->SendOnMemoryPressure();
- }
+ const auto& child = mNotLost->outOfProcess;
+ (void)child->SendOnMemoryPressure();
}
NS_IMETHODIMP
@@ -1108,10 +1104,9 @@ void ClientWebGLContext::DidRefresh() { Run<RPROC(DidRefresh)>(); }
already_AddRefed<gfx::SourceSurface> ClientWebGLContext::GetSurfaceSnapshot(
gfxAlphaType* const out_alphaType) {
const FuncScope funcScope(*this, "<GetSurfaceSnapshot>");
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return nullptr;
- }
+ if (IsContextLost()) return nullptr;
+ RefPtr<webgl::NotLostData> notLost(
+ mNotLost); // Hold a strong-ref to prevent LoseContext=>UAF.
auto ret = BackBufferSnapshot();
if (!ret) return nullptr;
@@ -1158,10 +1153,9 @@ mozilla::ipc::IProtocol* ClientWebGLContext::SupportsSnapshotExternalCanvas()
RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
const bool requireAlphaPremult) {
const FuncScope funcScope(*this, "<GetSurfaceSnapshot>");
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return nullptr;
- }
+ if (IsContextLost()) return nullptr;
+ RefPtr<webgl::NotLostData> notLost(
+ mNotLost); // Hold a strong-ref to prevent LoseContext=>UAF.
const auto& options = notLost->info.options;
@@ -1176,7 +1170,7 @@ RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
/*zero=*/true));
};
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
const auto maybeSize = inProcess->FrontBufferSnapshotInto({});
if (!maybeSize) return nullptr;
@@ -1216,7 +1210,7 @@ RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
}
return surf;
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
webgl::FrontBufferSnapshotIpc res;
if (!child->SendGetFrontBufferSnapshot(&res)) {
@@ -1262,10 +1256,9 @@ RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
}
RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return nullptr;
- }
+ if (IsContextLost()) return nullptr;
+ RefPtr<webgl::NotLostData> notLost(
+ mNotLost); // Hold a strong-ref to prevent LoseContext=>UAF.
const auto& options = notLost->info.options;
const auto& state = State();
@@ -1340,11 +1333,6 @@ RefPtr<gfx::DataSourceSurface> ClientWebGLContext::BackBufferSnapshot() {
UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer(
mozilla::CanvasUtils::ImageExtraction aExtractionBehavior,
int32_t* out_format, gfx::IntSize* out_imageSize) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return nullptr;
- }
-
*out_format = 0;
*out_imageSize = {};
@@ -1355,7 +1343,7 @@ UniquePtr<uint8_t[]> ClientWebGLContext::GetImageBuffer(
RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
- const auto& premultAlpha = notLost->info.options.premultipliedAlpha;
+ const auto& premultAlpha = mNotLost->info.options.premultipliedAlpha;
*out_imageSize = dataSurface->GetSize();
if (aExtractionBehavior == CanvasUtils::ImageExtraction::Randomize) {
@@ -1372,18 +1360,13 @@ ClientWebGLContext::GetInputStream(
const char* mimeType, const nsAString& encoderOptions,
mozilla::CanvasUtils::ImageExtraction extractionBehavior,
const nsACString& randomizationKey, nsIInputStream** out_stream) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return NS_ERROR_FAILURE;
- }
-
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
gfxAlphaType any;
RefPtr<gfx::SourceSurface> snapshot = GetSurfaceSnapshot(&any);
if (!snapshot) return NS_ERROR_FAILURE;
RefPtr<gfx::DataSourceSurface> dataSurface = snapshot->GetDataSurface();
- const auto& premultAlpha = notLost->info.options.premultipliedAlpha;
+ const auto& premultAlpha = mNotLost->info.options.premultipliedAlpha;
if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) {
return gfxUtils::GetInputStreamWithRandomNoise(
@@ -1433,24 +1416,21 @@ ClientWebGLContext::CreateOpaqueFramebuffer(
auto ret = AsRefPtr(new WebGLFramebufferJS(*this, true));
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return ret.forget();
- }
-
- const auto& inProcess = notLost->inProcess;
- if (inProcess) {
- if (!inProcess->CreateOpaqueFramebuffer(ret->mId, options)) {
- ret = nullptr;
+ if (mNotLost) {
+ const auto& inProcess = mNotLost->inProcess;
+ if (inProcess) {
+ if (!inProcess->CreateOpaqueFramebuffer(ret->mId, options)) {
+ ret = nullptr;
+ }
+ return ret.forget();
}
- return ret.forget();
+ const auto& child = mNotLost->outOfProcess;
+ child->FlushPendingCmds();
+ bool ok = false;
+ if (!child->SendCreateOpaqueFramebuffer(ret->mId, options, &ok))
+ return nullptr;
+ if (!ok) return nullptr;
}
- const auto& child = notLost->outOfProcess;
- child->FlushPendingCmds();
- bool ok = false;
- if (!child->SendCreateOpaqueFramebuffer(ret->mId, options, &ok))
- return nullptr;
- if (!ok) return nullptr;
return ret.forget();
}
@@ -1963,12 +1943,9 @@ bool ClientWebGLContext::IsVertexArray(
void ClientWebGLContext::SetEnabledI(const GLenum cap, const Maybe<GLuint> i,
const bool val) const {
const FuncScope funcScope(*this, "enable/disable");
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
+ if (IsContextLost()) return;
- auto& map = notLost->state.mIsEnabledMap;
+ auto& map = mNotLost->state.mIsEnabledMap;
auto slot = MaybeFind(map, cap);
if (i && cap != LOCAL_GL_BLEND) {
slot = nullptr;
@@ -1987,12 +1964,9 @@ void ClientWebGLContext::SetEnabledI(const GLenum cap, const Maybe<GLuint> i,
bool ClientWebGLContext::IsEnabled(const GLenum cap) const {
const FuncScope funcScope(*this, "isEnabled");
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return false;
- }
+ if (IsContextLost()) return false;
- const auto& map = notLost->state.mIsEnabledMap;
+ const auto& map = mNotLost->state.mIsEnabledMap;
const auto slot = MaybeFind(map, cap);
if (!slot) {
EnqueueError_ArgEnum("cap", cap);
@@ -2013,10 +1987,9 @@ void ClientWebGLContext::GetInternalformatParameter(
JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
const FuncScope funcScope(*this, "getInternalformatParameter");
retval.set(JS::NullValue());
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
+ const auto notLost =
+ mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
+ if (IsContextLost()) return;
const auto& inProcessContext = notLost->inProcess;
Maybe<std::vector<int32_t>> maybe;
@@ -2061,17 +2034,14 @@ bool ToJSValueOrNull(JSContext* const cx, const RefPtr<T>& ptr,
}
Maybe<double> ClientWebGLContext::GetNumber(const GLenum pname) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return Nothing();
- }
+ MOZ_ASSERT(!IsContextLost());
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetNumber(pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
@@ -2082,17 +2052,14 @@ Maybe<double> ClientWebGLContext::GetNumber(const GLenum pname) {
}
Maybe<std::string> ClientWebGLContext::GetString(const GLenum pname) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return Nothing();
- }
+ MOZ_ASSERT(!IsContextLost());
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetString(pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<std::string> ret;
@@ -2105,11 +2072,6 @@ Maybe<std::string> ClientWebGLContext::GetString(const GLenum pname) {
void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& rv, const bool debug) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getParameter");
if (IsContextLost()) return;
@@ -2512,8 +2474,8 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
if (maybe) {
auto str = std::string{};
if (pname == dom::MOZ_debug_Binding::WSI_INFO) {
- const auto& outOfProcess = notLost->outOfProcess;
- const auto& inProcess = notLost->inProcess;
+ const auto& outOfProcess = mNotLost->outOfProcess;
+ const auto& inProcess = mNotLost->inProcess;
str += PrintfStdString("outOfProcess: %s\ninProcess: %s\n",
ToChars(bool(outOfProcess)),
ToChars(bool(inProcess)));
@@ -2578,19 +2540,15 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname,
void ClientWebGLContext::GetBufferParameter(
JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandle<JS::Value> retval) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
retval.set(JS::NullValue());
+ if (IsContextLost()) return;
const auto maybe = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetBufferParameter(target, pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetBufferParameter(target, pname, &ret)) {
@@ -2621,13 +2579,9 @@ void ClientWebGLContext::GetFramebufferAttachmentParameter(
JSContext* const cx, const GLenum target, const GLenum attachment,
const GLenum pname, JS::MutableHandle<JS::Value> retval,
ErrorResult& rv) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getFramebufferAttachmentParameter");
+ if (IsContextLost()) return;
const auto& state = State();
@@ -2643,12 +2597,12 @@ void ClientWebGLContext::GetFramebufferAttachmentParameter(
const auto fnGet = [&](const GLenum pname) {
const auto fbId = fb ? fb->mId : 0;
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetFramebufferAttachmentParameter(fbId, attachment,
pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetFramebufferAttachmentParameter(fbId, attachment, pname,
@@ -2707,12 +2661,8 @@ void ClientWebGLContext::GetRenderbufferParameter(
JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandle<JS::Value> retval) const {
retval.set(JS::NullValue());
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
const FuncScope funcScope(*this, "getRenderbufferParameter");
+ if (IsContextLost()) return;
if (target != LOCAL_GL_RENDERBUFFER) {
EnqueueError_ArgEnum("target", target);
@@ -2723,11 +2673,11 @@ void ClientWebGLContext::GetRenderbufferParameter(
const auto& rb = state.mBoundRb;
const auto rbId = rb ? rb->mId : 0;
const auto maybe = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetRenderbufferParameter(rbId, pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetRenderbufferParameter(rbId, pname, &ret)) {
@@ -2743,13 +2693,9 @@ void ClientWebGLContext::GetRenderbufferParameter(
void ClientWebGLContext::GetIndexedParameter(
JSContext* cx, GLenum target, GLuint index,
JS::MutableHandle<JS::Value> retval, ErrorResult& rv) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getIndexedParameter");
+ if (IsContextLost()) return;
const auto& state = State();
@@ -2779,11 +2725,11 @@ void ClientWebGLContext::GetIndexedParameter(
}
const auto maybe = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetIndexedParameter(target, index);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetIndexedParameter(target, index, &ret)) {
@@ -2815,13 +2761,9 @@ void ClientWebGLContext::GetUniform(JSContext* const cx,
const WebGLProgramJS& prog,
const WebGLUniformLocationJS& loc,
JS::MutableHandle<JS::Value> retval) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getUniform");
+ if (IsContextLost()) return;
if (!prog.ValidateUsable(*this, "prog")) return;
if (!loc.ValidateUsable(*this, "loc")) return;
@@ -2839,11 +2781,11 @@ void ClientWebGLContext::GetUniform(JSContext* const cx,
}
const auto res = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetUniform(prog.mId, loc.mLocation);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
webgl::GetUniformData ret;
if (!child->SendGetUniform(prog.mId, loc.mLocation, &ret)) {
@@ -2959,15 +2901,10 @@ void ClientWebGLContext::GetUniform(JSContext* const cx,
already_AddRefed<WebGLShaderPrecisionFormatJS>
ClientWebGLContext::GetShaderPrecisionFormat(const GLenum shadertype,
const GLenum precisiontype) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return nullptr;
- }
-
const FuncScope funcScope(*this, "getShaderPrecisionFormat");
if (IsContextLost()) return nullptr;
- const auto& shaderPrecisions = *notLost->info.shaderPrecisions;
+ const auto& shaderPrecisions = *mNotLost->info.shaderPrecisions;
const auto args =
webgl::GetShaderPrecisionFormatArgs{shadertype, precisiontype};
const auto found = MaybeFind(shaderPrecisions, args);
@@ -3019,16 +2956,13 @@ void ClientWebGLContext::BlendFuncSeparateI(Maybe<GLuint> i, GLenum srcRGB,
}
GLenum ClientWebGLContext::CheckFramebufferStatus(GLenum target) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
- }
+ if (IsContextLost()) return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->CheckFramebufferStatus(target);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
GLenum ret = 0;
if (!child->SendCheckFramebufferStatus(target, &ret)) {
@@ -3150,34 +3084,27 @@ void ClientWebGLContext::DepthRange(GLclampf zNear, GLclampf zFar) {
}
void ClientWebGLContext::Flush(const bool flushGl) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
const FuncScope funcScope(*this, "flush");
+ if (IsContextLost()) return;
if (flushGl) {
Run<RPROC(Flush)>();
}
- if (notLost->inProcess) return;
- const auto& child = notLost->outOfProcess;
+ if (mNotLost->inProcess) return;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
}
void ClientWebGLContext::Finish() {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
+ if (IsContextLost()) return;
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
inProcess->Finish();
return;
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
(void)child->SendFinish();
}
@@ -3185,23 +3112,19 @@ void ClientWebGLContext::Finish() {
void ClientWebGLContext::FrontFace(GLenum mode) { Run<RPROC(FrontFace)>(mode); }
GLenum ClientWebGLContext::GetError() {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return 0;
- }
-
const FuncScope funcScope(*this, "getError");
if (mNextError) {
const auto ret = mNextError;
mNextError = 0;
return ret;
}
+ if (IsContextLost()) return 0;
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetError();
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
GLenum ret = 0;
if (!child->SendGetError(&ret)) {
@@ -3580,10 +3503,8 @@ void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset,
GLuint dstElemCountOverride) {
const FuncScope funcScope(*this, "getBufferSubData");
if (IsContextLost()) return;
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
+ const auto notLost =
+ mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
if (!ValidateNonNegative("srcByteOffset", srcByteOffset)) return;
size_t elemSize = SizeOfViewElem(dstData);
@@ -4192,13 +4113,9 @@ void ClientWebGLContext::GenerateMipmap(GLenum texTarget) const {
void ClientWebGLContext::GetTexParameter(
JSContext* cx, GLenum texTarget, GLenum pname,
JS::MutableHandle<JS::Value> retval) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getTexParameter");
+ if (IsContextLost()) return;
auto& state = State();
auto& texUnit = state.mTexUnits[state.mActiveTexUnit];
@@ -4215,11 +4132,11 @@ void ClientWebGLContext::GetTexParameter(
}
const auto maybe = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetTexParameter(tex->mId, pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetTexParameter(tex->mId, pname, &ret)) {
@@ -4398,12 +4315,8 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
const Maybe<ivec3>& isize, GLint border,
const webgl::PackingInfo& pi,
const TexImageSource& src) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
-
const FuncScope funcScope(*this, "tex(Sub)Image[23]D");
+ if (IsContextLost()) return;
if (!IsTexTargetForDims(ImageToTexTarget(imageTarget), mIsWebGL2, funcDims)) {
EnqueueError_ArgEnum("imageTarget", imageTarget);
return;
@@ -4600,7 +4513,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
if (desc->sd) {
const auto& sd = *(desc->sd);
const auto sdType = sd.type();
- const auto& contextInfo = notLost->info;
+ const auto& contextInfo = mNotLost->info;
// TODO (Bug 754256): Figure out the source colorSpace.
const auto& webgl = this;
@@ -4647,7 +4560,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
} break;
case layers::SurfaceDescriptor::TSurfaceDescriptorD3D10: {
const auto& sdD3D = sd.get_SurfaceDescriptorD3D10();
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
MOZ_ASSERT(desc->image);
keepAliveImage = desc->image;
@@ -4657,7 +4570,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
}
} break;
case layers::SurfaceDescriptor::TSurfaceDescriptorGPUVideo: {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
MOZ_ASSERT(desc->image);
keepAliveImage = desc->image;
if (inProcess) {
@@ -4680,7 +4593,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
}
} break;
case layers::SurfaceDescriptor::TSurfaceDescriptorExternalImage: {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
MOZ_ASSERT(desc->sourceSurf);
keepAliveSurf = desc->sourceSurf;
if (inProcess) {
@@ -4689,7 +4602,7 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
}
} break;
case layers::SurfaceDescriptor::TSurfaceDescriptorCanvasSurface: {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
MOZ_ASSERT(desc->sourceSurf);
keepAliveSurf = desc->sourceSurf;
if (inProcess) {
@@ -4757,12 +4670,12 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
CastUvec3(offset), pi, std::move(*desc));
} else {
// We can't handle shmems like SurfaceDescriptorBuffer inline, so use ipdl.
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->TexImage(static_cast<uint32_t>(level), respecFormat,
CastUvec3(offset), pi, *desc);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
// The shmem we're handling was only shared from RDD to Content, and
@@ -4916,19 +4829,16 @@ void ClientWebGLContext::UseProgram(WebGLProgramJS* const prog) {
}
void ClientWebGLContext::ValidateProgram(WebGLProgramJS& prog) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
const FuncScope funcScope(*this, "validateProgram");
+ if (IsContextLost()) return;
if (!prog.ValidateUsable(*this, "prog")) return;
prog.mLastValidate = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->ValidateProgram(prog.mId);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
bool ret = {};
if (!child->SendValidateProgram(prog.mId, &ret)) {
@@ -4942,15 +4852,11 @@ void ClientWebGLContext::ValidateProgram(WebGLProgramJS& prog) const {
Maybe<double> ClientWebGLContext::GetVertexAttribPriv(const GLuint index,
const GLenum pname) {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return Nothing();
- }
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetVertexAttrib(index, pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetVertexAttrib(index, pname, &ret)) {
@@ -5383,10 +5289,9 @@ void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const Span<uint8_t> dest) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return false;
- }
+ const auto notLost =
+ mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
+ if (!notLost) return false;
const auto& inProcess = notLost->inProcess;
if (inProcess) {
inProcess->ReadPixelsInto(desc, dest);
@@ -5528,20 +5433,17 @@ void ClientWebGLContext::GetQuery(JSContext* cx, GLenum specificTarget,
void ClientWebGLContext::GetQueryParameter(
JSContext*, WebGLQueryJS& query, const GLenum pname,
JS::MutableHandle<JS::Value> retval) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getQueryParameter");
+ if (IsContextLost()) return;
if (!query.ValidateUsable(*this, "query")) return;
auto maybe = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetQueryParameter(query.mId, pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetQueryParameter(query.mId, pname, &ret)) {
@@ -5664,20 +5566,17 @@ void ClientWebGLContext::QueryCounter(WebGLQueryJS& query,
void ClientWebGLContext::GetSamplerParameter(
JSContext* cx, const WebGLSamplerJS& sampler, const GLenum pname,
JS::MutableHandle<JS::Value> retval) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return;
- }
retval.set(JS::NullValue());
const FuncScope funcScope(*this, "getSamplerParameter");
+ if (IsContextLost()) return;
if (!sampler.ValidateUsable(*this, "sampler")) return;
const auto maybe = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetSamplerParameter(sampler.mId, pname);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
Maybe<double> ret;
if (!child->SendGetSamplerParameter(sampler.mId, pname, &ret)) {
@@ -5768,11 +5667,8 @@ void ClientWebGLContext::GetSyncParameter(
GLenum ClientWebGLContext::ClientWaitSync(WebGLSyncJS& sync,
const GLbitfield flags,
const GLuint64 timeout) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return LOCAL_GL_WAIT_FAILED;
- }
const FuncScope funcScope(*this, "clientWaitSync");
+ if (IsContextLost()) return LOCAL_GL_WAIT_FAILED;
if (!sync.ValidateUsable(*this, "sync")) return LOCAL_GL_WAIT_FAILED;
static constexpr auto VALID_BITS = LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT;
@@ -5833,11 +5729,11 @@ GLenum ClientWebGLContext::ClientWaitSync(WebGLSyncJS& sync,
// Fine, time to block:
const auto ret = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->ClientWaitSync(sync.mId, flags, timeout);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
GLenum ret = {};
if (!child->SendClientWaitSync(sync.mId, flags, timeout, &ret)) {
@@ -6055,7 +5951,7 @@ void ClientWebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers) {
void ClientWebGLContext::EnqueueErrorImpl(const GLenum error,
const nsACString& text) const {
- if (IsContextLost()) return;
+ if (!mNotLost) return; // Ignored if context is lost.
AutoEnqueueFlush();
Run<RPROC(GenerateError)>(error, ToString(text));
}
@@ -6105,7 +6001,7 @@ void ClientWebGLContext::GetSupportedExtensions(
dom::Nullable<nsTArray<nsString>>& retval,
const dom::CallerType callerType) const {
retval.SetNull();
- if (IsContextLost()) return;
+ if (!mNotLost) return;
auto& retarr = retval.SetValue();
for (const auto i : MakeEnumeratedRange(WebGLExtensionID::Max)) {
@@ -6121,7 +6017,7 @@ void ClientWebGLContext::GetSupportedExtensions(
void ClientWebGLContext::GetSupportedProfilesASTC(
dom::Nullable<nsTArray<nsString>>& retval) const {
retval.SetNull();
- if (IsContextLost()) return;
+ if (!mNotLost) return;
const auto& limits = Limits();
auto& retarr = retval.SetValue();
@@ -6514,11 +6410,8 @@ GLint ClientWebGLContext::GetAttribLocation(const WebGLProgramJS& prog,
GLint ClientWebGLContext::GetFragDataLocation(const WebGLProgramJS& prog,
const nsAString& name) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return -1;
- }
const FuncScope funcScope(*this, "getFragDataLocation");
+ if (IsContextLost()) return -1;
if (!prog.ValidateUsable(*this, "program")) return -1;
const auto nameU8 = ToString(NS_ConvertUTF16toUTF8(name));
@@ -6530,11 +6423,11 @@ GLint ClientWebGLContext::GetFragDataLocation(const WebGLProgramJS& prog,
}
return [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetFragDataLocation(prog.mId, nameU8);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
GLint ret = {};
if (!child->SendGetFragDataLocation(prog.mId, nameU8, &ret)) {
@@ -6863,17 +6756,13 @@ void ClientWebGLContext::ShaderSource(WebGLShaderJS& shader,
const webgl::CompileResult& ClientWebGLContext::GetCompileResult(
const WebGLShaderJS& shader) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return shader.mResult;
- }
if (shader.mResult.pending) {
shader.mResult = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetCompileResult(shader.mId);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
webgl::CompileResult ret = {};
if (!child->SendGetCompileResult(shader.mId, &ret)) {
@@ -6887,17 +6776,17 @@ const webgl::CompileResult& ClientWebGLContext::GetCompileResult(
const webgl::LinkResult& ClientWebGLContext::GetLinkResult(
const WebGLProgramJS& prog) const {
- RefPtr<webgl::NotLostData> notLost(mNotLost);
- if (!notLost) {
- return *(prog.mResult);
- }
if (prog.mResult->pending) {
+ const auto notLost =
+ mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
+ if (!notLost) return *(prog.mResult);
+
*(prog.mResult) = [&]() {
- const auto& inProcess = notLost->inProcess;
+ const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
return inProcess->GetLinkResult(prog.mId);
}
- const auto& child = notLost->outOfProcess;
+ const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
webgl::LinkResult ret;
if (!child->SendGetLinkResult(prog.mId, &ret)) {