From cbff465051913919cdf769ce41d07f235296f9d5 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Thu, 18 Mar 2021 11:57:10 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1167420 - Handle fallible AppendElement call in netwerk/base/Dashboard.cpp. r=valentin (a485b8990) - Bug 968520 - Add mozilla::fallible to FallibleTArray::AppendElement calls. r=froydnj (12a529a0e) - Bug 1172584 - Avoid coping FallibleTArray in SendRequestRunnable constructor. r=dragana (c3a4a4253) - Bug 948466: Rename gfxPangoFonts to gfxFontconfigFonts. r=nical (43eed1f5f) - Bug 968520 - Add mozilla::fallible to more FallibleTArray calls. r=froydnj (339968a1d) - Bug 1166544 - Assume successful InsertElementAt calls in DOMSVG*List::MaybeInsertNullInAnimValListAt. r=dholbert (cf687dad7) - Bug 968520 - Add mozilla::fallible to FallibleTArray::InsertElementAt calls. r=froydnj (cc5c68ff2) - Bug 968520 - Add mozilla::fallible to more FallibleTArray::InsertElementsAt calls. r=froydnj (66df1d034) - Bug 1165735 - Make ThreadSharedFloatArrayBufferList::mContents infallible. r=roc (eda2839db) - Bug 1166544 - Use ReplaceElementAt instead of Clear and InsertElementAt in SVGMotionSMILType::Add. r=dholbert (474887a8c) - Bug 1167418 - Check AppendElement call in MediaQueryList. r=heycam (b6ed6d153) - Bug 1167418 - Use nsTArray instead of FallibleTArray in MediaQueryList. r=heycam (c9e3816d0) - Bug 1167418 - Follow-up: Fix bustage (5015e91ce) - Bug 1174220 - Part 1: Remove capacity constructor of MediaLargeByteBuffer. r=jya (66819d3e4) - Bug 1179282 - Use nsTArray::Assign instead of the assignment operator in dom/svg/. r=dholbert (cb3d43c19) - Bug 968520 - Add nsTArray::Assign. r=froydnj (e5eccf354) - Bug 1182277, don't leak when using nsAutoTArray inside nsTArray, r=nfroyd (bba32394c) - Bug 1143575. Avoid including Android's GraphicBuffer.h from LayersTypes.h. r=nical (99e4e2816) - Bug 1143575. Avoid use of COMPARE macro which can clash with Android headers. r=bent (99cfc74c4) - Bug 1143575. Add RefBase #include to stagefright stubs. r=cpearce (f9e327600) - Bug 1143575. test_HaveMetadataUnbufferedSeek should not wait for canplay since preload='metadata' elements may not fire canplay. r=cpearce (f1b0eee27) - Bug 1143575. Make GL context current before cleaning up programs. r=nical (d7b05b2bd) - partial Bug 1143575. Android's screenshotting code should invalidate the LayrManagerComposite to ensure composition will actually happen. r=nical (58fb296ab) - Bug 1143575. Remove unused Image::IsSentToCompositor tracking. r=nical (808d0b3f0) - Bug 1143575. Remove unused CompositionNotifySink. r=nical (98a332305) - Bug 1143575. Remove unused VideoFrameContainer::Reset. r=nical (e292bc722) - Bug 1143575. Rename mAsyncTransactionTrackeres to mAsyncTransactionTrackers. r=nical (df71ebf4f) - Bug 1143575. Remove unused ImageContainer::ResetPaintCount. r=nical (a92c5bf6e) - Bug 1143575. Remove unused VideoFrameContainer::ClearCurrentFrame aResetSize parameter. r=nical (5d3c9b83a) - Bug 1143575. Remove unused ReturnReleaseFence. r=nical (9d6ea92b5) - Bug 1143575. LayerManagerComposite can't get END_NO_COMPOSITE. r=mattwoodrow (0c5c364b5) - Bug 1143575. Remove unused AttachAsyncCompositable overload. r=nical (5fd3d4f6d) - Bug 1143575. Rename ImageBridgeChild's AutoRemoteTextures to AutoRemoveTexturesFromImageBridge to avoid clashes with later work. r=nical (34d67fcc0) - Bug 1143575. Fix some code formatting. r=nical (1d7f30f60) - Bug 1143575. Move mLayer from ImageClientBridge up into its superclass ImageClient. r=nical (40c902a36) - Bug 1127336 - Label HW-decoded frames with correct origin. - r=vlad (fd1580bcd) - Bug 1167504 - Part 1: Remove BindableName - Framebuffer. r=jgilbert (b3133eee6) - Bug 1167504 - Part 2: Remove BindableName - Renderbuffer. r=jgilbert (155a7e796) - Bug 1167504 - Part 3: Remove BindableName - Sampler. r=jgilbert (8c5c68960) - Bug 1167504 - Part 4: Remove BindableName - Texture. r=jgilbert (28077db04) - Bug 1167504 - Part 5: Remove BindableName - Transform Feedback. r=jgilbert (4fd839598) - Bug 1170454: Fix up instance type for VAOs. r=smaug,r=jgilbert (cc62d993a) - Bug 1167504 - Part 6: Remove BindableName - Vertex Array. r=jgilbert (1d54d5bc1) - Bug 1048724 - Implement GetBufferSubData. r=jgilbert, r=smaug (06570aa84) - Bug 1167504 - Part 7: Remove BindableName - Buffer. r=jgilbert (b2ddf3fc6) --- dom/base/Console.cpp | 22 ++-- dom/base/WebSocket.cpp | 2 +- dom/base/nsDOMMutationObserver.cpp | 5 +- dom/base/nsJSTimeoutHandler.cpp | 2 +- dom/base/nsScreen.cpp | 2 +- dom/bindings/Codegen.py | 4 +- dom/camera/DOMCameraControl.cpp | 2 +- dom/canvas/CanvasRenderingContext2D.cpp | 11 +- dom/canvas/CanvasUtils.h | 2 +- dom/canvas/WebGL2Context.h | 7 +- dom/canvas/WebGL2ContextBuffers.cpp | 91 ++++++++++++-- dom/canvas/WebGL2ContextFramebuffers.cpp | 6 +- dom/canvas/WebGL2ContextSamplers.cpp | 3 +- dom/canvas/WebGL2ContextTransformFeedback.cpp | 7 +- dom/canvas/WebGL2ContextVAOs.cpp | 19 +-- dom/canvas/WebGLBuffer.cpp | 17 ++- dom/canvas/WebGLBuffer.h | 12 +- dom/canvas/WebGLContext.cpp | 6 +- dom/canvas/WebGLContext.h | 2 + dom/canvas/WebGLContextDraw.cpp | 10 +- dom/canvas/WebGLContextGL.cpp | 52 ++++++-- dom/canvas/WebGLContextUnchecked.cpp | 22 ++-- dom/canvas/WebGLContextUtils.cpp | 14 +-- dom/canvas/WebGLContextVertexArray.cpp | 19 ++- dom/canvas/WebGLFramebuffer.cpp | 14 ++- dom/canvas/WebGLFramebuffer.h | 16 ++- dom/canvas/WebGLRenderbuffer.cpp | 9 +- dom/canvas/WebGLRenderbuffer.h | 13 +- dom/canvas/WebGLSampler.cpp | 4 +- dom/canvas/WebGLSampler.h | 4 +- dom/canvas/WebGLTexture.cpp | 21 ++-- dom/canvas/WebGLTexture.h | 11 +- dom/canvas/WebGLTransformFeedback.cpp | 4 +- dom/canvas/WebGLTransformFeedback.h | 5 +- dom/canvas/WebGLVertexArray.cpp | 9 +- dom/canvas/WebGLVertexArray.h | 13 +- dom/canvas/WebGLVertexArrayFake.cpp | 18 +++ dom/canvas/WebGLVertexArrayFake.h | 13 +- dom/canvas/WebGLVertexArrayGL.cpp | 38 +++++- dom/canvas/WebGLVertexArrayGL.h | 24 ++-- dom/canvas/WebGLVertexArrayObject.cpp | 35 ++++++ dom/canvas/WebGLVertexArrayObject.h | 42 +++++++ dom/canvas/moz.build | 2 + dom/datastore/DataStoreService.cpp | 2 +- dom/html/HTMLInputElement.cpp | 6 +- dom/indexedDB/ActorsParent.cpp | 20 +-- dom/indexedDB/IDBObjectStore.cpp | 9 +- dom/media/MediaData.cpp | 2 + dom/media/MediaData.h | 2 - dom/media/MediaDecoderStateMachine.cpp | 4 + dom/media/VideoFrameContainer.cpp | 14 +-- dom/media/VideoFrameContainer.h | 4 +- .../test/test_HaveMetadataUnbufferedSeek.html | 6 +- dom/media/webaudio/AudioNodeEngine.h | 2 +- dom/mobilemessage/ipc/SmsChild.cpp | 8 +- dom/network/TCPSocketChild.cpp | 3 +- dom/network/TCPSocketParent.cpp | 2 +- dom/network/UDPSocketChild.cpp | 2 +- dom/network/UDPSocketParent.cpp | 2 +- dom/nfc/gonk/NfcService.cpp | 11 +- dom/plugins/base/nsNPAPIPluginInstance.cpp | 2 +- dom/plugins/ipc/PluginInstanceParent.cpp | 11 -- dom/plugins/ipc/PluginInstanceParent.h | 2 - dom/security/nsCSPContext.cpp | 2 +- dom/security/nsCSPUtils.cpp | 4 +- dom/smil/nsSMILAnimationFunction.cpp | 10 +- dom/smil/nsSMILParserUtils.cpp | 7 +- dom/svg/DOMSVGLengthList.cpp | 4 +- dom/svg/DOMSVGNumberList.cpp | 4 +- dom/svg/DOMSVGPathSegList.cpp | 13 +- dom/svg/DOMSVGPointList.cpp | 4 +- dom/svg/DOMSVGTransformList.cpp | 5 +- dom/svg/SVGLengthList.cpp | 4 +- dom/svg/SVGLengthList.h | 4 +- dom/svg/SVGMotionSMILAnimationFunction.cpp | 9 +- dom/svg/SVGMotionSMILPathUtils.cpp | 4 +- dom/svg/SVGMotionSMILType.cpp | 16 ++- dom/svg/SVGNumberList.cpp | 4 +- dom/svg/SVGNumberList.h | 4 +- dom/svg/SVGPathData.cpp | 6 +- dom/svg/SVGPointList.cpp | 4 +- dom/svg/SVGPointList.h | 4 +- dom/svg/SVGStringList.cpp | 4 +- dom/svg/SVGStringList.h | 4 +- dom/svg/SVGTransformList.cpp | 4 +- dom/svg/SVGTransformList.h | 4 +- dom/svg/SVGTransformListParser.cpp | 12 +- dom/svg/SVGTransformListSMILType.cpp | 23 ++-- dom/tv/TVSource.cpp | 2 +- dom/webidl/WebGL2RenderingContext.webidl | 7 +- gfx/gl/GLBlitHelper.cpp | 116 ++++++++---------- gfx/gl/GLBlitHelper.h | 21 ++-- gfx/gl/GLContext.cpp | 2 +- gfx/layers/GLImages.cpp | 14 ++- gfx/layers/ImageContainer.cpp | 1 - gfx/layers/ImageContainer.h | 32 +---- gfx/layers/LayersTypes.cpp | 58 +++++++++ gfx/layers/LayersTypes.h | 31 ++--- gfx/layers/apz/testutil/APZTestData.cpp | 2 +- gfx/layers/apz/util/APZCCallbackHelper.cpp | 3 + gfx/layers/apz/util/APZCCallbackHelper.h | 2 + gfx/layers/client/ClientImageLayer.cpp | 6 +- gfx/layers/client/ClientLayerManager.cpp | 14 --- gfx/layers/client/CompositableClient.h | 3 +- gfx/layers/client/ContentClient.cpp | 12 +- gfx/layers/client/ImageClient.cpp | 35 ++---- gfx/layers/client/ImageClient.h | 23 ++-- gfx/layers/client/TextureClient.h | 4 +- gfx/layers/client/TiledContentClient.cpp | 12 +- gfx/layers/composite/FrameUniformityData.cpp | 3 +- .../composite/LayerManagerComposite.cpp | 8 +- gfx/layers/ipc/AsyncTransactionTracker.cpp | 65 +++++----- gfx/layers/ipc/AsyncTransactionTracker.h | 58 ++++++--- gfx/layers/ipc/CompositorParent.cpp | 17 +++ gfx/layers/ipc/CompositorParent.h | 2 + gfx/layers/ipc/ImageBridgeChild.cpp | 53 ++++---- gfx/layers/ipc/LayersMessages.ipdlh | 8 -- gfx/layers/ipc/ShadowLayers.h | 7 -- gfx/layers/moz.build | 1 + gfx/layers/opengl/CompositorOGL.cpp | 14 ++- gfx/layers/opengl/GrallocTextureClient.cpp | 10 +- gfx/layers/opengl/GrallocTextureClient.h | 4 +- gfx/thebes/gfxDWriteFontList.cpp | 14 +-- gfx/thebes/gfxFT2FontList.cpp | 2 +- gfx/thebes/gfxFcPlatformFontList.cpp | 4 +- gfx/thebes/gfxFont.h | 2 +- ...xPangoFonts.cpp => gfxFontconfigFonts.cpp} | 16 ++- .../{gfxPangoFonts.h => gfxFontconfigFonts.h} | 6 +- gfx/thebes/gfxGDIFontList.cpp | 6 +- gfx/thebes/gfxPlatformGtk.cpp | 2 +- gfx/thebes/gfxQtPlatform.cpp | 2 +- gfx/thebes/moz.build | 8 +- image/SourceBuffer.cpp | 2 +- intl/lwbrk/nsPangoBreaker.cpp | 2 +- ipc/glue/IPCMessageUtils.h | 2 +- layout/base/FrameLayerBuilder.cpp | 2 +- layout/base/SelectionCarets.cpp | 16 +-- layout/base/TouchCaret.cpp | 2 +- layout/base/nsPresContext.cpp | 2 +- layout/style/MediaQueryList.cpp | 14 ++- layout/style/MediaQueryList.h | 7 +- media/libstagefright/binding/Index.cpp | 5 +- media/libstagefright/binding/MP4Metadata.cpp | 5 +- media/libstagefright/binding/MoofParser.cpp | 5 +- .../media/stagefright/foundation/AMessage.h | 2 + .../stubs/include/ui/GraphicBuffer.h | 2 + .../src/peerconnection/PeerConnectionImpl.cpp | 16 ++- .../WebrtcGlobalInformation.cpp | 18 +-- netwerk/base/Dashboard.cpp | 30 +++-- netwerk/base/nsUDPSocket.cpp | 13 +- widget/gonk/nsScreenManagerGonk.h | 2 + xpcom/glue/nsTArray.h | 31 +++++ xpcom/io/nsPipe3.cpp | 16 +-- xpcom/tests/gtest/TestTArray.cpp | 57 +++++++++ xpcom/tests/gtest/moz.build | 1 + 155 files changed, 1151 insertions(+), 724 deletions(-) create mode 100644 dom/canvas/WebGLVertexArrayObject.cpp create mode 100644 dom/canvas/WebGLVertexArrayObject.h create mode 100644 gfx/layers/LayersTypes.cpp rename gfx/thebes/{gfxPangoFonts.cpp => gfxFontconfigFonts.cpp} (99%) rename gfx/thebes/{gfxPangoFonts.h => gfxFontconfigFonts.h} (97%) create mode 100644 xpcom/tests/gtest/TestTArray.cpp diff --git a/dom/base/Console.cpp b/dom/base/Console.cpp index 703db08ac8..3f23f59ec8 100644 --- a/dom/base/Console.cpp +++ b/dom/base/Console.cpp @@ -607,7 +607,7 @@ private: return; } - if (!arguments.AppendElement(value)) { + if (!arguments.AppendElement(value, fallible)) { return; } } @@ -768,7 +768,7 @@ Console::Time(JSContext* aCx, const JS::Handle aTime) Sequence data; SequenceRooter rooter(aCx, &data); - if (!aTime.isUndefined() && !data.AppendElement(aTime)) { + if (!aTime.isUndefined() && !data.AppendElement(aTime, fallible)) { return; } @@ -781,7 +781,7 @@ Console::TimeEnd(JSContext* aCx, const JS::Handle aTime) Sequence data; SequenceRooter rooter(aCx, &data); - if (!aTime.isUndefined() && !data.AppendElement(aTime)) { + if (!aTime.isUndefined() && !data.AppendElement(aTime, fallible)) { return; } @@ -794,7 +794,7 @@ Console::TimeStamp(JSContext* aCx, const JS::Handle aData) Sequence data; SequenceRooter rooter(aCx, &data); - if (aData.isString() && !data.AppendElement(aData)) { + if (aData.isString() && !data.AppendElement(aData, fallible)) { return; } @@ -834,7 +834,7 @@ Console::ProfileMethod(JSContext* aCx, const nsAString& aAction, Sequence& sequence = event.mArguments.Value(); for (uint32_t i = 0; i < aData.Length(); ++i) { - if (!sequence.AppendElement(aData[i])) { + if (!sequence.AppendElement(aData[i], fallible)) { return; } } @@ -1380,7 +1380,7 @@ FlushOutput(JSContext* aCx, Sequence& aSequence, nsString &aOutput) return false; } - if (!aSequence.AppendElement(JS::StringValue(str))) { + if (!aSequence.AppendElement(JS::StringValue(str), fallible)) { return false; } @@ -1511,7 +1511,7 @@ Console::ProcessArguments(JSContext* aCx, v = aData[index++]; } - if (!aSequence.AppendElement(v)) { + if (!aSequence.AppendElement(v, fallible)) { return false; } @@ -1534,13 +1534,13 @@ Console::ProcessArguments(JSContext* aCx, int32_t diff = aSequence.Length() - aStyles.Length(); if (diff > 0) { for (int32_t i = 0; i < diff; i++) { - if (!aStyles.AppendElement(JS::NullValue())) { + if (!aStyles.AppendElement(JS::NullValue(), fallible)) { return false; } } } - if (!aStyles.AppendElement(JS::StringValue(jsString))) { + if (!aStyles.AppendElement(JS::StringValue(jsString), fallible)) { return false; } } @@ -1612,7 +1612,7 @@ Console::ProcessArguments(JSContext* aCx, // The rest of the array, if unused by the format string. for (; index < aData.Length(); ++index) { - if (!aSequence.AppendElement(aData[index])) { + if (!aSequence.AppendElement(aData[index], fallible)) { return false; } } @@ -1748,7 +1748,7 @@ Console::ArgumentsToValueList(const nsTArray>& aData, Sequence& aSequence) { for (uint32_t i = 0; i < aData.Length(); ++i) { - if (!aSequence.AppendElement(aData[i])) { + if (!aSequence.AppendElement(aData[i], fallible)) { return false; } } diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index 9dd37515f1..7d13d466eb 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -1004,7 +1004,7 @@ WebSocket::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { Sequence protocols; - if (!protocols.AppendElement(aProtocol)) { + if (!protocols.AppendElement(aProtocol, fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index 8f9fc0b6ad..51584c1cc3 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -715,7 +715,8 @@ nsDOMMutationObserver::GetObservingInfo( mozilla::dom::Sequence& filtersAsStrings = info.mAttributeFilter.Value(); for (int32_t j = 0; j < filters.Count(); ++j) { - if (!filtersAsStrings.AppendElement(nsDependentAtomString(filters[j]))) { + if (!filtersAsStrings.AppendElement(nsDependentAtomString(filters[j]), + mozilla::fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } @@ -774,7 +775,7 @@ nsDOMMutationObserver::HandleMutation() for (uint32_t i = 0; i < mPendingMutationCount; ++i) { nsRefPtr next; current->mNext.swap(next); - *mutations.AppendElement() = current; + *mutations.AppendElement(mozilla::fallible) = current; current.swap(next); } } diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp index fba0a362ee..d413c419d5 100644 --- a/dom/base/nsJSTimeoutHandler.cpp +++ b/dom/base/nsJSTimeoutHandler.cpp @@ -368,7 +368,7 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval, return NS_ERROR_OUT_OF_MEMORY; } for (uint32_t idx = 0; idx < argCount; ++idx) { - *args.AppendElement() = argv[idx + 2]; + *args.AppendElement(fallible) = argv[idx + 2]; } args.SwapElements(mArgs); } else { diff --git a/dom/base/nsScreen.cpp b/dom/base/nsScreen.cpp index b2c57faf3b..b1249691f2 100644 --- a/dom/base/nsScreen.cpp +++ b/dom/base/nsScreen.cpp @@ -247,7 +247,7 @@ nsScreen::MozLockOrientation(const nsAString& aOrientation, ErrorResult& aRv) { nsString orientation(aOrientation); Sequence orientations; - if (!orientations.AppendElement(orientation)) { + if (!orientations.AppendElement(orientation, fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return false; } diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 729c293ab3..d52d0b0aeb 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -4337,7 +4337,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if (done${nestingLevel}) { break; } - ${elementType}* slotPtr${nestingLevel} = arr${nestingLevel}.AppendElement(); + ${elementType}* slotPtr${nestingLevel} = arr${nestingLevel}.AppendElement(mozilla::fallible); if (!slotPtr${nestingLevel}) { JS_ReportOutOfMemory(cx); $*{exceptionCode} @@ -5632,7 +5632,7 @@ class CGArgumentConverter(CGThing): return false; } for (uint32_t variadicArg = ${index}; variadicArg < ${argc}; ++variadicArg) { - ${elemType}& slot = *${declName}.AppendElement(); + ${elemType}& slot = *${declName}.AppendElement(mozilla::fallible); """) ).substitute(replacer) diff --git a/dom/camera/DOMCameraControl.cpp b/dom/camera/DOMCameraControl.cpp index d6befde08f..1c6ca8c55f 100644 --- a/dom/camera/DOMCameraControl.cpp +++ b/dom/camera/DOMCameraControl.cpp @@ -1374,7 +1374,7 @@ nsDOMCameraControl::OnFacesDetected(const nsTArray& aFaces if (faces.SetCapacity(len, fallible)) { for (uint32_t i = 0; i < len; ++i) { - *faces.AppendElement() = + *faces.AppendElement(fallible) = new DOMCameraDetectedFace(static_cast(this), aFaces[i]); } } diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 4a919fa6fc..3bc637a609 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -2799,7 +2799,7 @@ void CanvasRenderingContext2D::DrawFocusIfNeeded(mozilla::dom::Element& aElement // set dashing for foreground FallibleTArray& dash = CurrentState().dash; for (uint32_t i = 0; i < 2; ++i) { - if (!dash.AppendElement(1)) { + if (!dash.AppendElement(1, fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } @@ -4108,14 +4108,14 @@ CanvasRenderingContext2D::SetLineDash(const Sequence& aSegments, return; } - if (!dash.AppendElement(aSegments[x])) { + if (!dash.AppendElement(aSegments[x], fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } } if (aSegments.Length() % 2) { // If the number of elements is odd, concatenate again for (uint32_t x = 0; x < aSegments.Length(); x++) { - if (!dash.AppendElement(aSegments[x])) { + if (!dash.AppendElement(aSegments[x], fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } @@ -4429,7 +4429,10 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR); gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR); } - bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), mVideoTexture, LOCAL_GL_TEXTURE_2D, 1); + const gl::OriginPos destOrigin = gl::OriginPos::TopLeft; + bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), + mVideoTexture, LOCAL_GL_TEXTURE_2D, + destOrigin); if (ok) { NativeSurface texSurf; texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE; diff --git a/dom/canvas/CanvasUtils.h b/dom/canvas/CanvasUtils.h index 673c5c04f9..118f709652 100644 --- a/dom/canvas/CanvasUtils.h +++ b/dom/canvas/CanvasUtils.h @@ -129,7 +129,7 @@ JSValToDashArray(JSContext* cx, const JS::Value& patternArray, } else if (d > 0.0) { haveNonzeroElement = true; } - if (!dashes.AppendElement(d)) { + if (!dashes.AppendElement(d, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h index b4fdee0e18..997ee006bd 100644 --- a/dom/canvas/WebGL2Context.h +++ b/dom/canvas/WebGL2Context.h @@ -45,8 +45,9 @@ public: void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); - void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBuffer& returnedData); - void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBufferView& returnedData); + void GetBufferSubData(GLenum target, GLintptr offset, + const dom::Nullable& maybeData); + // ------------------------------------------------------------------------- // Framebuffer objects - WebGL2ContextFramebuffers.cpp @@ -276,6 +277,8 @@ private: GLsizei width, GLsizei height, GLsizei depth, const char* info); + // CreateVertexArrayImpl is assumed to be infallible. + virtual WebGLVertexArray* CreateVertexArrayImpl() override; virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override; virtual bool ValidateBufferTarget(GLenum target, const char* info) override; virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override; diff --git a/dom/canvas/WebGL2ContextBuffers.cpp b/dom/canvas/WebGL2ContextBuffers.cpp index 952ab5ac36..9fe6b41617 100644 --- a/dom/canvas/WebGL2ContextBuffers.cpp +++ b/dom/canvas/WebGL2ContextBuffers.cpp @@ -71,7 +71,7 @@ WebGL2Context::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, } ErrorInvalidOperation("%s: buffer already bound to a incompatible target %s", - info, EnumName(buffer->Target().get())); + info, EnumName(buffer->Target())); return false; } @@ -129,14 +129,87 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget, void WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset, - const dom::ArrayBuffer& returnedData) + const dom::Nullable& maybeData) { - MOZ_CRASH("Not Implemented."); -} + if (IsContextLost()) + return; -void -WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset, - const dom::ArrayBufferView& returnedData) -{ - MOZ_CRASH("Not Implemented."); + // For the WebGLBuffer bound to the passed target, read + // returnedData.byteLength bytes from the buffer starting at byte + // offset offset and write them to returnedData. + + // If zero is bound to target, an INVALID_OPERATION error is + // generated. + if (!ValidateBufferTarget(target, "getBufferSubData")) + return; + + // If offset is less than zero, an INVALID_VALUE error is + // generated. + if (offset < 0) + return ErrorInvalidValue("getBufferSubData: negative offset"); + + // If returnedData is null then an INVALID_VALUE error is + // generated. + if (maybeData.IsNull()) + return ErrorInvalidValue("getBufferSubData: returnedData is null"); + + WebGLRefPtr& bufferSlot = GetBufferSlotByTarget(target); + WebGLBuffer* boundBuffer = bufferSlot.get(); + if (!boundBuffer) + return ErrorInvalidOperation("getBufferSubData: no buffer bound"); + + // If offset + returnedData.byteLength would extend beyond the end + // of the buffer an INVALID_VALUE error is generated. + const dom::ArrayBuffer& data = maybeData.Value(); + data.ComputeLengthAndData(); + + CheckedInt neededByteLength = CheckedInt(offset) + data.Length(); + if (!neededByteLength.isValid()) { + ErrorInvalidValue("getBufferSubData: Integer overflow computing the needed" + " byte length."); + return; + } + + if (neededByteLength.value() > boundBuffer->ByteLength()) { + ErrorInvalidValue("getBufferSubData: Not enough data. Operation requires" + " %d bytes, but buffer only has %d bytes.", + neededByteLength.value(), boundBuffer->ByteLength()); + return; + } + + // If target is TRANSFORM_FEEDBACK_BUFFER, and any transform + // feedback object is currently active, an INVALID_OPERATION error + // is generated. + WebGLTransformFeedback* currentTF = mBoundTransformFeedback; + if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER && currentTF) { + if (currentTF->mIsActive) + return ErrorInvalidOperation("getBufferSubData: Currently bound transform" + " feedback is active"); + + // https://github.com/NVIDIA/WebGL/commit/63aff5e58c1d79825a596f0f4aa46174b9a5f72c + // Performing reads and writes on a buffer that is currently + // bound for transform feedback causes undefined results in + // GLES3.0 and OpenGL 4.5. In practice results of reads and + // writes might be consistent as long as transform feedback + // objects are not active, but neither GLES3.0 nor OpenGL 4.5 + // spec guarantees this - just being bound for transform + // feedback is sufficient to cause undefined results. + + BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, nullptr); + } + + /* If the buffer is written and read sequentially by other + * operations and getBufferSubData, it is the responsibility of + * the WebGL API to ensure that data are access + * consistently. This applies even if the buffer is currently + * bound to a transform feedback binding point. + */ + + void* ptr = gl->fMapBufferRange(target, offset, data.Length(), LOCAL_GL_MAP_READ_BIT); + memcpy(data.Data(), ptr, data.Length()); + gl->fUnmapBuffer(target); + + if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER && currentTF) { + BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, currentTF); + } } diff --git a/dom/canvas/WebGL2ContextFramebuffers.cpp b/dom/canvas/WebGL2ContextFramebuffers.cpp index 66fca94612..84ae4873bf 100644 --- a/dom/canvas/WebGL2ContextFramebuffers.cpp +++ b/dom/canvas/WebGL2ContextFramebuffers.cpp @@ -349,19 +349,19 @@ TranslateDefaultAttachments(const dom::Sequence& in, dom::SequenceAppendElement(LOCAL_GL_COLOR_ATTACHMENT0)) { + if (!out->AppendElement(LOCAL_GL_COLOR_ATTACHMENT0, fallible)) { return false; } break; case LOCAL_GL_DEPTH: - if (!out->AppendElement(LOCAL_GL_DEPTH_ATTACHMENT)) { + if (!out->AppendElement(LOCAL_GL_DEPTH_ATTACHMENT, fallible)) { return false; } break; case LOCAL_GL_STENCIL: - if (!out->AppendElement(LOCAL_GL_STENCIL_ATTACHMENT)) { + if (!out->AppendElement(LOCAL_GL_STENCIL_ATTACHMENT, fallible)) { return false; } break; diff --git a/dom/canvas/WebGL2ContextSamplers.cpp b/dom/canvas/WebGL2ContextSamplers.cpp index 922ed4ad15..bad4b50bdb 100644 --- a/dom/canvas/WebGL2ContextSamplers.cpp +++ b/dom/canvas/WebGL2ContextSamplers.cpp @@ -54,7 +54,8 @@ WebGL2Context::IsSampler(WebGLSampler* sampler) if (sampler->IsDeleted()) return false; - return !sampler->HasEverBeenBound(); + MakeContextCurrent(); + return gl->fIsSampler(sampler->mGLName); } void diff --git a/dom/canvas/WebGL2ContextTransformFeedback.cpp b/dom/canvas/WebGL2ContextTransformFeedback.cpp index 17a13312bc..9dd96f9464 100644 --- a/dom/canvas/WebGL2ContextTransformFeedback.cpp +++ b/dom/canvas/WebGL2ContextTransformFeedback.cpp @@ -60,7 +60,7 @@ WebGL2Context::IsTransformFeedback(WebGLTransformFeedback* tf) return false; MakeContextCurrent(); - return gl->fIsTransformFeedback(tf->GLName()); + return gl->fIsTransformFeedback(tf->mGLName); } void @@ -84,11 +84,8 @@ WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf) if (tf && tf->IsDeleted()) return ErrorInvalidOperation("bindTransformFeedback: Attempt to bind deleted id"); - if (tf) - tf->BindTo(LOCAL_GL_TRANSFORM_FEEDBACK); - MakeContextCurrent(); - gl->fBindTransformFeedback(target, tf ? tf->GLName() : 0); + gl->fBindTransformFeedback(target, tf ? tf->mGLName : 0); if (tf) mBoundTransformFeedback = tf; else diff --git a/dom/canvas/WebGL2ContextVAOs.cpp b/dom/canvas/WebGL2ContextVAOs.cpp index 2957bfd4a3..5e58c91b0a 100644 --- a/dom/canvas/WebGL2ContextVAOs.cpp +++ b/dom/canvas/WebGL2ContextVAOs.cpp @@ -5,16 +5,17 @@ #include "WebGL2Context.h" #include "GLContext.h" +#include "WebGLVertexArrayObject.h" -using namespace mozilla; -using namespace mozilla::dom; +namespace mozilla { // ------------------------------------------------------------------------- // Vertex Array Object -// TODO(djg): Implemented in WebGLContext -/* - already_AddRefed CreateVertexArray(); - void DeleteVertexArray(WebGLVertexArrayObject* vertexArray); - bool IsVertexArray(WebGLVertexArrayObject* vertexArray); - void BindVertexArray(WebGLVertexArrayObject* vertexArray); -*/ + +WebGLVertexArray* +WebGL2Context::CreateVertexArrayImpl() +{ + return dom::WebGLVertexArrayObject::Create(this); +} + +} // namespace mozilla diff --git a/dom/canvas/WebGLBuffer.cpp b/dom/canvas/WebGLBuffer.cpp index d6909bd2a1..7126f08801 100644 --- a/dom/canvas/WebGLBuffer.cpp +++ b/dom/canvas/WebGLBuffer.cpp @@ -13,8 +13,9 @@ namespace mozilla { WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf) - : WebGLBindableName(buf) - , WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) + , mGLName(buf) + , mTarget(LOCAL_GL_NONE) , mByteLength(0) { mContext->mBuffers.insertBack(this); @@ -35,6 +36,18 @@ WebGLBuffer::Delete() LinkedListElement::remove(); // remove from mContext->mBuffers } +void +WebGLBuffer::BindTo(GLenum target) +{ + MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE."); + MOZ_ASSERT(!HasEverBeenBound() || mTarget == target, "Rebinding is illegal."); + + bool targetChanged = (target != mTarget); + mTarget = target; + if (targetChanged) + OnTargetChanged(); +} + void WebGLBuffer::OnTargetChanged() { diff --git a/dom/canvas/WebGLBuffer.h b/dom/canvas/WebGLBuffer.h index 76b5bfc9e6..f5a810473e 100644 --- a/dom/canvas/WebGLBuffer.h +++ b/dom/canvas/WebGLBuffer.h @@ -10,7 +10,6 @@ #include "mozilla/LinkedList.h" #include "mozilla/MemoryReporting.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLObjectModel.h" #include "WebGLStrongTypes.h" #include "WebGLTypes.h" @@ -21,7 +20,6 @@ class WebGLElementArrayCache; class WebGLBuffer final : public nsWrapperCache - , public WebGLBindableName , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject @@ -41,6 +39,10 @@ public: void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t updateSizeInBytes); + void BindTo(GLenum target); + bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; } + GLenum Target() const { return mTarget; } + bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count, uint32_t* const out_upperBound); @@ -52,13 +54,17 @@ public: virtual JSObject* WrapObject(JSContext* cx, JS::Handle aGivenProto) override; + const GLenum mGLName; + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer) protected: ~WebGLBuffer(); - virtual void OnTargetChanged() override; + void OnTargetChanged(); + + GLenum mTarget; WebGLsizeiptr mByteLength; nsAutoPtr mCache; diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 757e4ca3e9..745b361785 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -1871,11 +1871,13 @@ WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget, 0, format, type, nullptr); } + const gl::OriginPos destOrigin = mPixelStoreFlipY ? gl::OriginPos::BottomLeft + : gl::OriginPos::TopLeft; bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), - tex->GLName(), + tex->mGLName, texImageTarget.get(), - mPixelStoreFlipY); + destOrigin); if (ok) { TexInternalFormat effectiveInternalFormat = EffectiveInternalFormatFromInternalFormatAndType(internalFormat, diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 050840c756..7d27ec3f6e 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -1385,6 +1385,8 @@ private: private: // ------------------------------------------------------------------------- // Context customization points + virtual WebGLVertexArray* CreateVertexArrayImpl(); + virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) = 0; virtual bool ValidateBufferTarget(GLenum target, const char* info) = 0; virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0; diff --git a/dom/canvas/WebGLContextDraw.cpp b/dom/canvas/WebGLContextDraw.cpp index 2c725ae82f..2110de5d70 100644 --- a/dom/canvas/WebGLContextDraw.cpp +++ b/dom/canvas/WebGLContextDraw.cpp @@ -598,7 +598,7 @@ WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount) } GLenum error = GetAndFlushUnderlyingGLErrors(); - gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0); + gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0); // note that we do this error checking and early return AFTER having restored the buffer binding above if (error) { @@ -624,7 +624,7 @@ WebGLContext::UndoFakeVertexAttrib0() if (mBoundVertexArray->HasAttrib(0) && mBoundVertexArray->mAttribs[0].buf) { const WebGLVertexAttribData& attrib0 = mBoundVertexArray->mAttribs[0]; - gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.buf->GLName()); + gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.buf->mGLName); if (attrib0.integer) { gl->fVertexAttribIPointer(0, attrib0.size, @@ -643,7 +643,7 @@ WebGLContext::UndoFakeVertexAttrib0() gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); } - gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0); + gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0); } WebGLContextFakeBlackStatus @@ -735,11 +735,11 @@ WebGLContext::UnbindFakeBlackTextures() for (int32_t i = 0; i < mGLMaxTextureUnits; ++i) { if (mBound2DTextures[i] && mBound2DTextures[i]->ResolvedFakeBlackStatus() != WebGLTextureFakeBlackStatus::NotNeeded) { gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i); - gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBound2DTextures[i]->GLName()); + gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mBound2DTextures[i]->mGLName); } if (mBoundCubeMapTextures[i] && mBoundCubeMapTextures[i]->ResolvedFakeBlackStatus() != WebGLTextureFakeBlackStatus::NotNeeded) { gl->fActiveTexture(LOCAL_GL_TEXTURE0 + i); - gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->GLName()); + gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, mBoundCubeMapTextures[i]->mGLName); } } diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp index 5d41c1fcf7..c67a360085 100644 --- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -160,9 +160,11 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb) if (!wfb) { gl->fBindFramebuffer(target, 0); } else { - wfb->BindTo(target); - GLuint framebuffername = wfb->GLName(); + GLuint framebuffername = wfb->mGLName; gl->fBindFramebuffer(target, framebuffername); +#ifdef ANDROID + wfb->mIsFB = true; +#endif } switch (target) { @@ -197,15 +199,15 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb) if (wrb && wrb->IsDeleted()) return; - if (wrb) - wrb->BindTo(target); - MakeContextCurrent(); // Sometimes we emulate renderbuffers (depth-stencil emu), so there's not // always a 1-1 mapping from `wrb` to GL name. Just have `wrb` handle it. if (wrb) { wrb->BindRenderbuffer(); +#ifdef ANDROID + wrb->mIsRB = true; +#endif } else { gl->fBindRenderbuffer(target, 0); } @@ -750,7 +752,7 @@ WebGLContext::DeleteTexture(WebGLTexture* tex) (mBound3DTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_3D)) { ActiveTexture(LOCAL_GL_TEXTURE0 + i); - BindTexture(tex->Target().get(), nullptr); + BindTexture(tex->Target(), nullptr); } } ActiveTexture(LOCAL_GL_TEXTURE0 + activeTexture); @@ -1704,9 +1706,22 @@ WebGLContext::IsFramebuffer(WebGLFramebuffer* fb) if (IsContextLost()) return false; - return ValidateObjectAllowDeleted("isFramebuffer", fb) && - !fb->IsDeleted() && - fb->HasEverBeenBound(); + if (!ValidateObjectAllowDeleted("isFramebuffer", fb)) + return false; + + if (fb->IsDeleted()) + return false; + +#ifdef ANDROID + if (gl->WorkAroundDriverBugs() && + gl->Renderer() == GLRenderer::AndroidEmulator) + { + return fb->mIsFB; + } +#endif + + MakeContextCurrent(); + return gl->fIsFramebuffer(fb->mGLName); } bool @@ -1724,9 +1739,22 @@ WebGLContext::IsRenderbuffer(WebGLRenderbuffer* rb) if (IsContextLost()) return false; - return ValidateObjectAllowDeleted("isRenderBuffer", rb) && - !rb->IsDeleted() && - rb->HasEverBeenBound(); + if (!ValidateObjectAllowDeleted("isRenderBuffer", rb)) + return false; + + if (rb->IsDeleted()) + return false; + +#ifdef ANDROID + if (gl->WorkAroundDriverBugs() && + gl->Renderer() == GLRenderer::AndroidEmulator) + { + return rb->mIsRB; + } +#endif + + MakeContextCurrent(); + return gl->fIsRenderbuffer(rb->PrimaryGLName()); } bool diff --git a/dom/canvas/WebGLContextUnchecked.cpp b/dom/canvas/WebGLContextUnchecked.cpp index 3b0acf1867..3824bc3037 100644 --- a/dom/canvas/WebGLContextUnchecked.cpp +++ b/dom/canvas/WebGLContextUnchecked.cpp @@ -24,21 +24,21 @@ void WebGLContextUnchecked::BindBuffer(GLenum target, WebGLBuffer* buffer) { gl->MakeCurrent(); - gl->fBindBuffer(target, buffer ? buffer->GLName() : 0); + gl->fBindBuffer(target, buffer ? buffer->mGLName : 0); } void WebGLContextUnchecked::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer) { gl->MakeCurrent(); - gl->fBindBufferBase(target, index, buffer ? buffer->GLName() : 0); + gl->fBindBufferBase(target, index, buffer ? buffer->mGLName : 0); } void WebGLContextUnchecked::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, WebGLintptr offset, WebGLsizeiptr size) { gl->MakeCurrent(); - gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size); + gl->fBindBufferRange(target, index, buffer ? buffer->mGLName : 0, offset, size); } void @@ -56,9 +56,7 @@ void WebGLContextUnchecked::BindSampler(GLuint unit, WebGLSampler* sampler) { gl->MakeCurrent(); - gl->fBindSampler(unit, sampler ? sampler->GLName() : 0); - if (sampler) - sampler->BindTo(LOCAL_GL_SAMPLER_BINDING); + gl->fBindSampler(unit, sampler ? sampler->mGLName : 0); } GLint @@ -69,7 +67,7 @@ WebGLContextUnchecked::GetSamplerParameteriv(WebGLSampler* sampler, GLint param = 0; gl->MakeCurrent(); - gl->fGetSamplerParameteriv(sampler->GLName(), pname, ¶m); + gl->fGetSamplerParameteriv(sampler->mGLName, pname, ¶m); return param; } @@ -82,7 +80,7 @@ WebGLContextUnchecked::GetSamplerParameterfv(WebGLSampler* sampler, GLfloat param = 0.0f; gl->MakeCurrent(); - gl->fGetSamplerParameterfv(sampler->GLName(), pname, ¶m); + gl->fGetSamplerParameterfv(sampler->mGLName, pname, ¶m); return param; } @@ -93,7 +91,7 @@ WebGLContextUnchecked::SamplerParameteri(WebGLSampler* sampler, { MOZ_ASSERT(sampler, "Did you validate?"); gl->MakeCurrent(); - gl->fSamplerParameteri(sampler->GLName(), pname, param); + gl->fSamplerParameteri(sampler->mGLName, pname, param); } void @@ -103,7 +101,7 @@ WebGLContextUnchecked::SamplerParameteriv(WebGLSampler* sampler, { MOZ_ASSERT(sampler, "Did you validate?"); gl->MakeCurrent(); - gl->fSamplerParameteriv(sampler->GLName(), pname, param); + gl->fSamplerParameteriv(sampler->mGLName, pname, param); } void @@ -113,7 +111,7 @@ WebGLContextUnchecked::SamplerParameterf(WebGLSampler* sampler, { MOZ_ASSERT(sampler, "Did you validate?"); gl->MakeCurrent(); - gl->fSamplerParameterf(sampler->GLName(), pname, param); + gl->fSamplerParameterf(sampler->mGLName, pname, param); } void @@ -123,7 +121,7 @@ WebGLContextUnchecked::SamplerParameterfv(WebGLSampler* sampler, { MOZ_ASSERT(sampler, "Did you validate?"); gl->MakeCurrent(); - gl->fSamplerParameterfv(sampler->GLName(), pname, param); + gl->fSamplerParameterfv(sampler->mGLName, pname, param); } } // namespace mozilla diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp index 3d40016a64..8a67cfcce3 100644 --- a/dom/canvas/WebGLContextUtils.cpp +++ b/dom/canvas/WebGLContextUtils.cpp @@ -1052,15 +1052,15 @@ WebGLContext::AssertCachedBindings() // Bound object state if (IsWebGL2()) { - GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName() + GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, bound); - bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->GLName() : 0; + bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, bound); } else { MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer); - GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->GLName() + GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound); } @@ -1073,20 +1073,20 @@ WebGLContext::AssertCachedBindings() AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture); WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D); - bound = curTex ? curTex->GLName() : 0; + bound = curTex ? curTex->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound); curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP); - bound = curTex ? curTex->GLName() : 0; + bound = curTex ? curTex->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound); // Buffers - bound = mBoundArrayBuffer ? mBoundArrayBuffer->GLName() : 0; + bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound); MOZ_ASSERT(mBoundVertexArray); WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer; - bound = curBuff ? curBuff->GLName() : 0; + bound = curBuff ? curBuff->mGLName : 0; AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound); MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors()); diff --git a/dom/canvas/WebGLContextVertexArray.cpp b/dom/canvas/WebGLContextVertexArray.cpp index 5e90abf754..a4d5b6cb89 100644 --- a/dom/canvas/WebGLContextVertexArray.cpp +++ b/dom/canvas/WebGLContextVertexArray.cpp @@ -51,7 +51,7 @@ WebGLContext::CreateVertexArray() if (IsContextLost()) return nullptr; - nsRefPtr globj = WebGLVertexArray::Create(this); + nsRefPtr globj = CreateVertexArrayImpl(); MakeContextCurrent(); globj->GenVertexArray(); @@ -59,6 +59,12 @@ WebGLContext::CreateVertexArray() return globj.forget(); } +WebGLVertexArray* +WebGLContext::CreateVertexArrayImpl() +{ + return WebGLVertexArray::Create(this); +} + void WebGLContext::DeleteVertexArray(WebGLVertexArray* array) { @@ -86,9 +92,14 @@ WebGLContext::IsVertexArray(WebGLVertexArray* array) if (!array) return false; - return ValidateObjectAllowDeleted("isVertexArray", array) && - !array->IsDeleted() && - array->HasEverBeenBound(); + if (!ValidateObjectAllowDeleted("isVertexArray", array)) + return false; + + if (array->IsDeleted()) + return false; + + MakeContextCurrent(); + return array->IsVertexArray(); } } // namespace mozilla diff --git a/dom/canvas/WebGLFramebuffer.cpp b/dom/canvas/WebGLFramebuffer.cpp index 02e0c27d07..c51bd14ccb 100644 --- a/dom/canvas/WebGLFramebuffer.cpp +++ b/dom/canvas/WebGLFramebuffer.cpp @@ -378,7 +378,7 @@ WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl, const GLenum imageTarget = ImageTarget().get(); const GLint mipLevel = MipLevel(); - const GLuint glName = Texture()->GLName(); + const GLuint glName = Texture()->mGLName; if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, @@ -404,14 +404,18 @@ WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl, // WebGLFramebuffer WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo) - : WebGLBindableName(fbo) - , WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) + , mGLName(fbo) , mStatus(0) , mReadBufferMode(LOCAL_GL_COLOR_ATTACHMENT0) , mColorAttachment0(this, LOCAL_GL_COLOR_ATTACHMENT0) , mDepthAttachment(this, LOCAL_GL_DEPTH_ATTACHMENT) , mStencilAttachment(this, LOCAL_GL_STENCIL_ATTACHMENT) , mDepthStencilAttachment(this, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) +#ifdef ANDROID + , mIsFB(false) +#endif + { mContext->mFramebuffers.insertBack(this); } @@ -432,6 +436,10 @@ WebGLFramebuffer::Delete() mContext->MakeContextCurrent(); mContext->gl->fDeleteFramebuffers(1, &mGLName); LinkedListElement::removeFrom(mContext->mFramebuffers); + +#ifdef ANDROID + mIsFB = false; +#endif } void diff --git a/dom/canvas/WebGLFramebuffer.h b/dom/canvas/WebGLFramebuffer.h index 2ec52fde17..7e901c06d4 100644 --- a/dom/canvas/WebGLFramebuffer.h +++ b/dom/canvas/WebGLFramebuffer.h @@ -8,7 +8,6 @@ #include "mozilla/LinkedList.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLObjectModel.h" #include "WebGLStrongTypes.h" @@ -23,12 +22,13 @@ namespace gl { class WebGLFramebuffer final : public nsWrapperCache - , public WebGLBindableName , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject , public SupportsWeakPtr { + friend class WebGLContext; + public: MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer) @@ -53,7 +53,6 @@ public: } bool IsDefined() const; - bool IsDeleteRequested() const; TexInternalFormat EffectiveInternalFormat() const; @@ -99,6 +98,8 @@ public: FBAttachment attachmentLoc) const; }; + const GLuint mGLName; + private: mutable GLenum mStatus; @@ -111,6 +112,15 @@ private: AttachPoint mDepthStencilAttachment; nsTArray mMoreColorAttachments; +#ifdef ANDROID + // Bug 1140459: Some drivers (including our test slaves!) don't + // give reasonable answers for IsRenderbuffer, maybe others. + // This shows up on Android 2.3 emulator. + // + // So we track the `is a Framebuffer` state ourselves. + bool mIsFB; +#endif + public: WebGLFramebuffer(WebGLContext* webgl, GLuint fbo); diff --git a/dom/canvas/WebGLRenderbuffer.cpp b/dom/canvas/WebGLRenderbuffer.cpp index 9919aa15ed..d9583dcd57 100644 --- a/dom/canvas/WebGLRenderbuffer.cpp +++ b/dom/canvas/WebGLRenderbuffer.cpp @@ -47,14 +47,16 @@ WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle aGivenProto) } WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl) - : WebGLBindable() - , WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) , mPrimaryRB(0) , mSecondaryRB(0) , mInternalFormat(0) , mInternalFormatForGL(0) , mImageDataStatus(WebGLImageDataStatus::NoImageData) , mSamples(1) +#ifdef ANDROID + , mIsRB(false) +#endif { mContext->MakeContextCurrent(); @@ -75,6 +77,9 @@ WebGLRenderbuffer::Delete() mContext->gl->fDeleteRenderbuffers(1, &mSecondaryRB); LinkedListElement::removeFrom(mContext->mRenderbuffers); +#ifdef ANDROID + mIsRB = false; +#endif } int64_t diff --git a/dom/canvas/WebGLRenderbuffer.h b/dom/canvas/WebGLRenderbuffer.h index e10dd77437..440dfdba55 100644 --- a/dom/canvas/WebGLRenderbuffer.h +++ b/dom/canvas/WebGLRenderbuffer.h @@ -8,7 +8,6 @@ #include "mozilla/LinkedList.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLFramebufferAttachable.h" #include "WebGLObjectModel.h" @@ -16,7 +15,6 @@ namespace mozilla { class WebGLRenderbuffer final : public nsWrapperCache - , public WebGLBindable , public WebGLRefCountedObject , public LinkedListElement , public WebGLRectangleObject @@ -41,6 +39,8 @@ public: GLsizei Samples() const { return mSamples; } void SetSamples(GLsizei samples) { mSamples = samples; } + GLuint PrimaryGLName() const { return mPrimaryRB; } + GLenum InternalFormat() const { return mInternalFormat; } void SetInternalFormat(GLenum internalFormat) { mInternalFormat = internalFormat; @@ -80,7 +80,16 @@ protected: GLenum mInternalFormatForGL; WebGLImageDataStatus mImageDataStatus; GLsizei mSamples; +#ifdef ANDROID + // Bug 1140459: Some drivers (including our test slaves!) don't + // give reasonable answers for IsRenderbuffer, maybe others. + // This shows up on Android 2.3 emulator. + // + // So we track the `is a Renderbuffer` state ourselves. + bool mIsRB; +#endif + friend class WebGLContext; friend class WebGLFramebuffer; }; diff --git a/dom/canvas/WebGLSampler.cpp b/dom/canvas/WebGLSampler.cpp index 8d8cc7be50..8f91968586 100644 --- a/dom/canvas/WebGLSampler.cpp +++ b/dom/canvas/WebGLSampler.cpp @@ -12,8 +12,8 @@ namespace mozilla { WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler) - : WebGLBindableName(sampler), - WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) + , mGLName(sampler) { mContext->mSamplers.insertBack(this); } diff --git a/dom/canvas/WebGLSampler.h b/dom/canvas/WebGLSampler.h index ba2ef77c9b..8ab1387c9b 100644 --- a/dom/canvas/WebGLSampler.h +++ b/dom/canvas/WebGLSampler.h @@ -8,14 +8,12 @@ #include "mozilla/LinkedList.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLObjectModel.h" namespace mozilla { class WebGLSampler final : public nsWrapperCache - , public WebGLBindableName , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject @@ -25,6 +23,8 @@ class WebGLSampler final public: explicit WebGLSampler(WebGLContext* webgl, GLuint sampler); + const GLuint mGLName; + void Delete(); WebGLContext* GetParentObject() const; diff --git a/dom/canvas/WebGLTexture.cpp b/dom/canvas/WebGLTexture.cpp index 8baf14554d..8162f0287a 100644 --- a/dom/canvas/WebGLTexture.cpp +++ b/dom/canvas/WebGLTexture.cpp @@ -23,8 +23,9 @@ WebGLTexture::WrapObject(JSContext* cx, JS::Handle aGivenProto) { } WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex) - : WebGLBindableName(tex) - , WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) + , mGLName(tex) + , mTarget(LOCAL_GL_NONE) , mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR) , mMagFilter(LOCAL_GL_LINEAR) , mWrapS(LOCAL_GL_REPEAT) @@ -141,7 +142,7 @@ WebGLTexture::Bind(TexTarget texTarget) bool firstTimeThisTextureIsBound = !HasEverBeenBound(); if (firstTimeThisTextureIsBound) { - BindTo(texTarget); + mTarget = texTarget.get(); } else if (texTarget != Target()) { mContext->ErrorInvalidOperation("bindTexture: This texture has already" " been bound to a different target."); @@ -151,9 +152,7 @@ WebGLTexture::Bind(TexTarget texTarget) return; } - GLuint name = GLName(); - - mContext->gl->fBindTexture(texTarget.get(), name); + mContext->gl->fBindTexture(texTarget.get(), mGLName); if (firstTimeThisTextureIsBound) { mFacesCount = (texTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? 6 : 1; @@ -228,7 +227,7 @@ WebGLTexture::SetCustomMipmap() imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1); imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1); imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1); - for(size_t face = 0; face < mFacesCount; ++face) { + for (size_t face = 0; face < mFacesCount; ++face) { ImageInfoAtFace(face, level) = imageInfo; } } @@ -275,8 +274,8 @@ WebGLTexture::IsMipmapCubeComplete() const return false; for (int i = 0; i < 6; i++) { - const TexImageTarget face = TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP, - i); + const TexImageTarget face = + TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP, i); if (!DoesMipmapHaveAllLevelsConsistentlyDefined(face)) return false; } @@ -625,7 +624,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, // Try to clear with glClear. if (imageTarget == LOCAL_GL_TEXTURE_2D) { - bool cleared = ClearWithTempFB(mContext, GLName(), imageTarget, level, + bool cleared = ClearWithTempFB(mContext, mGLName, imageTarget, level, imageInfo.mEffectiveInternalFormat, imageInfo.mHeight, imageInfo.mWidth); if (cleared) { @@ -636,7 +635,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, } // That didn't work. Try uploading zeros then. - gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get()); + gl::ScopedBindTexture autoBindTex(mContext->gl, mGLName, mTarget); size_t bitspertexel = GetBitsPerTexel(imageInfo.mEffectiveInternalFormat); MOZ_ASSERT((bitspertexel % 8) == 0); // That would only happen for diff --git a/dom/canvas/WebGLTexture.h b/dom/canvas/WebGLTexture.h index b253e5058d..5545fdaadb 100644 --- a/dom/canvas/WebGLTexture.h +++ b/dom/canvas/WebGLTexture.h @@ -12,7 +12,6 @@ #include "mozilla/LinkedList.h" #include "nsAlgorithm.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLFramebufferAttachable.h" #include "WebGLObjectModel.h" #include "WebGLStrongTypes.h" @@ -31,7 +30,6 @@ IsPOTAssumingNonnegative(GLsizei x) // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter. class WebGLTexture final : public nsWrapperCache - , public WebGLBindableName , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject @@ -42,6 +40,9 @@ public: void Delete(); + bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; } + GLenum Target() const { return mTarget; } + WebGLContext* GetParentObject() const { return Context(); } @@ -62,6 +63,12 @@ protected: // We store information about the various images that are part of this // texture. (cubemap faces, mipmap levels) +public: + const GLuint mGLName; + +protected: + GLenum mTarget; + public: class ImageInfo : public WebGLRectangleObject diff --git a/dom/canvas/WebGLTransformFeedback.cpp b/dom/canvas/WebGLTransformFeedback.cpp index b4dc42054a..8aabc47a2d 100644 --- a/dom/canvas/WebGLTransformFeedback.cpp +++ b/dom/canvas/WebGLTransformFeedback.cpp @@ -13,8 +13,8 @@ namespace mozilla { WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl, GLuint tf) - : WebGLBindableName(tf) - , WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) + , mGLName(tf) , mMode(LOCAL_GL_NONE) , mIsActive(false) , mIsPaused(false) diff --git a/dom/canvas/WebGLTransformFeedback.h b/dom/canvas/WebGLTransformFeedback.h index 09e7f6e301..d373e49292 100644 --- a/dom/canvas/WebGLTransformFeedback.h +++ b/dom/canvas/WebGLTransformFeedback.h @@ -8,14 +8,12 @@ #include "mozilla/LinkedList.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLObjectModel.h" namespace mozilla { class WebGLTransformFeedback final : public nsWrapperCache - , public WebGLBindableName , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject @@ -30,11 +28,14 @@ public: WebGLContext* GetParentObject() const; virtual JSObject* WrapObject(JSContext* cx, JS::Handle aGivenProto) override; + const GLuint mGLName; + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback) private: ~WebGLTransformFeedback(); + GLenum mMode; bool mIsActive; bool mIsPaused; diff --git a/dom/canvas/WebGLVertexArray.cpp b/dom/canvas/WebGLVertexArray.cpp index 84e7dc9d8f..4776322142 100644 --- a/dom/canvas/WebGLVertexArray.cpp +++ b/dom/canvas/WebGLVertexArray.cpp @@ -21,8 +21,7 @@ WebGLVertexArray::WrapObject(JSContext* cx, JS::Handle aGivenProto) } WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl) - : WebGLBindable() - , WebGLContextBoundObject(webgl) + : WebGLContextBoundObject(webgl) , mGLName(0) { mContext->mVertexArrays.insertBack(this); @@ -50,6 +49,12 @@ WebGLVertexArray::Delete() mAttribs.Clear(); } +bool +WebGLVertexArray::IsVertexArray() +{ + return IsVertexArrayImpl(); +} + void WebGLVertexArray::EnsureAttrib(GLuint index) { diff --git a/dom/canvas/WebGLVertexArray.h b/dom/canvas/WebGLVertexArray.h index 10c14a99c6..332fc59818 100644 --- a/dom/canvas/WebGLVertexArray.h +++ b/dom/canvas/WebGLVertexArray.h @@ -8,7 +8,6 @@ #include "mozilla/LinkedList.h" #include "nsWrapperCache.h" -#include "WebGLBindableName.h" #include "WebGLBuffer.h" #include "WebGLObjectModel.h" #include "WebGLStrongTypes.h" @@ -20,7 +19,6 @@ class WebGLVertexArrayFake; class WebGLVertexArray : public nsWrapperCache - , public WebGLBindable , public WebGLRefCountedObject , public LinkedListElement , public WebGLContextBoundObject @@ -31,14 +29,9 @@ public: void BindVertexArray() { // Bind to dummy value to signal that this vertex array has ever been // bound. - BindTo(LOCAL_GL_VERTEX_ARRAY_BINDING); BindVertexArrayImpl(); }; - virtual void GenVertexArray() = 0; - virtual void BindVertexArrayImpl() = 0; - virtual void DeleteImpl() = 0; - void EnsureAttrib(GLuint index); bool HasAttrib(GLuint index) const { return index < mAttribs.Length(); @@ -49,6 +42,7 @@ public: // Implement parent classes: void Delete(); + bool IsVertexArray(); WebGLContext* GetParentObject() const { return Context(); @@ -68,6 +62,11 @@ protected: MOZ_ASSERT(IsDeleted()); } + virtual void GenVertexArray() = 0; + virtual void BindVertexArrayImpl() = 0; + virtual void DeleteImpl() = 0; + virtual bool IsVertexArrayImpl() = 0; + GLuint mGLName; nsTArray mAttribs; WebGLRefPtr mElementArrayBuffer; diff --git a/dom/canvas/WebGLVertexArrayFake.cpp b/dom/canvas/WebGLVertexArrayFake.cpp index b12f99687d..e5e5909687 100644 --- a/dom/canvas/WebGLVertexArrayFake.cpp +++ b/dom/canvas/WebGLVertexArrayFake.cpp @@ -10,6 +10,11 @@ namespace mozilla { +WebGLVertexArrayFake::WebGLVertexArrayFake(WebGLContext* webgl) + : WebGLVertexArray(webgl) + , mIsVAO(false) +{ } + void WebGLVertexArrayFake::BindVertexArrayImpl() { @@ -52,6 +57,19 @@ WebGLVertexArrayFake::BindVertexArrayImpl() } mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer); + mIsVAO = true; +} + +void +WebGLVertexArrayFake::DeleteImpl() +{ + mIsVAO = false; +} + +bool +WebGLVertexArrayFake::IsVertexArrayImpl() +{ + return mIsVAO; } } // namespace mozilla diff --git a/dom/canvas/WebGLVertexArrayFake.h b/dom/canvas/WebGLVertexArrayFake.h index 365c487557..6f970c9657 100644 --- a/dom/canvas/WebGLVertexArrayFake.h +++ b/dom/canvas/WebGLVertexArrayFake.h @@ -13,21 +13,22 @@ namespace mozilla { class WebGLVertexArrayFake final : public WebGLVertexArray { -public: + friend class WebGLVertexArray; + +protected: virtual void BindVertexArrayImpl() override; - virtual void DeleteImpl() override {}; + virtual void DeleteImpl() override; virtual void GenVertexArray() override {}; + virtual bool IsVertexArrayImpl() override; private: - explicit WebGLVertexArrayFake(WebGLContext* webgl) - : WebGLVertexArray(webgl) - { } + explicit WebGLVertexArrayFake(WebGLContext* webgl); ~WebGLVertexArrayFake() { DeleteOnce(); } - friend class WebGLVertexArray; + bool mIsVAO; }; } // namespace mozilla diff --git a/dom/canvas/WebGLVertexArrayGL.cpp b/dom/canvas/WebGLVertexArrayGL.cpp index 06d1f76c17..e88c2a4b91 100644 --- a/dom/canvas/WebGLVertexArrayGL.cpp +++ b/dom/canvas/WebGLVertexArrayGL.cpp @@ -10,6 +10,18 @@ namespace mozilla { +WebGLVertexArrayGL::WebGLVertexArrayGL(WebGLContext* webgl) + : WebGLVertexArray(webgl) +#if defined(XP_LINUX) + , mIsVAO(false) +#endif +{ } + +WebGLVertexArrayGL::~WebGLVertexArrayGL() +{ + DeleteOnce(); +} + void WebGLVertexArrayGL::DeleteImpl() { @@ -17,14 +29,21 @@ WebGLVertexArrayGL::DeleteImpl() mContext->MakeContextCurrent(); mContext->gl->fDeleteVertexArrays(1, &mGLName); + +#if defined(XP_LINUX) + mIsVAO = false; +#endif } void WebGLVertexArrayGL::BindVertexArrayImpl() { mContext->mBoundVertexArray = this; - mContext->gl->fBindVertexArray(mGLName); + +#if defined(XP_LINUX) + mIsVAO = true; +#endif } void @@ -33,4 +52,21 @@ WebGLVertexArrayGL::GenVertexArray() mContext->gl->fGenVertexArrays(1, &mGLName); } +bool +WebGLVertexArrayGL::IsVertexArrayImpl() +{ +#if defined(XP_LINUX) + gl::GLContext* gl = mContext->gl; + if (gl->WorkAroundDriverBugs() && + gl->Vendor() == gl::GLVendor::VMware && + gl->Renderer() == gl::GLRenderer::GalliumLlvmpipe) + { + return mIsVAO; + } +#endif + + mContext->MakeContextCurrent(); + return mContext->gl->fIsVertexArray(mGLName) != 0; +} + } // namespace mozilla diff --git a/dom/canvas/WebGLVertexArrayGL.h b/dom/canvas/WebGLVertexArrayGL.h index 84993461a6..4923804347 100644 --- a/dom/canvas/WebGLVertexArrayGL.h +++ b/dom/canvas/WebGLVertexArrayGL.h @@ -10,24 +10,28 @@ namespace mozilla { -class WebGLVertexArrayGL final +class WebGLVertexArrayGL : public WebGLVertexArray { + friend class WebGLVertexArray; + public: virtual void DeleteImpl() override; virtual void BindVertexArrayImpl() override; virtual void GenVertexArray() override; + virtual bool IsVertexArrayImpl() override; -private: - explicit WebGLVertexArrayGL(WebGLContext* webgl) - : WebGLVertexArray(webgl) - { } +protected: + explicit WebGLVertexArrayGL(WebGLContext* webgl); + ~WebGLVertexArrayGL(); - ~WebGLVertexArrayGL() { - DeleteOnce(); - } - - friend class WebGLVertexArray; +#if defined(XP_LINUX) + // Bug 1140459: Some drivers (including our test slaves!) don't + // give reasonable answers for IsRenderbuffer, maybe others. + // + // So we track the `is a VAO` state ourselves. + bool mIsVAO; +#endif }; } // namespace mozilla diff --git a/dom/canvas/WebGLVertexArrayObject.cpp b/dom/canvas/WebGLVertexArrayObject.cpp new file mode 100644 index 0000000000..71ec32e50b --- /dev/null +++ b/dom/canvas/WebGLVertexArrayObject.cpp @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLVertexArrayObject.h" + +#include "mozilla/dom/WebGL2RenderingContextBinding.h" + +namespace mozilla { +namespace dom { + +WebGLVertexArray* +WebGLVertexArrayObject::Create(WebGLContext* webgl) +{ + // WebGL 2: This is core in GL ES 3. If support is missing something + // is very wrong. + bool vaoSupport = webgl->GL()->IsSupported(gl::GLFeature::vertex_array_object); + MOZ_RELEASE_ASSERT(vaoSupport, "Vertex Array Objects aren't supported."); + if (vaoSupport) + return new WebGLVertexArrayObject(webgl); + + return nullptr; +} + +JSObject* +WebGLVertexArrayObject::WrapObject(JSContext* cx, + JS::Handle givenProto) +{ + return dom::WebGLVertexArrayObjectBinding::Wrap(cx, this, givenProto); +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/canvas/WebGLVertexArrayObject.h b/dom/canvas/WebGLVertexArrayObject.h new file mode 100644 index 0000000000..a58bff9ebb --- /dev/null +++ b/dom/canvas/WebGLVertexArrayObject.h @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef mozilla_dom_WebGLVertexArrayObject_h +#define mozilla_dom_WebGLVertexArrayObject_h + +#include "WebGLVertexArrayGL.h" + +namespace mozilla { +namespace dom { + +/** + * This class implements the DOM bindings for WebGL 2 VAO. + * + * This exists to so the object returned from gl.createVertexArray() + * is an instance of WebGLVertexArrayObject (to match the WebGL 2 + * spec.) + */ +class WebGLVertexArrayObject final + : public WebGLVertexArrayGL +{ +public: + static WebGLVertexArray* Create(WebGLContext* webgl); + + virtual JSObject* WrapObject(JSContext* cx, JS::Handle givenProto) override; + +private: + explicit WebGLVertexArrayObject(WebGLContext* webgl) + : WebGLVertexArrayGL(webgl) + { } + + ~WebGLVertexArrayObject() { + DeleteOnce(); + } +}; + +} // namespace dom +} // namespace mozilla + +#endif // !mozilla_dom_WebGLVertexArrayObject_h diff --git a/dom/canvas/moz.build b/dom/canvas/moz.build index 75c9ae641b..84ffa64e2d 100644 --- a/dom/canvas/moz.build +++ b/dom/canvas/moz.build @@ -33,6 +33,7 @@ EXPORTS.mozilla.dom += [ 'CanvasUtils.h', 'ImageData.h', 'TextMetrics.h', + 'WebGLVertexArrayObject.h', ] # http://support.microsoft.com/kb/143208 @@ -128,6 +129,7 @@ UNIFIED_SOURCES += [ 'WebGLVertexArray.cpp', 'WebGLVertexArrayFake.cpp', 'WebGLVertexArrayGL.cpp', + 'WebGLVertexArrayObject.cpp', ] LOCAL_INCLUDES += [ '/js/xpconnect/wrappers', diff --git a/dom/datastore/DataStoreService.cpp b/dom/datastore/DataStoreService.cpp index 7a37c38690..e675d9664e 100644 --- a/dom/datastore/DataStoreService.cpp +++ b/dom/datastore/DataStoreService.cpp @@ -1325,7 +1325,7 @@ DataStoreService::CreateFirstRevisionId(uint32_t aAppId, new FirstRevisionIdCallback(aAppId, aName, aManifestURL); Sequence dbs; - if (!dbs.AppendElement(NS_LITERAL_STRING(DATASTOREDB_REVISION))) { + if (!dbs.AppendElement(NS_LITERAL_STRING(DATASTOREDB_REVISION), fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index e0938a4ad7..24981a2f29 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1872,7 +1872,7 @@ HTMLInputElement::SetValue(const nsAString& aValue, ErrorResult& aRv) return; } Sequence list; - if (!list.AppendElement(aValue)) { + if (!list.AppendElement(aValue, fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } @@ -2462,7 +2462,7 @@ HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames, uint32_t aLen Sequence list; for (uint32_t i = 0; i < aLength; ++i) { - if (!list.AppendElement(nsDependentString(aFileNames[i]))) { + if (!list.AppendElement(nsDependentString(aFileNames[i]), fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } @@ -2515,7 +2515,7 @@ HTMLInputElement::SetUserInput(const nsAString& aValue) if (mType == NS_FORM_INPUT_FILE) { Sequence list; - if (!list.AppendElement(aValue)) { + if (!list.AppendElement(aValue, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 6817aabf1f..7fa92cbce8 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -8500,7 +8500,7 @@ ConvertBlobsToActors(PBackgroundParent* aBackgroundActor, return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - MOZ_ALWAYS_TRUE(aActors.AppendElement(actor)); + MOZ_ALWAYS_TRUE(aActors.AppendElement(actor, fallible)); if (collectFileInfos) { nsRefPtr fileInfo = file.mFileInfo; @@ -8508,7 +8508,7 @@ ConvertBlobsToActors(PBackgroundParent* aBackgroundActor, // Transfer a reference to the receiver. auto transferedFileInfo = reinterpret_cast(fileInfo.forget().take()); - MOZ_ALWAYS_TRUE(aFileInfos.AppendElement(transferedFileInfo)); + MOZ_ALWAYS_TRUE(aFileInfos.AppendElement(transferedFileInfo, fallible)); } } @@ -12359,7 +12359,7 @@ Database::Invalidate() auto* array = static_cast>*>(aUserData); - if (NS_WARN_IF(!array->AppendElement(aEntry->GetKey()))) { + if (NS_WARN_IF(!array->AppendElement(aEntry->GetKey(), fallible))) { return PL_DHASH_STOP; } @@ -12626,7 +12626,7 @@ Database::AllocPBackgroundIDBTransactionParent( if (closure->mName == aValue->mCommonMetadata.name() && !aValue->mDeleted) { - MOZ_ALWAYS_TRUE(closure->mObjectStores.AppendElement(aValue)); + MOZ_ALWAYS_TRUE(closure->mObjectStores.AppendElement(aValue, fallible)); return PL_DHASH_STOP; } @@ -18566,7 +18566,7 @@ FactoryOp::SendVersionChangeMessages(DatabaseActorInfo* aDatabaseActorInfo, Database* database = aDatabaseActorInfo->mLiveDatabases[index]; if ((!aOpeningDatabase || database != aOpeningDatabase) && !database->IsClosed() && - NS_WARN_IF(!maybeBlockedDatabases.AppendElement(database))) { + NS_WARN_IF(!maybeBlockedDatabases.AppendElement(database, fallible))) { return NS_ERROR_OUT_OF_MEMORY; } } @@ -22848,7 +22848,7 @@ ObjectStoreAddOrPutRequestOp::Init(TransactionBase* aTransaction) TPBackgroundIDBDatabaseFileParent || fileOrFileId.type() == DatabaseFileOrMutableFileId::Tint64_t); - StoredFileInfo* storedFileInfo = mStoredFileInfos.AppendElement(); + StoredFileInfo* storedFileInfo = mStoredFileInfos.AppendElement(fallible); MOZ_ASSERT(storedFileInfo); switch (fileOrFileId.type()) { @@ -23413,7 +23413,7 @@ ObjectStoreGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection) bool hasResult; while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { - StructuredCloneReadInfo* cloneInfo = mResponse.AppendElement(); + StructuredCloneReadInfo* cloneInfo = mResponse.AppendElement(fallible); if (NS_WARN_IF(!cloneInfo)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -23540,7 +23540,7 @@ ObjectStoreGetAllKeysRequestOp::DoDatabaseWork(DatabaseConnection* aConnection) bool hasResult; while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { - Key* key = mResponse.AppendElement(); + Key* key = mResponse.AppendElement(fallible); if (NS_WARN_IF(!key)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -23962,7 +23962,7 @@ IndexGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection) bool hasResult; while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { - StructuredCloneReadInfo* cloneInfo = mResponse.AppendElement(); + StructuredCloneReadInfo* cloneInfo = mResponse.AppendElement(fallible); if (NS_WARN_IF(!cloneInfo)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -24154,7 +24154,7 @@ IndexGetKeyRequestOp::DoDatabaseWork(DatabaseConnection* aConnection) bool hasResult; while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { - Key* key = mResponse.AppendElement(); + Key* key = mResponse.AppendElement(fallible); if (NS_WARN_IF(!key)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 64a834d416..d7c265956b 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -1245,14 +1245,17 @@ IDBObjectStore::AddOrPut(JSContext* aCx, return nullptr; } - MOZ_ALWAYS_TRUE(fileActorOrMutableFileIds.AppendElement(fileActor)); + MOZ_ALWAYS_TRUE(fileActorOrMutableFileIds.AppendElement(fileActor, + fallible)); } else { const int64_t fileId = blobOrFileInfo.mFileInfo->Id(); MOZ_ASSERT(fileId > 0); - MOZ_ALWAYS_TRUE(fileActorOrMutableFileIds.AppendElement(fileId)); + MOZ_ALWAYS_TRUE(fileActorOrMutableFileIds.AppendElement(fileId, + fallible)); - nsRefPtr* newFileInfo = fileInfosToKeepAlive.AppendElement(); + nsRefPtr* newFileInfo = + fileInfosToKeepAlive.AppendElement(fallible); if (NS_WARN_IF(!newFileInfo)) { aRv = NS_ERROR_OUT_OF_MEMORY; return nullptr; diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp index bd011d61f9..1dabddc4e7 100644 --- a/dom/media/MediaData.cpp +++ b/dom/media/MediaData.cpp @@ -612,9 +612,11 @@ MediaRawDataWriter::Prepend(const uint8_t* aData, size_t aSize) if (!EnsureSize(aSize + mTarget->mSize)) { return false; } + // Shift the data to the right by aSize to leave room for the new data. memmove(mTarget->mData + aSize, mTarget->mData, mTarget->mSize); memcpy(mTarget->mData, aData, aSize); + mTarget->mSize += aSize; return true; } diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h index 3e9b80e6e4..fed5415584 100644 --- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -420,8 +420,6 @@ private: // It is designed to share potentially big byte arrays. class MediaLargeByteBuffer : public FallibleTArray { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaLargeByteBuffer); - MediaLargeByteBuffer() = default; - explicit MediaLargeByteBuffer(size_t aCapacity) : FallibleTArray(aCapacity) {} private: ~MediaLargeByteBuffer() {} diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 5288f41506..92a3ce1840 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -661,6 +661,10 @@ MediaDecoderStateMachine::NeedToDecodeVideo() { MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); + SAMPLE_LOG("NeedToDecodeVideo() isDec=%d decToTar=%d minPrl=%d seek=%d enufVid=%d", + IsVideoDecoding(), mDecodeToSeekTarget, mMinimizePreroll, + mState == DECODER_STATE_SEEKING, + HaveEnoughDecodedVideo()); return IsVideoDecoding() && ((mState == DECODER_STATE_SEEKING && mDecodeToSeekTarget) || (mState == DECODER_STATE_DECODING_FIRSTFRAME && diff --git a/dom/media/VideoFrameContainer.cpp b/dom/media/VideoFrameContainer.cpp index 20cb12de11..2b53924fd2 100644 --- a/dom/media/VideoFrameContainer.cpp +++ b/dom/media/VideoFrameContainer.cpp @@ -65,17 +65,7 @@ void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, mPaintTarget = aTargetTime; } -void VideoFrameContainer::Reset() -{ - ClearCurrentFrame(true); - Invalidate(); - mIntrinsicSize = gfxIntSize(-1, -1); - mPaintDelay = mozilla::TimeDuration(); - mPaintTarget = mozilla::TimeStamp(); - mImageContainer->ResetPaintCount(); -} - -void VideoFrameContainer::ClearCurrentFrame(bool aResetSize) +void VideoFrameContainer::ClearCurrentFrame() { MutexAutoLock lock(mMutex); @@ -86,7 +76,7 @@ void VideoFrameContainer::ClearCurrentFrame(bool aResetSize) mImageContainer->UnlockCurrentImage(); mImageContainer->ClearAllImages(); - mImageSizeChanged = aResetSize; + mImageSizeChanged = false; } ImageContainer* VideoFrameContainer::GetImageContainer() { diff --git a/dom/media/VideoFrameContainer.h b/dom/media/VideoFrameContainer.h index eca09d0849..ef5f0297cc 100644 --- a/dom/media/VideoFrameContainer.h +++ b/dom/media/VideoFrameContainer.h @@ -48,9 +48,7 @@ public: // Call on any thread void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage, TimeStamp aTargetTime); - void ClearCurrentFrame(bool aResetSize = false); - // Reset the VideoFrameContainer - void Reset(); + void ClearCurrentFrame(); // Time in seconds by which the last painted video frame was late by. // E.g. if the last painted frame should have been painted at time t, // but was actually painted at t+n, this returns n in seconds. Threadsafe. diff --git a/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html b/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html index 7e2d5e4f04..f6192074a5 100644 --- a/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html +++ b/dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html @@ -22,9 +22,9 @@ runWithMSE(function (ms, v) { var target = 2; - v.addEventListener("canplay", function oncanplay() { - v.removeEventListener("canplay", oncanplay); - ok(v.readyState >= v.HAVE_FUTURE_DATA, "readyState is >= FUTURE_DATA"); + v.addEventListener("loadeddata", function onloadeddata() { + v.removeEventListener("loadeddata", onloadeddata); + ok(v.readyState >= v.HAVE_CURRENT_DATA, "readyState is >= CURRENT_DATA"); v.currentTime = target; }); diff --git a/dom/media/webaudio/AudioNodeEngine.h b/dom/media/webaudio/AudioNodeEngine.h index 8202837db3..7b8d84a2cc 100644 --- a/dom/media/webaudio/AudioNodeEngine.h +++ b/dom/media/webaudio/AudioNodeEngine.h @@ -110,7 +110,7 @@ public: } private: - AutoFallibleTArray mContents; + nsAutoTArray mContents; }; /** diff --git a/dom/mobilemessage/ipc/SmsChild.cpp b/dom/mobilemessage/ipc/SmsChild.cpp index c106b81d97..0de97607c9 100644 --- a/dom/mobilemessage/ipc/SmsChild.cpp +++ b/dom/mobilemessage/ipc/SmsChild.cpp @@ -349,8 +349,8 @@ MobileMessageCursorChild::DoNotifyResult(const nsTArray& aDat for (uint32_t i = 0; i < length; i++) { nsCOMPtr message = CreateMessageFromMessageData(aDataArray[i]); - NS_ENSURE_TRUE_VOID(messages.AppendElement(message)); - NS_ENSURE_TRUE_VOID(autoArray.AppendElement(message.get())); + NS_ENSURE_TRUE_VOID(messages.AppendElement(message, fallible)); + NS_ENSURE_TRUE_VOID(autoArray.AppendElement(message.get(), fallible)); } mCursorCallback->NotifyCursorResult(autoArray.Elements(), length); @@ -370,8 +370,8 @@ MobileMessageCursorChild::DoNotifyResult(const nsTArray& aDataArray) for (uint32_t i = 0; i < length; i++) { nsCOMPtr thread = new MobileMessageThread(aDataArray[i]); - NS_ENSURE_TRUE_VOID(threads.AppendElement(thread)); - NS_ENSURE_TRUE_VOID(autoArray.AppendElement(thread.get())); + NS_ENSURE_TRUE_VOID(threads.AppendElement(thread, fallible)); + NS_ENSURE_TRUE_VOID(autoArray.AppendElement(thread.get(), fallible)); } mCursorCallback->NotifyCursorResult(autoArray.Elements(), length); diff --git a/dom/network/TCPSocketChild.cpp b/dom/network/TCPSocketChild.cpp index 4668120ccd..b4fa4d26d8 100644 --- a/dom/network/TCPSocketChild.cpp +++ b/dom/network/TCPSocketChild.cpp @@ -237,7 +237,8 @@ TCPSocketChild::SendSend(JS::Handle aData, if (!data) { return NS_ERROR_OUT_OF_MEMORY; } - if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes)) { + if (!fallibleArr.InsertElementsAt(0, data + aByteOffset, nbytes, + fallible)) { return NS_ERROR_OUT_OF_MEMORY; } } diff --git a/dom/network/TCPSocketParent.cpp b/dom/network/TCPSocketParent.cpp index 80d55f39a1..d3cf7a5a24 100644 --- a/dom/network/TCPSocketParent.cpp +++ b/dom/network/TCPSocketParent.cpp @@ -311,7 +311,7 @@ TCPSocketParent::SendEvent(const nsAString& aType, JS::Handle aDataVa errLine = __LINE__; break; } - if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) { + if (!fallibleArr.InsertElementsAt(0, buffer, nbytes, fallible)) { errLine = __LINE__; break; } diff --git a/dom/network/UDPSocketChild.cpp b/dom/network/UDPSocketChild.cpp index 1249ecce23..03c01aae87 100644 --- a/dom/network/UDPSocketChild.cpp +++ b/dom/network/UDPSocketChild.cpp @@ -251,7 +251,7 @@ UDPSocketChild::SendDataInternal(const UDPSocketAddr& aAddr, NS_ENSURE_ARG(aData); FallibleTArray fallibleArray; - if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) { + if (!fallibleArray.InsertElementsAt(0, aData, aByteLength, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/network/UDPSocketParent.cpp b/dom/network/UDPSocketParent.cpp index adee8f2984..3741972aac 100644 --- a/dom/network/UDPSocketParent.cpp +++ b/dom/network/UDPSocketParent.cpp @@ -459,7 +459,7 @@ UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage } FallibleTArray fallibleArray; - if (!fallibleArray.InsertElementsAt(0, buffer, len)) { + if (!fallibleArray.InsertElementsAt(0, buffer, len, fallible)) { FireInternalError(__LINE__); return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/nfc/gonk/NfcService.cpp b/dom/nfc/gonk/NfcService.cpp index 5b97e95304..9f1df9f117 100644 --- a/dom/nfc/gonk/NfcService.cpp +++ b/dom/nfc/gonk/NfcService.cpp @@ -161,14 +161,15 @@ public: int length = mEvent.mTechList.Length(); event.mTechList.Construct(); - if (!event.mTechList.Value().SetCapacity(length)) { + if (!event.mTechList.Value().SetCapacity(length, fallible)) { return NS_ERROR_FAILURE; } for (int i = 0; i < length; i++) { NFCTechType tech = static_cast(mEvent.mTechList[i]); MOZ_ASSERT(tech < NFCTechType::EndGuard_); - *event.mTechList.Value().AppendElement() = tech; + // FIXME: Make this infallible after bug 968520 is done. + *event.mTechList.Value().AppendElement(fallible) = tech; } } @@ -180,13 +181,15 @@ public: if (mEvent.mRecords.Length() > 0) { int length = mEvent.mRecords.Length(); event.mRecords.Construct(); - if (!event.mRecords.Value().SetCapacity(length)) { + if (!event.mRecords.Value().SetCapacity(length, fallible)) { return NS_ERROR_FAILURE; } for (int i = 0; i < length; i++) { NDEFRecordStruct& recordStruct = mEvent.mRecords[i]; - MozNDEFRecordOptions& record = *event.mRecords.Value().AppendElement(); + // FIXME: Make this infallible after bug 968520 is done. + MozNDEFRecordOptions& record = + *event.mRecords.Value().AppendElement(fallible); record.mTnf = recordStruct.mTnf; MOZ_ASSERT(record.mTnf < TNF::EndGuard_); diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index d6dcb4ca5e..719a74c924 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -978,7 +978,7 @@ already_AddRefed nsNPAPIPluginInstance::CreateSurfaceText void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable() { if (mRunning == RUNNING && mOwner) - AndroidBridge::Bridge()->ScheduleComposite(); + AndroidBridge::Bridge()->InvalidateAndScheduleComposite(); } void* nsNPAPIPluginInstance::AcquireContentWindow() diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 671dc6387a..a456b26c2f 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -393,17 +393,6 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor( return true; } -class NotificationSink : public CompositionNotifySink -{ -public: - explicit NotificationSink(PluginInstanceParent* aInstance) : mInstance(aInstance) - { } - - virtual void DidComposite() { mInstance->DidComposite(); } -private: - PluginInstanceParent *mInstance; -}; - bool PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel( const int& drawingModel, NPError* result) diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index fc740774a7..b85788b284 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -33,7 +33,6 @@ class nsPluginInstanceOwner; namespace mozilla { namespace layers { class ImageContainer; -class CompositionNotifySink; } namespace plugins { @@ -343,7 +342,6 @@ private: bool mIsWhitelistedForShumway; NPWindowType mWindowType; int16_t mDrawingModel; - nsAutoPtr mNotifySink; nsDataHashtable, PluginScriptableObjectParent*> mScriptableObjects; diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index 0f46e7d220..a4b3a604b6 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -1212,7 +1212,7 @@ nsCSPContext::ToJSON(nsAString& outCSPinJSON) for (uint32_t p = 0; p < mPolicies.Length(); p++) { dom::CSP jsonCSP; mPolicies[p]->toDomCSPStruct(jsonCSP); - jsonPolicies.mCsp_policies.Value().AppendElement(jsonCSP); + jsonPolicies.mCsp_policies.Value().AppendElement(jsonCSP, fallible); } // convert the gathered information to JSON diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp index b807234384..5d9f84b95f 100644 --- a/dom/security/nsCSPUtils.cpp +++ b/dom/security/nsCSPUtils.cpp @@ -801,7 +801,7 @@ nsCSPDirective::toDomCSPStruct(mozilla::dom::CSP& outCSP) const for (uint32_t i = 0; i < mSrcs.Length(); i++) { src.Truncate(); mSrcs[i]->toString(src); - srcs.AppendElement(src); + srcs.AppendElement(src, mozilla::fallible); } switch(mDirective) { @@ -1055,7 +1055,7 @@ nsCSPPolicy::toDomCSPStruct(mozilla::dom::CSP& outCSP) const for (uint32_t i = 0; i < mDirectives.Length(); ++i) { if (mDirectives[i]->equals(nsIContentSecurityPolicy::REFERRER_DIRECTIVE)) { mozilla::dom::Sequence srcs; - srcs.AppendElement(mReferrerPolicy); + srcs.AppendElement(mReferrerPolicy, mozilla::fallible); outCSP.mReferrer.Construct(); outCSP.mReferrer.Value() = srcs; } else { diff --git a/dom/smil/nsSMILAnimationFunction.cpp b/dom/smil/nsSMILAnimationFunction.cpp index 6c708c0662..c7d19db56b 100644 --- a/dom/smil/nsSMILAnimationFunction.cpp +++ b/dom/smil/nsSMILAnimationFunction.cpp @@ -787,20 +787,20 @@ nsSMILAnimationFunction::GetValues(const nsISMILAttr& aSMILAttr, // AppendElement() below must succeed, because SetCapacity() succeeded. if (!to.IsNull()) { if (!from.IsNull()) { - MOZ_ALWAYS_TRUE(result.AppendElement(from)); - MOZ_ALWAYS_TRUE(result.AppendElement(to)); + MOZ_ALWAYS_TRUE(result.AppendElement(from, mozilla::fallible)); + MOZ_ALWAYS_TRUE(result.AppendElement(to, mozilla::fallible)); } else { - MOZ_ALWAYS_TRUE(result.AppendElement(to)); + MOZ_ALWAYS_TRUE(result.AppendElement(to, mozilla::fallible)); } } else if (!by.IsNull()) { nsSMILValue effectiveFrom(by.mType); if (!from.IsNull()) effectiveFrom = from; // Set values to 'from; from + by' - MOZ_ALWAYS_TRUE(result.AppendElement(effectiveFrom)); + MOZ_ALWAYS_TRUE(result.AppendElement(effectiveFrom, mozilla::fallible)); nsSMILValue effectiveTo(effectiveFrom); if (!effectiveTo.IsNull() && NS_SUCCEEDED(effectiveTo.Add(by))) { - MOZ_ALWAYS_TRUE(result.AppendElement(effectiveTo)); + MOZ_ALWAYS_TRUE(result.AppendElement(effectiveTo, mozilla::fallible)); } else { // Using by-animation with non-additive type or bad base-value return NS_ERROR_FAILURE; diff --git a/dom/smil/nsSMILParserUtils.cpp b/dom/smil/nsSMILParserUtils.cpp index e075e49265..21e630aab1 100644 --- a/dom/smil/nsSMILParserUtils.cpp +++ b/dom/smil/nsSMILParserUtils.cpp @@ -535,7 +535,8 @@ nsSMILParserUtils::ParseKeySplines(const nsAString& aSpec, !aKeySplines.AppendElement(nsSMILKeySpline(values[0], values[1], values[2], - values[3]))) { + values[3]), + fallible)) { return false; } } @@ -563,7 +564,7 @@ nsSMILParserUtils::ParseSemicolonDelimitedProgressList(const nsAString& aSpec, return false; } - if (!aArray.AppendElement(value)) { + if (!aArray.AppendElement(value, fallible)) { return false; } previousValue = value; @@ -594,7 +595,7 @@ public: tmpPreventCachingOfSandwich))) return false; - if (!mValuesArray->AppendElement(newValue)) { + if (!mValuesArray->AppendElement(newValue, fallible)) { return false; } if (tmpPreventCachingOfSandwich) { diff --git a/dom/svg/DOMSVGLengthList.cpp b/dom/svg/DOMSVGLengthList.cpp index bca3d66db4..1788d7a398 100644 --- a/dom/svg/DOMSVGLengthList.cpp +++ b/dom/svg/DOMSVGLengthList.cpp @@ -266,7 +266,7 @@ DOMSVGLengthList::InsertItemBefore(DOMSVGLength& newItem, MaybeInsertNullInAnimValListAt(index); InternalList().InsertItem(index, domItem->ToSVGLength()); - MOZ_ALWAYS_TRUE(mItems.InsertElementAt(index, domItem.get())); + MOZ_ALWAYS_TRUE(mItems.InsertElementAt(index, domItem.get(), fallible)); // This MUST come after the insertion into InternalList(), or else under the // insertion into InternalList() the values read from domItem would be bad @@ -380,7 +380,7 @@ DOMSVGLengthList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); - animVal->mItems.InsertElementAt(aIndex, static_cast(nullptr)); + MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, nullptr, fallible)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); } diff --git a/dom/svg/DOMSVGNumberList.cpp b/dom/svg/DOMSVGNumberList.cpp index b5feac3e78..9df233c85b 100644 --- a/dom/svg/DOMSVGNumberList.cpp +++ b/dom/svg/DOMSVGNumberList.cpp @@ -250,7 +250,7 @@ DOMSVGNumberList::InsertItemBefore(DOMSVGNumber& aItem, MaybeInsertNullInAnimValListAt(index); InternalList().InsertItem(index, domItem->ToSVGNumber()); - MOZ_ALWAYS_TRUE(mItems.InsertElementAt(index, domItem)); + MOZ_ALWAYS_TRUE(mItems.InsertElementAt(index, domItem, fallible)); // This MUST come after the insertion into InternalList(), or else under the // insertion into InternalList() the values read from domItem would be bad @@ -359,7 +359,7 @@ DOMSVGNumberList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); - animVal->mItems.InsertElementAt(aIndex, static_cast(nullptr)); + MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, nullptr, fallible)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); } diff --git a/dom/svg/DOMSVGPathSegList.cpp b/dom/svg/DOMSVGPathSegList.cpp index cf9d3ef144..e7ffd842d4 100644 --- a/dom/svg/DOMSVGPathSegList.cpp +++ b/dom/svg/DOMSVGPathSegList.cpp @@ -221,7 +221,7 @@ DOMSVGPathSegList::InternalListWillChangeTo(const SVGPathData& aNewValue) // have FEWER items than it does. return; } - if (!mItems.AppendElement(ItemProxy(nullptr, dataIndex))) { + if (!mItems.AppendElement(ItemProxy(nullptr, dataIndex), fallible)) { // OOM ErrorResult rv; Clear(rv); @@ -385,10 +385,12 @@ DOMSVGPathSegList::InsertItemBefore(DOMSVGPathSeg& aNewItem, MOZ_ALWAYS_TRUE(InternalList().mData.InsertElementsAt(internalIndex, segAsRaw, - 1 + argCount)); + 1 + argCount, + fallible)); MOZ_ALWAYS_TRUE(mItems.InsertElementAt(aIndex, ItemProxy(domItem.get(), - internalIndex))); + internalIndex), + fallible)); // This MUST come after the insertion into InternalList(), or else under the // insertion into InternalList() the values read from domItem would be bad @@ -541,7 +543,10 @@ DOMSVGPathSegList:: MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); - animVal->mItems.InsertElementAt(aIndex, ItemProxy(nullptr, aInternalIndex)); + MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, + ItemProxy(nullptr, + aInternalIndex), + fallible)); animVal->UpdateListIndicesFromIndex(aIndex + 1, 1 + aArgCountForItem); } diff --git a/dom/svg/DOMSVGPointList.cpp b/dom/svg/DOMSVGPointList.cpp index e777595216..9c52471e63 100644 --- a/dom/svg/DOMSVGPointList.cpp +++ b/dom/svg/DOMSVGPointList.cpp @@ -317,7 +317,7 @@ DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex, MaybeInsertNullInAnimValListAt(aIndex); InternalList().InsertItem(aIndex, domItem->ToSVGPoint()); - MOZ_ALWAYS_TRUE(mItems.InsertElementAt(aIndex, domItem)); + MOZ_ALWAYS_TRUE(mItems.InsertElementAt(aIndex, domItem, fallible)); // This MUST come after the insertion into InternalList(), or else under the // insertion into InternalList() the values read from domItem would be bad @@ -433,7 +433,7 @@ DOMSVGPointList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); - animVal->mItems.InsertElementAt(aIndex, static_cast(nullptr)); + MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, nullptr, fallible)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); } diff --git a/dom/svg/DOMSVGTransformList.cpp b/dom/svg/DOMSVGTransformList.cpp index 79e950f431..87930c994d 100644 --- a/dom/svg/DOMSVGTransformList.cpp +++ b/dom/svg/DOMSVGTransformList.cpp @@ -258,7 +258,7 @@ DOMSVGTransformList::InsertItemBefore(SVGTransform& newItem, MaybeInsertNullInAnimValListAt(index); InternalList().InsertItem(index, domItem->ToSVGTransform()); - MOZ_ALWAYS_TRUE(mItems.InsertElementAt(index, domItem.get())); + MOZ_ALWAYS_TRUE(mItems.InsertElementAt(index, domItem.get(), fallible)); // This MUST come after the insertion into InternalList(), or else under the // insertion into InternalList() the values read from domItem would be bad @@ -406,8 +406,7 @@ DOMSVGTransformList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); - animVal->mItems.InsertElementAt(aIndex, - static_cast(nullptr)); + MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, nullptr, fallible)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); } diff --git a/dom/svg/SVGLengthList.cpp b/dom/svg/SVGLengthList.cpp index b44de345ff..0c5b7752e5 100644 --- a/dom/svg/SVGLengthList.cpp +++ b/dom/svg/SVGLengthList.cpp @@ -18,11 +18,9 @@ namespace mozilla { nsresult SVGLengthList::CopyFrom(const SVGLengthList& rhs) { - if (!mLengths.SetCapacity(rhs.Length(), fallible)) { - // Yes, we do want fallible alloc here + if (!mLengths.Assign(rhs.mLengths, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - mLengths = rhs.mLengths; return NS_OK; } diff --git a/dom/svg/SVGLengthList.h b/dom/svg/SVGLengthList.h index 41951eda84..4d11e1afb9 100644 --- a/dom/svg/SVGLengthList.h +++ b/dom/svg/SVGLengthList.h @@ -107,7 +107,7 @@ private: bool InsertItem(uint32_t aIndex, const SVGLength &aLength) { if (aIndex >= mLengths.Length()) aIndex = mLengths.Length(); - return !!mLengths.InsertElementAt(aIndex, aLength); + return !!mLengths.InsertElementAt(aIndex, aLength, fallible); } void ReplaceItem(uint32_t aIndex, const SVGLength &aLength) { @@ -123,7 +123,7 @@ private: } bool AppendItem(SVGLength aLength) { - return !!mLengths.AppendElement(aLength); + return !!mLengths.AppendElement(aLength, fallible); } protected: diff --git a/dom/svg/SVGMotionSMILAnimationFunction.cpp b/dom/svg/SVGMotionSMILAnimationFunction.cpp index 74cd097d29..972d1b6270 100644 --- a/dom/svg/SVGMotionSMILAnimationFunction.cpp +++ b/dom/svg/SVGMotionSMILAnimationFunction.cpp @@ -174,7 +174,7 @@ SVGMotionSMILAnimationFunction:: if (HasAttr(nsGkAtoms::from)) { const nsAString& fromStr = GetAttr(nsGkAtoms::from)->GetStringValue(); success = pathGenerator.MoveToAbsolute(fromStr); - mPathVertices.AppendElement(0.0); + mPathVertices.AppendElement(0.0, fallible); } else { // Create dummy 'from' value at 0,0, if we're doing by-animation. // (NOTE: We don't add the dummy 0-point to our list for *to-animation*, @@ -182,7 +182,7 @@ SVGMotionSMILAnimationFunction:: // expect a dummy value. It only expects one value: the final 'to' value.) pathGenerator.MoveToOrigin(); if (!HasAttr(nsGkAtoms::to)) { - mPathVertices.AppendElement(0.0); + mPathVertices.AppendElement(0.0, fallible); } success = true; } @@ -200,7 +200,7 @@ SVGMotionSMILAnimationFunction:: success = pathGenerator.LineToRelative(byStr, dist); } if (success) { - mPathVertices.AppendElement(dist); + mPathVertices.AppendElement(dist, fallible); } } } @@ -308,7 +308,8 @@ SVGMotionSMILAnimationFunction:: double curDist = aPointDistances[i] * distanceMultiplier; if (!aResult.AppendElement( SVGMotionSMILType::ConstructSMILValue(aPath, curDist, - mRotateType, mRotateAngle))) { + mRotateType, mRotateAngle), + fallible)) { return false; } } diff --git a/dom/svg/SVGMotionSMILPathUtils.cpp b/dom/svg/SVGMotionSMILPathUtils.cpp index 24c9db6992..e31c6a3862 100644 --- a/dom/svg/SVGMotionSMILPathUtils.cpp +++ b/dom/svg/SVGMotionSMILPathUtils.cpp @@ -136,14 +136,14 @@ SVGMotionSMILPathUtils::MotionValueParser:: // Interpret first value in "values" attribute as the path's initial MoveTo success = mPathGenerator->MoveToAbsolute(aValueStr); if (success) { - success = !!mPointDistances->AppendElement(0.0); + success = !!mPointDistances->AppendElement(0.0, fallible); } } else { double dist; success = mPathGenerator->LineToAbsolute(aValueStr, dist); if (success) { mDistanceSoFar += dist; - success = !!mPointDistances->AppendElement(mDistanceSoFar); + success = !!mPointDistances->AppendElement(mDistanceSoFar, fallible); } } return success; diff --git a/dom/svg/SVGMotionSMILType.cpp b/dom/svg/SVGMotionSMILType.cpp index d5a6cd3119..ca4e560a0a 100644 --- a/dom/svg/SVGMotionSMILType.cpp +++ b/dom/svg/SVGMotionSMILType.cpp @@ -195,13 +195,10 @@ SVGMotionSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const const MotionSegmentArray& srcArr = ExtractMotionSegmentArray(aSrc); MotionSegmentArray& dstArr = ExtractMotionSegmentArray(aDest); - - // Ensure we have sufficient memory. - if (!dstArr.SetCapacity(srcArr.Length(), fallible)) { + if (!dstArr.Assign(srcArr, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - dstArr = srcArr; // Do the assignment. return NS_OK; } @@ -305,8 +302,7 @@ SVGMotionSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, // Replace destination's current value -- a point-on-a-path -- with the // translation that results from our addition. - dstArr.Clear(); - dstArr.AppendElement(MotionSegment(newX, newY, rotateAngle)); + dstArr.ReplaceElementAt(0, MotionSegment(newX, newY, rotateAngle)); return NS_OK; } @@ -324,7 +320,7 @@ SVGMotionSMILType::SandwichAdd(nsSMILValue& aDest, MOZ_ASSERT(srcArr.Length() == 1, "Trying to do sandwich add of more than one value"); - if (!dstArr.AppendElement(srcArr[0])) { + if (!dstArr.AppendElement(srcArr[0], fallible)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -441,7 +437,8 @@ SVGMotionSMILType::Interpolate(const nsSMILValue& aStartVal, // AppendElement has guaranteed success here, since Init() allocates 1 slot. MOZ_ALWAYS_TRUE(resultArr.AppendElement(MotionSegment(path, resultDist, rotateType, - rotateAngle))); + rotateAngle), + fallible)); return NS_OK; } @@ -484,7 +481,8 @@ SVGMotionSMILType::ConstructSMILValue(Path* aPath, // AppendElement has guaranteed success here, since Init() allocates 1 slot. MOZ_ALWAYS_TRUE(arr.AppendElement(MotionSegment(aPath, aDist, - aRotateType, aRotateAngle))); + aRotateType, aRotateAngle), + fallible)); return smilVal; } diff --git a/dom/svg/SVGNumberList.cpp b/dom/svg/SVGNumberList.cpp index c32f4a3b31..2d0d37d455 100644 --- a/dom/svg/SVGNumberList.cpp +++ b/dom/svg/SVGNumberList.cpp @@ -17,11 +17,9 @@ namespace mozilla { nsresult SVGNumberList::CopyFrom(const SVGNumberList& rhs) { - if (!mNumbers.SetCapacity(rhs.Length(), fallible)) { - // Yes, we do want fallible alloc here + if (!mNumbers.Assign(rhs.mNumbers, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - mNumbers = rhs.mNumbers; return NS_OK; } diff --git a/dom/svg/SVGNumberList.h b/dom/svg/SVGNumberList.h index 43726e339e..b6845ffd55 100644 --- a/dom/svg/SVGNumberList.h +++ b/dom/svg/SVGNumberList.h @@ -110,7 +110,7 @@ private: if (aIndex >= mNumbers.Length()) { aIndex = mNumbers.Length(); } - return !!mNumbers.InsertElementAt(aIndex, aNumber); + return !!mNumbers.InsertElementAt(aIndex, aNumber, fallible); } void ReplaceItem(uint32_t aIndex, const float &aNumber) { @@ -126,7 +126,7 @@ private: } bool AppendItem(float aNumber) { - return !!mNumbers.AppendElement(aNumber); + return !!mNumbers.AppendElement(aNumber, fallible); } protected: diff --git a/dom/svg/SVGPathData.cpp b/dom/svg/SVGPathData.cpp index 146d916a91..b43c796e12 100644 --- a/dom/svg/SVGPathData.cpp +++ b/dom/svg/SVGPathData.cpp @@ -34,11 +34,9 @@ static bool IsMoveto(uint16_t aSegType) nsresult SVGPathData::CopyFrom(const SVGPathData& rhs) { - if (!mData.SetCapacity(rhs.mData.Length(), fallible)) { - // Yes, we do want fallible alloc here + if (!mData.Assign(rhs.mData, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - mData = rhs.mData; return NS_OK; } @@ -175,7 +173,7 @@ SVGPathData::GetDistancesFromOriginToEndsOfVisibleSegments(FallibleTArrayAppendElement(state.length)) { + if (!aOutput->AppendElement(state.length, fallible)) { return false; } } diff --git a/dom/svg/SVGPointList.cpp b/dom/svg/SVGPointList.cpp index 4253805534..8cbc55148b 100644 --- a/dom/svg/SVGPointList.cpp +++ b/dom/svg/SVGPointList.cpp @@ -16,11 +16,9 @@ namespace mozilla { nsresult SVGPointList::CopyFrom(const SVGPointList& rhs) { - if (!SetCapacity(rhs.Length())) { - // Yes, we do want fallible alloc here + if (!mItems.Assign(rhs.mItems, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - mItems = rhs.mItems; return NS_OK; } diff --git a/dom/svg/SVGPointList.h b/dom/svg/SVGPointList.h index 8d94f80763..7f4008c6d8 100644 --- a/dom/svg/SVGPointList.h +++ b/dom/svg/SVGPointList.h @@ -118,7 +118,7 @@ private: if (aIndex >= mItems.Length()) { aIndex = mItems.Length(); } - return !!mItems.InsertElementAt(aIndex, aPoint); + return !!mItems.InsertElementAt(aIndex, aPoint, fallible); } void ReplaceItem(uint32_t aIndex, const SVGPoint &aPoint) { @@ -134,7 +134,7 @@ private: } bool AppendItem(SVGPoint aPoint) { - return !!mItems.AppendElement(aPoint); + return !!mItems.AppendElement(aPoint, fallible); } protected: diff --git a/dom/svg/SVGStringList.cpp b/dom/svg/SVGStringList.cpp index 0184bc1f7e..dc00bc5b88 100644 --- a/dom/svg/SVGStringList.cpp +++ b/dom/svg/SVGStringList.cpp @@ -16,11 +16,9 @@ namespace mozilla { nsresult SVGStringList::CopyFrom(const SVGStringList& rhs) { - if (!mStrings.SetCapacity(rhs.Length(), fallible)) { - // Yes, we do want fallible alloc here + if (!mStrings.Assign(rhs.mStrings, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - mStrings = rhs.mStrings; mIsSet = true; return NS_OK; } diff --git a/dom/svg/SVGStringList.h b/dom/svg/SVGStringList.h index 6a2f9c8fc0..e10ac5da47 100644 --- a/dom/svg/SVGStringList.h +++ b/dom/svg/SVGStringList.h @@ -105,7 +105,7 @@ private: if (aIndex >= mStrings.Length()) { aIndex = mStrings.Length(); } - if (mStrings.InsertElementAt(aIndex, aString)) { + if (mStrings.InsertElementAt(aIndex, aString, fallible)) { mIsSet = true; return true; } @@ -125,7 +125,7 @@ private: } bool AppendItem(const nsAString &aString) { - if (mStrings.AppendElement(aString)) { + if (mStrings.AppendElement(aString, fallible)) { mIsSet = true; return true; } diff --git a/dom/svg/SVGTransformList.cpp b/dom/svg/SVGTransformList.cpp index d37e79ce22..c6c4eefafe 100644 --- a/dom/svg/SVGTransformList.cpp +++ b/dom/svg/SVGTransformList.cpp @@ -43,11 +43,9 @@ SVGTransformList::CopyFrom(const SVGTransformList& rhs) nsresult SVGTransformList::CopyFrom(const nsTArray& aTransformArray) { - if (!mItems.SetCapacity(aTransformArray.Length(), fallible)) { - // Yes, we do want fallible alloc here + if (!mItems.Assign(aTransformArray, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - mItems = aTransformArray; return NS_OK; } diff --git a/dom/svg/SVGTransformList.h b/dom/svg/SVGTransformList.h index 334fa3dbba..ed8202bce7 100644 --- a/dom/svg/SVGTransformList.h +++ b/dom/svg/SVGTransformList.h @@ -113,7 +113,7 @@ private: if (aIndex >= mItems.Length()) { aIndex = mItems.Length(); } - return !!mItems.InsertElementAt(aIndex, aTransform); + return !!mItems.InsertElementAt(aIndex, aTransform, fallible); } void ReplaceItem(uint32_t aIndex, const nsSVGTransform& aTransform) { @@ -129,7 +129,7 @@ private: } bool AppendItem(const nsSVGTransform& aTransform) { - return !!mItems.AppendElement(aTransform); + return !!mItems.AppendElement(aTransform, fallible); } protected: diff --git a/dom/svg/SVGTransformListParser.cpp b/dom/svg/SVGTransformListParser.cpp index 91c4e8be5a..797a909ed3 100644 --- a/dom/svg/SVGTransformListParser.cpp +++ b/dom/svg/SVGTransformListParser.cpp @@ -146,7 +146,7 @@ SVGTransformListParser::ParseTranslate() // fall-through case 2: { - nsSVGTransform* transform = mTransforms.AppendElement(); + nsSVGTransform* transform = mTransforms.AppendElement(fallible); if (!transform) { return false; } @@ -174,7 +174,7 @@ SVGTransformListParser::ParseScale() // fall-through case 2: { - nsSVGTransform* transform = mTransforms.AppendElement(); + nsSVGTransform* transform = mTransforms.AppendElement(fallible); if (!transform) { return false; } @@ -203,7 +203,7 @@ SVGTransformListParser::ParseRotate() // fall-through case 3: { - nsSVGTransform* transform = mTransforms.AppendElement(); + nsSVGTransform* transform = mTransforms.AppendElement(fallible); if (!transform) { return false; } @@ -225,7 +225,7 @@ SVGTransformListParser::ParseSkewX() return false; } - nsSVGTransform* transform = mTransforms.AppendElement(); + nsSVGTransform* transform = mTransforms.AppendElement(fallible); if (!transform) { return false; } @@ -244,7 +244,7 @@ SVGTransformListParser::ParseSkewY() return false; } - nsSVGTransform* transform = mTransforms.AppendElement(); + nsSVGTransform* transform = mTransforms.AppendElement(fallible); if (!transform) { return false; } @@ -263,7 +263,7 @@ SVGTransformListParser::ParseMatrix() return false; } - nsSVGTransform* transform = mTransforms.AppendElement(); + nsSVGTransform* transform = mTransforms.AppendElement(fallible); if (!transform) { return false; } diff --git a/dom/svg/SVGTransformListSMILType.cpp b/dom/svg/SVGTransformListSMILType.cpp index 114e385727..40777b026b 100644 --- a/dom/svg/SVGTransformListSMILType.cpp +++ b/dom/svg/SVGTransformListSMILType.cpp @@ -48,12 +48,9 @@ SVGTransformListSMILType::Assign(nsSMILValue& aDest, const TransformArray* srcTransforms = static_cast(aSrc.mU.mPtr); TransformArray* dstTransforms = static_cast(aDest.mU.mPtr); - - // Before we assign, ensure we have sufficient memory - bool result = dstTransforms->SetCapacity(srcTransforms->Length(), fallible); - NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY); - - *dstTransforms = *srcTransforms; + if (!dstTransforms->Assign(*srcTransforms, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } return NS_OK; } @@ -118,7 +115,7 @@ SVGTransformListSMILType::Add(nsSMILValue& aDest, const SVGTransformSMILData& srcTransform = srcTransforms[0]; if (dstTransforms.IsEmpty()) { SVGTransformSMILData* result = dstTransforms.AppendElement( - SVGTransformSMILData(srcTransform.mTransformType)); + SVGTransformSMILData(srcTransform.mTransformType), fallible); NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY); } SVGTransformSMILData& dstTransform = dstTransforms[0]; @@ -170,7 +167,8 @@ SVGTransformListSMILType::SandwichAdd(nsSMILValue& aDest, // Stick the src on the end of the array const SVGTransformSMILData& srcTransform = srcTransforms[0]; - SVGTransformSMILData* result = dstTransforms.AppendElement(srcTransform); + SVGTransformSMILData* result = + dstTransforms.AppendElement(srcTransform, fallible); NS_ENSURE_TRUE(result,NS_ERROR_OUT_OF_MEMORY); return NS_OK; @@ -305,7 +303,7 @@ SVGTransformListSMILType::Interpolate(const nsSMILValue& aStartVal, // Assign the result SVGTransformSMILData* transform = - dstTransforms.AppendElement(resultTransform); + dstTransforms.AppendElement(resultTransform, fallible); NS_ENSURE_TRUE(transform,NS_ERROR_OUT_OF_MEMORY); return NS_OK; @@ -323,7 +321,7 @@ SVGTransformListSMILType::AppendTransform( NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type"); TransformArray& transforms = *static_cast(aValue.mU.mPtr); - return transforms.AppendElement(aTransform) ? + return transforms.AppendElement(aTransform, fallible) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } @@ -342,7 +340,8 @@ SVGTransformListSMILType::AppendTransforms(const SVGTransformList& aList, for (uint32_t i = 0; i < aList.Length(); ++i) { // No need to check the return value below since we have already allocated // the necessary space - MOZ_ALWAYS_TRUE(transforms.AppendElement(SVGTransformSMILData(aList[i]))); + MOZ_ALWAYS_TRUE(transforms.AppendElement(SVGTransformSMILData(aList[i]), + fallible)); } return true; } @@ -364,7 +363,7 @@ SVGTransformListSMILType::GetTransforms(const nsSMILValue& aValue, for (uint32_t i = 0; i < smilTransforms.Length(); ++i) { // No need to check the return value below since we have already allocated // the necessary space - aTransforms.AppendElement(smilTransforms[i].ToSVGTransform()); + aTransforms.AppendElement(smilTransforms[i].ToSVGTransform(), fallible); } return true; } diff --git a/dom/tv/TVSource.cpp b/dom/tv/TVSource.cpp index 306dd8abcd..5c12d2582d 100644 --- a/dom/tv/TVSource.cpp +++ b/dom/tv/TVSource.cpp @@ -349,7 +349,7 @@ TVSource::NotifyEITBroadcasted(nsITVChannelData* aChannelData, for (uint32_t i = 0; i < aCount; i++) { nsRefPtr program = new TVProgram(GetOwner(), channel, aProgramDataList[i]); - *programs.AppendElement() = program; + *programs.AppendElement(fallible) = program; } return DispatchEITBroadcastedEvent(programs); } diff --git a/dom/webidl/WebGL2RenderingContext.webidl b/dom/webidl/WebGL2RenderingContext.webidl index fa71c3ec62..91bc49799c 100644 --- a/dom/webidl/WebGL2RenderingContext.webidl +++ b/dom/webidl/WebGL2RenderingContext.webidl @@ -26,11 +26,9 @@ interface WebGLSync { interface WebGLTransformFeedback { }; -/* [Pref="webgl.enable-prototype-webgl2"] interface WebGLVertexArrayObject { }; -*/ [Pref="webgl.enable-prototype-webgl2"] interface WebGL2RenderingContext : WebGLRenderingContext @@ -322,8 +320,7 @@ interface WebGL2RenderingContext : WebGLRenderingContext /* Buffer objects */ void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); - void getBufferSubData(GLenum target, GLintptr offset, ArrayBuffer returnedData); - void getBufferSubData(GLenum target, GLintptr offset, ArrayBufferView returnedData); + void getBufferSubData(GLenum target, GLintptr offset, ArrayBuffer? returnedData); /* Framebuffer objects */ void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, @@ -472,10 +469,8 @@ interface WebGL2RenderingContext : WebGLRenderingContext void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); /* Vertex Array Objects */ - /* WebGLVertexArrayObject? createVertexArray(); void deleteVertexArray(WebGLVertexArrayObject? vertexArray); [WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray); void bindVertexArray(WebGLVertexArrayObject? array); - */ }; diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index b3208d4eb6..5e620e6d6e 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -690,7 +690,7 @@ GLBlitHelper::BindAndUploadEGLImage(EGLImage image, GLuint target) #ifdef MOZ_WIDGET_GONK bool -GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip) +GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage) { ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); @@ -711,8 +711,6 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip) BindAndUploadEGLImage(image, LOCAL_GL_TEXTURE_EXTERNAL_OES); - mGL->fUniform1f(mYFlipLoc, yflip ? (float)1.0f : (float)0.0f); - mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); sEGLLibrary.fDestroyImage(sEGLLibrary.Display(), image); @@ -726,7 +724,7 @@ GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip) #define ATTACH_WAIT_MS 50 bool -GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yflip) +GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage) { AndroidSurfaceTexture* surfaceTexture = stImage->GetData()->mSurfTex; @@ -746,7 +744,6 @@ GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool surfaceTexture->GetTransformMatrix(transform); mGL->fUniformMatrix4fv(mTextureTransformLoc, 1, false, &transform._11); - mGL->fUniform1f(mYFlipLoc, yflip ? 1.0f : 0.0f); mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); surfaceTexture->Detach(); @@ -756,7 +753,7 @@ GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool } bool -GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yflip) +GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image) { EGLImage eglImage = image->GetData()->mImage; EGLSync eglSync = image->GetData()->mSync; @@ -775,8 +772,6 @@ GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yflip) BindAndUploadEGLImage(eglImage, LOCAL_GL_TEXTURE_2D); - mGL->fUniform1f(mYFlipLoc, yflip ? 1.0f : 0.0f); - mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, oldBinding); @@ -786,7 +781,7 @@ GLBlitHelper::BlitEGLImageImage(layers::EGLImageImage* image, bool yflip) #endif bool -GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yflip) +GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage) { ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); const PlanarYCbCrData* yuvData = yuvImage->GetData(); @@ -807,8 +802,6 @@ GLBlitHelper::BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yfli BindAndUploadYUVTexture(Channel_Cb, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCbChannel, needsAllocation); BindAndUploadYUVTexture(Channel_Cr, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCrChannel, needsAllocation); - mGL->fUniform1f(mYFlipLoc, yflip ? (float)1.0 : (float)0.0); - if (needsAllocation) { mGL->fUniform2f(mYTexScaleLoc, (float)yuvData->mYSize.width/yuvData->mYStride, 1.0f); mGL->fUniform2f(mCbCrTexScaleLoc, (float)yuvData->mCbCrSize.width/yuvData->mCbCrStride, 1.0f); @@ -826,32 +819,39 @@ bool GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize, GLuint destFB, - bool yflip, - GLuint xoffset, - GLuint yoffset, - GLuint cropWidth, - GLuint cropHeight) + OriginPos destOrigin) { ScopedGLDrawState autoStates(mGL); BlitType type; + OriginPos srcOrigin; + switch (srcImage->GetFormat()) { case ImageFormat::PLANAR_YCBCR: type = ConvertPlanarYCbCr; + srcOrigin = OriginPos::TopLeft; break; - case ImageFormat::GRALLOC_PLANAR_YCBCR: + #ifdef MOZ_WIDGET_GONK + case ImageFormat::GRALLOC_PLANAR_YCBCR: type = ConvertGralloc; + srcOrigin = OriginPos::TopLeft; break; #endif + #ifdef MOZ_WIDGET_ANDROID case ImageFormat::SURFACE_TEXTURE: type = ConvertSurfaceTexture; + srcOrigin = static_cast(srcImage)->GetData() + ->mOriginPos; break; + case ImageFormat::EGLIMAGE: type = ConvertEGLImage; + srcOrigin = static_cast(srcImage)->GetData()->mOriginPos; break; #endif + default: return false; } @@ -861,37 +861,34 @@ GLBlitHelper::BlitImageToFramebuffer(layers::Image* srcImage, return false; } + const bool needsYFlip = (srcOrigin != destOrigin); + mGL->fUniform1f(mYFlipLoc, needsYFlip ? (float)1.0 : (float)0.0); + ScopedBindFramebuffer boundFB(mGL, destFB); mGL->fColorMask(LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE); mGL->fViewport(0, 0, destSize.width, destSize.height); - if (xoffset != 0 && yoffset != 0 && cropWidth != 0 && cropHeight != 0) { - mGL->fEnable(LOCAL_GL_SCISSOR_TEST); - mGL->fScissor(xoffset, yoffset, (GLsizei)cropWidth, (GLsizei)cropHeight); - } + switch (type) { #ifdef MOZ_WIDGET_GONK - if (type == ConvertGralloc) { - layers::GrallocImage* grallocImage = static_cast(srcImage); - return BlitGrallocImage(grallocImage, yflip); - } -#endif - if (type == ConvertPlanarYCbCr) { - mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1); - PlanarYCbCrImage* yuvImage = static_cast(srcImage); - return BlitPlanarYCbCrImage(yuvImage, yflip); - } -#ifdef MOZ_WIDGET_ANDROID - if (type == ConvertSurfaceTexture) { - layers::SurfaceTextureImage* stImage = static_cast(srcImage); - return BlitSurfaceTextureImage(stImage, yflip); - } - if (type == ConvertEGLImage) { - layers::EGLImageImage* eglImage = static_cast(srcImage); - return BlitEGLImageImage(eglImage, yflip); - } + case ConvertGralloc: + return BlitGrallocImage(static_cast(srcImage)); #endif - return false; + case ConvertPlanarYCbCr: + mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1); + return BlitPlanarYCbCrImage(static_cast(srcImage)); + +#ifdef MOZ_WIDGET_ANDROID + case ConvertSurfaceTexture: + return BlitSurfaceTextureImage(static_cast(srcImage)); + + case ConvertEGLImage: + return BlitEGLImageImage(static_cast(srcImage)); +#endif + + default: + return false; + } } bool @@ -899,22 +896,15 @@ GLBlitHelper::BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize, GLuint destTex, GLenum destTarget, - bool yflip, - GLuint xoffset, - GLuint yoffset, - GLuint cropWidth, - GLuint cropHeight) + OriginPos destOrigin) { - ScopedGLDrawState autoStates(mGL); + ScopedFramebufferForTexture autoFBForTex(mGL, destTex, destTarget); - if (!mFBO) - mGL->fGenFramebuffers(1, &mFBO); + if (!autoFBForTex.IsComplete()) { + MOZ_CRASH("ScopedFramebufferForTexture failed."); + } - ScopedBindFramebuffer boundFB(mGL, mFBO); - mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, - destTarget, destTex, 0); - return BlitImageToFramebuffer(srcImage, destSize, mFBO, yflip, xoffset, yoffset, - cropWidth, cropHeight); + return BlitImageToFramebuffer(srcImage, destSize, autoFBForTex.FB(), destOrigin); } void @@ -929,7 +919,7 @@ GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, if (mGL->IsSupported(GLFeature::framebuffer_blit)) { ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget); - MOZ_ASSERT(srcWrapper.IsComplete()); + MOZ_DIAGNOSTIC_ASSERT(srcWrapper.IsComplete()); BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB, srcSize, destSize, @@ -938,8 +928,7 @@ GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, } BlitType type; - switch (srcTarget) - { + switch (srcTarget) { case LOCAL_GL_TEXTURE_2D: type = BlitTex2D; break; @@ -947,8 +936,7 @@ GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, type = BlitTexRect; break; default: - printf_stderr("Fatal Error: Failed to prepare to blit texture->framebuffer.\n"); - MOZ_CRASH(); + MOZ_CRASH("Fatal Error: Bad `srcTarget`."); break; } @@ -963,10 +951,14 @@ GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, bool good = UseTexQuadProgram(type, srcSize); if (!good) { // We're up against the wall, so bail. - // This should really be MOZ_CRASH(why) or MOZ_RUNTIME_ASSERT(good). - printf_stderr("Fatal Error: Failed to prepare to blit texture->framebuffer.\n"); - MOZ_CRASH(); + MOZ_DIAGNOSTIC_ASSERT(false, + "Error: Failed to prepare to blit texture->framebuffer.\n"); + mGL->fScissor(0, 0, destSize.width, destSize.height); + mGL->fColorMask(1, 1, 1, 1); + mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); + return; } + mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); } diff --git a/gfx/gl/GLBlitHelper.h b/gfx/gl/GLBlitHelper.h index 6317b8db99..b6bff759c0 100644 --- a/gfx/gl/GLBlitHelper.h +++ b/gfx/gl/GLBlitHelper.h @@ -145,18 +145,20 @@ class GLBlitHelper final void BindAndUploadEGLImage(EGLImage image, GLuint target); #ifdef MOZ_WIDGET_GONK - bool BlitGrallocImage(layers::GrallocImage* grallocImage, bool yflip); + bool BlitGrallocImage(layers::GrallocImage* grallocImage); #endif - bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage, bool yflip); + bool BlitPlanarYCbCrImage(layers::PlanarYCbCrImage* yuvImage); #ifdef MOZ_WIDGET_ANDROID // Blit onto the current FB. - bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage, bool yflip); - bool BlitEGLImageImage(layers::EGLImageImage* eglImage, bool yflip); + bool BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage); + bool BlitEGLImageImage(layers::EGLImageImage* eglImage); #endif -public: - explicit GLBlitHelper(GLContext* gl); + + friend class GLContext; + +public: ~GLBlitHelper(); // If you don't have |srcFormats| for the 2nd definition, @@ -187,12 +189,9 @@ public: GLenum srcTarget = LOCAL_GL_TEXTURE_2D, GLenum destTarget = LOCAL_GL_TEXTURE_2D); bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize, - GLuint destFB, bool yflip = false, GLuint xoffset = 0, - GLuint yoffset = 0, GLuint width = 0, GLuint height = 0); + GLuint destFB, OriginPos destOrigin); bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize, - GLuint destTex, GLenum destTarget, bool yflip = false, - GLuint xoffset = 0, GLuint yoffset = 0, GLuint width = 0, - GLuint height = 0); + GLuint destTex, GLenum destTarget, OriginPos destOrigin); }; } // namespace gl diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index a94216832f..1bc41e09b4 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -2396,7 +2396,7 @@ GLBlitHelper* GLContext::BlitHelper() { if (!mBlitHelper) { - mBlitHelper = MakeUnique(this); + mBlitHelper.reset(new GLBlitHelper(this)); } return mBlitHelper.get(); diff --git a/gfx/layers/GLImages.cpp b/gfx/layers/GLImages.cpp index 7f707f1a1c..673228990d 100644 --- a/gfx/layers/GLImages.cpp +++ b/gfx/layers/GLImages.cpp @@ -57,11 +57,17 @@ GLImage::GetAsSourceSurface() LOCAL_GL_UNSIGNED_BYTE, nullptr); - ScopedFramebufferForTexture fb(sSnapshotContext, scopedTex.Texture()); + ScopedFramebufferForTexture autoFBForTex(sSnapshotContext, scopedTex.Texture()); + if (!autoFBForTex.IsComplete()) { + MOZ_CRASH("ScopedFramebufferForTexture failed."); + } - GLBlitHelper helper(sSnapshotContext); + const gl::OriginPos destOrigin = gl::OriginPos::TopLeft; - if (!helper.BlitImageToFramebuffer(this, size, fb.FB(), true)) { + if (!sSnapshotContext->BlitHelper()->BlitImageToFramebuffer(this, size, + autoFBForTex.FB(), + destOrigin)) + { return nullptr; } @@ -71,7 +77,7 @@ GLImage::GetAsSourceSurface() return nullptr; } - ScopedBindFramebuffer bind(sSnapshotContext, fb.FB()); + ScopedBindFramebuffer bind(sSnapshotContext, autoFBForTex.FB()); ReadPixelsIntoDataSurface(sSnapshotContext, source); return source.forget(); } diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 27994b6f2f..f581b3fade 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -145,7 +145,6 @@ ImageContainer::ImageContainer(ImageContainer::Mode flag) mPreviousImagePainted(false), mImageFactory(new ImageFactory()), mRecycleBin(new BufferRecycleBin()), - mCompositionNotifySink(nullptr), mImageClient(nullptr) { if (ImageBridgeChild::IsCreated()) { diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h index 6f8f2b7ac3..ba87bf9543 100644 --- a/gfx/layers/ImageContainer.h +++ b/gfx/layers/ImageContainer.h @@ -145,9 +145,6 @@ public: int32_t GetSerial() { return mSerial; } - void MarkSent() { mSent = true; } - bool IsSentToCompositor() { return mSent; } - virtual already_AddRefed GetAsSourceSurface() = 0; virtual GrallocImage* AsGrallocImage() @@ -169,8 +166,7 @@ protected: Image(void* aImplData, ImageFormat aFormat) : mImplData(aImplData), mSerial(++sSerialCounter), - mFormat(aFormat), - mSent(false) + mFormat(aFormat) {} // Protected destructor, to discourage deletion outside of Release(): @@ -226,13 +222,6 @@ private: uint32_t mRecycledBufferSize; }; -class CompositionNotifySink -{ -public: - virtual void DidComposite() = 0; - virtual ~CompositionNotifySink() {} -}; - /** * A class that manages Image creation for a LayerManager. The only reason * we need a separate class here is that LayerManagers aren't threadsafe @@ -479,15 +468,6 @@ public: return mPaintCount; } - /** - * Resets the paint count to zero. - * Can be called from any thread. - */ - void ResetPaintCount() { - ReentrantMonitorAutoEnter mon(mReentrantMonitor); - mPaintCount = 0; - } - /** * Increments mPaintCount if this is the first time aPainted has been * painted, and sets mPaintTime if the painted image is the current image. @@ -509,14 +489,6 @@ public: mPaintCount++; mPreviousImagePainted = true; } - - if (mCompositionNotifySink) { - mCompositionNotifySink->DidComposite(); - } - } - - void SetCompositionNotifySink(CompositionNotifySink *aSink) { - mCompositionNotifySink = aSink; } private: @@ -569,8 +541,6 @@ private: nsRefPtr mRecycleBin; - CompositionNotifySink *mCompositionNotifySink; - // This member points to an ImageClient if this ImageContainer was // sucessfully created with ENABLE_ASYNC, or points to null otherwise. // 'unsuccessful' in this case only means that the ImageClient could not diff --git a/gfx/layers/LayersTypes.cpp b/gfx/layers/LayersTypes.cpp new file mode 100644 index 0000000000..f8ad2ae897 --- /dev/null +++ b/gfx/layers/LayersTypes.cpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "LayersTypes.h" + +#ifdef MOZ_WIDGET_GONK +#include +#endif + +namespace mozilla { +namespace layers { + +LayerRenderState::LayerRenderState() + : mFlags(LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT) + , mHasOwnOffset(false) +#ifdef MOZ_WIDGET_GONK + , mSurface(nullptr) + , mOverlayId(INVALID_OVERLAY) + , mTexture(nullptr) +#endif +{ +} + +LayerRenderState::LayerRenderState(const LayerRenderState& aOther) + : mFlags(aOther.mFlags) + , mHasOwnOffset(aOther.mHasOwnOffset) + , mOffset(aOther.mOffset) +#ifdef MOZ_WIDGET_GONK + , mSurface(aOther.mSurface) + , mOverlayId(aOther.mOverlayId) + , mSize(aOther.mSize) + , mTexture(aOther.mTexture) +#endif +{ +} + +LayerRenderState::~LayerRenderState() +{ +} + +#ifdef MOZ_WIDGET_GONK +LayerRenderState::LayerRenderState(android::GraphicBuffer* aSurface, + const gfx::IntSize& aSize, + LayerRenderStateFlags aFlags, + TextureHost* aTexture) + : mFlags(aFlags) + , mHasOwnOffset(false) + , mSurface(aSurface) + , mOverlayId(INVALID_OVERLAY) + , mSize(aSize) + , mTexture(aTexture) +{} +#endif + +} // namespace +} // namespace diff --git a/gfx/layers/LayersTypes.h b/gfx/layers/LayersTypes.h index d6c32cb26a..8a76d5ac3e 100644 --- a/gfx/layers/LayersTypes.h +++ b/gfx/layers/LayersTypes.h @@ -13,7 +13,7 @@ #include "mozilla/TypedEnumBits.h" #ifdef MOZ_WIDGET_GONK -#include +#include #endif #include // FILE #include "mozilla/Logging.h" // for PR_LOG @@ -28,7 +28,7 @@ #define INVALID_OVERLAY -1 namespace android { -class GraphicBuffer; +class MOZ_EXPORT GraphicBuffer; } namespace mozilla { @@ -85,28 +85,19 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(LayerRenderStateFlags) // The 'ifdef MOZ_WIDGET_GONK' sadness here is because we don't want to include // android::sp unless we have to. struct LayerRenderState { - LayerRenderState() -#ifdef MOZ_WIDGET_GONK - : mFlags(LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT) - , mHasOwnOffset(false) - , mSurface(nullptr) - , mOverlayId(INVALID_OVERLAY) - , mTexture(nullptr) -#endif - {} + // Constructors and destructor are defined in LayersTypes.cpp so we don't + // have to pull in a definition for GraphicBuffer.h here. In KK at least, + // that results in nasty pollution such as libui's hardware.h #defining + // 'version_major' and 'version_minor' which conflict with Theora's codec.c... + LayerRenderState(); + LayerRenderState(const LayerRenderState& aOther); + ~LayerRenderState(); #ifdef MOZ_WIDGET_GONK LayerRenderState(android::GraphicBuffer* aSurface, const gfx::IntSize& aSize, LayerRenderStateFlags aFlags, - TextureHost* aTexture) - : mFlags(aFlags) - , mHasOwnOffset(false) - , mSurface(aSurface) - , mOverlayId(INVALID_OVERLAY) - , mSize(aSize) - , mTexture(aTexture) - {} + TextureHost* aTexture); bool OriginBottomLeft() const { return bool(mFlags & LayerRenderStateFlags::ORIGIN_BOTTOM_LEFT); } @@ -133,6 +124,8 @@ struct LayerRenderState { bool mHasOwnOffset; // the location of the layer's origin on mSurface nsIntPoint mOffset; + // The 'ifdef MOZ_WIDGET_GONK' sadness here is because we don't want to include + // android::sp unless we have to. #ifdef MOZ_WIDGET_GONK // surface to render android::sp mSurface; diff --git a/gfx/layers/apz/testutil/APZTestData.cpp b/gfx/layers/apz/testutil/APZTestData.cpp index f48cf3a9cb..3c9440b646 100644 --- a/gfx/layers/apz/testutil/APZTestData.cpp +++ b/gfx/layers/apz/testutil/APZTestData.cpp @@ -17,7 +17,7 @@ struct APZTestDataToJSConverter { dom::Sequence& aOutTo, void (*aElementConverter)(const Key&, const Value&, KeyValuePair&)) { for (auto it = aFrom.begin(); it != aFrom.end(); ++it) { - aOutTo.AppendElement(); + aOutTo.AppendElement(fallible); aElementConverter(it->first, it->second, aOutTo.LastElement()); } } diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index d0e77ef28f..b71810a2ce 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -19,6 +19,9 @@ #include "nsIDOMWindow.h" #include "nsRefreshDriver.h" #include "nsView.h" +#include "mozilla/TouchEvents.h" +#include "mozilla/dom/Element.h" +#include "Layers.h" #define APZCCH_LOG(...) // #define APZCCH_LOG(...) printf_stderr("APZCCH: " __VA_ARGS__) diff --git a/gfx/layers/apz/util/APZCCallbackHelper.h b/gfx/layers/apz/util/APZCCallbackHelper.h index 0493127dd0..f4d30d8d65 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.h +++ b/gfx/layers/apz/util/APZCCallbackHelper.h @@ -6,6 +6,8 @@ #ifndef mozilla_layers_APZCCallbackHelper_h #define mozilla_layers_APZCCallbackHelper_h +#include "nsCOMPtr.h" +#include "nsIPresShell.h" #include "FrameMetrics.h" #include "mozilla/EventForwards.h" #include "mozilla/layers/APZUtils.h" diff --git a/gfx/layers/client/ClientImageLayer.cpp b/gfx/layers/client/ClientImageLayer.cpp index 0df90e8a68..6ac2d6c1a6 100644 --- a/gfx/layers/client/ClientImageLayer.cpp +++ b/gfx/layers/client/ClientImageLayer.cpp @@ -77,6 +77,7 @@ protected: void DestroyBackBuffer() { if (mImageClient) { + mImageClient->SetLayer(nullptr); mImageClient->OnDetach(); mImageClient = nullptr; } @@ -149,13 +150,10 @@ ClientImageLayer::RenderLayer() mImageClient = ImageClient::CreateImageClient(type, ClientManager()->AsShadowForwarder(), flags); - if (type == CompositableType::IMAGE_BRIDGE) { - static_cast(mImageClient.get())->SetLayer(this); - } - if (!mImageClient) { return; } + mImageClient->SetLayer(this); if (HasShadow() && !mContainer->IsAsync()) { mImageClient->Connect(); ClientManager()->AsShadowForwarder()->Attach(mImageClient, this); diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index f3ad29b67a..ad380fe61f 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -610,20 +610,6 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite) break; } - case EditReply::TReturnReleaseFence: { - const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence(); - FenceHandle fence = rep.fence(); - PTextureChild* child = rep.textureChild(); - - if (!fence.IsValid() || !child) { - break; - } - RefPtr texture = TextureClient::AsTextureClient(child); - if (texture) { - texture->SetReleaseFenceHandle(fence); - } - break; - } default: NS_RUNTIMEABORT("not reached"); diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 04688ab75d..1411985bfd 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -34,7 +34,8 @@ class PCompositableChild; */ class RemoveTextureFromCompositableTracker : public AsyncTransactionTracker { public: - RemoveTextureFromCompositableTracker() + explicit RemoveTextureFromCompositableTracker(AsyncTransactionWaiter* aWaiter = nullptr) + : AsyncTransactionTracker(aWaiter) { MOZ_COUNT_CTOR(RemoveTextureFromCompositableTracker); } diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 95f619c234..32985fb963 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -454,20 +454,24 @@ ContentClientDoubleBuffered::Updated(const nsIntRegion& aRegionToDraw, #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 if (mFrontClient) { // remove old buffer from CompositableHost - RefPtr tracker = new RemoveTextureFromCompositableTracker(); + RefPtr waiter = new AsyncTransactionWaiter(); + RefPtr tracker = + new RemoveTextureFromCompositableTracker(waiter); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mFrontClient); - mFrontClient->SetRemoveFromCompositableTracker(tracker); + mFrontClient->SetRemoveFromCompositableWaiter(waiter); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontClient); } if (mFrontClientOnWhite) { // remove old buffer from CompositableHost - RefPtr tracker = new RemoveTextureFromCompositableTracker(); + RefPtr waiter = new AsyncTransactionWaiter(); + RefPtr tracker = + new RemoveTextureFromCompositableTracker(waiter); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mFrontClientOnWhite); - mFrontClientOnWhite->SetRemoveFromCompositableTracker(tracker); + mFrontClientOnWhite->SetRemoveFromCompositableWaiter(waiter); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontClientOnWhite); } diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index 454b3cf716..2da29a38bc 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -74,21 +74,18 @@ ImageClient::CreateImageClient(CompositableType aCompositableHostType, void ImageClient::RemoveTexture(TextureClient* aTexture) { - RemoveTextureWithTracker(aTexture, nullptr); + RemoveTextureWithWaiter(aTexture); } void -ImageClient::RemoveTextureWithTracker(TextureClient* aTexture, - AsyncTransactionTracker* aAsyncTransactionTracker) +ImageClient::RemoveTextureWithWaiter(TextureClient* aTexture, + AsyncTransactionWaiter* aAsyncTransactionWaiter) { #ifdef MOZ_WIDGET_GONK - if (aAsyncTransactionTracker || + if (aAsyncTransactionWaiter || GetForwarder()->IsImageBridgeChild()) { - RefPtr request = aAsyncTransactionTracker; - if (!request) { - // Create AsyncTransactionTracker if it is not provided as argument. - request = new RemoveTextureFromCompositableTracker(); - } + RefPtr request = + new RemoveTextureFromCompositableTracker(aAsyncTransactionWaiter); // Hold TextureClient until the transaction complete to postpone // the TextureClient recycle/delete. request->SetTextureClient(aTexture); @@ -98,11 +95,6 @@ ImageClient::RemoveTextureWithTracker(TextureClient* aTexture, #endif GetForwarder()->RemoveTextureFromCompositable(this, aTexture); - if (aAsyncTransactionTracker) { - // Do not need to wait a transaction complete message - // from the compositor side. - aAsyncTransactionTracker->NotifyComplete(); - } } ImageClientSingle::ImageClientSingle(CompositableForwarder* aFwd, @@ -117,22 +109,13 @@ TextureInfo ImageClientSingle::GetTextureInfo() const return TextureInfo(CompositableType::IMAGE); } -already_AddRefed -ImageClientSingle::PrepareFlushAllImages() -{ - return MakeAndAddRef(); -} - void ImageClientSingle::FlushAllImages(bool aExceptFront, - AsyncTransactionTracker* aAsyncTransactionTracker) + AsyncTransactionWaiter* aAsyncTransactionWaiter) { if (!aExceptFront && mFrontBuffer) { - RemoveTextureWithTracker(mFrontBuffer, aAsyncTransactionTracker); + RemoveTextureWithWaiter(mFrontBuffer, aAsyncTransactionWaiter); mFrontBuffer = nullptr; - } else if(aAsyncTransactionTracker) { - // already flushed - aAsyncTransactionTracker->NotifyComplete(); } } @@ -273,6 +256,7 @@ ImageClientSingle::OnDetach() ImageClient::ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags, CompositableType aType) : CompositableClient(aFwd, aFlags) +, mLayer(nullptr) , mType(aType) , mLastPaintedImageSerial(0) {} @@ -292,7 +276,6 @@ ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd, TextureFlags aFlags) : ImageClient(aFwd, aFlags, CompositableType::IMAGE_BRIDGE) , mAsyncContainerID(0) -, mLayer(nullptr) { } diff --git a/gfx/layers/client/ImageClient.h b/gfx/layers/client/ImageClient.h index 7f0574993d..c3b7c97abf 100644 --- a/gfx/layers/client/ImageClient.h +++ b/gfx/layers/client/ImageClient.h @@ -23,6 +23,7 @@ namespace mozilla { namespace layers { +class ClientLayer; class CompositableForwarder; class AsyncTransactionTracker; class Image; @@ -63,27 +64,26 @@ public: virtual already_AddRefed CreateImage(ImageFormat aFormat) = 0; - /** - * Create AsyncTransactionTracker that is used for FlushAllImagesAsync(). - */ - virtual already_AddRefed PrepareFlushAllImages() { return nullptr; } + void SetLayer(ClientLayer* aLayer) { mLayer = aLayer; } + ClientLayer* GetLayer() const { return mLayer; } /** * asynchronously remove all the textures used by the image client. * */ virtual void FlushAllImages(bool aExceptFront, - AsyncTransactionTracker* aAsyncTransactionTracker) {} + AsyncTransactionWaiter* aAsyncTransactionWaiter) {} virtual void RemoveTexture(TextureClient* aTexture) override; - void RemoveTextureWithTracker(TextureClient* aTexture, - AsyncTransactionTracker* aAsyncTransactionTracker = nullptr); + void RemoveTextureWithWaiter(TextureClient* aTexture, + AsyncTransactionWaiter* aAsyncTransactionWaiter = nullptr); protected: ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags, CompositableType aType); + ClientLayer* mLayer; CompositableType mType; int32_t mLastPaintedImageSerial; gfx::IntRect mPictureRect; @@ -109,10 +109,8 @@ public: virtual already_AddRefed CreateImage(ImageFormat aFormat) override; - virtual already_AddRefed PrepareFlushAllImages() override; - virtual void FlushAllImages(bool aExceptFront, - AsyncTransactionTracker* aAsyncTransactionTracker) override; + AsyncTransactionWaiter* aAsyncTransactionWaiter) override; protected: RefPtr mFrontBuffer; @@ -132,10 +130,6 @@ public: virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) override; virtual bool Connect() override { return false; } virtual void Updated() {} - void SetLayer(ShadowableLayer* aLayer) - { - mLayer = aLayer; - } virtual TextureInfo GetTextureInfo() const override { @@ -155,7 +149,6 @@ public: protected: uint64_t mAsyncContainerID; - ShadowableLayer* mLayer; }; #ifdef MOZ_WIDGET_GONK diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index a34e6daff8..181db41235 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -40,7 +40,7 @@ namespace mozilla { namespace layers { -class AsyncTransactionTracker; +class AsyncTransactionWaiter; class CompositableForwarder; class ISurfaceAllocator; class CompositableClient; @@ -448,7 +448,7 @@ public: /** * Set AsyncTransactionTracker of RemoveTextureFromCompositableAsync() transaction. */ - virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) {} + virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) {} /** * This function waits until the buffer is no longer being used. diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 544b00f499..d24a6a95d0 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -561,10 +561,12 @@ TileClient::Flip() if (mFrontBuffer && mFrontBuffer->GetIPDLActor() && mCompositableClient && mCompositableClient->GetIPDLActor()) { // remove old buffer from CompositableHost - RefPtr tracker = new RemoveTextureFromCompositableTracker(); + RefPtr waiter = new AsyncTransactionWaiter(); + RefPtr tracker = + new RemoveTextureFromCompositableTracker(waiter); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mFrontBuffer); - mFrontBuffer->SetRemoveFromCompositableTracker(tracker); + mFrontBuffer->SetRemoveFromCompositableWaiter(waiter); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. mManager->AsShadowForwarder()->RemoveTextureFromCompositableAsync(tracker, mCompositableClient, @@ -659,10 +661,12 @@ TileClient::DiscardFrontBuffer() if (mFrontBuffer->GetIPDLActor() && mCompositableClient && mCompositableClient->GetIPDLActor()) { // remove old buffer from CompositableHost - RefPtr tracker = new RemoveTextureFromCompositableTracker(); + RefPtr waiter = new AsyncTransactionWaiter(); + RefPtr tracker = + new RemoveTextureFromCompositableTracker(waiter); // Hold TextureClient until transaction complete. tracker->SetTextureClient(mFrontBuffer); - mFrontBuffer->SetRemoveFromCompositableTracker(tracker); + mFrontBuffer->SetRemoveFromCompositableWaiter(waiter); // RemoveTextureFromCompositableAsync() expects CompositorChild's presence. mManager->AsShadowForwarder()->RemoveTextureFromCompositableAsync(tracker, mCompositableClient, diff --git a/gfx/layers/composite/FrameUniformityData.cpp b/gfx/layers/composite/FrameUniformityData.cpp index eb2c3db789..6027a14706 100644 --- a/gfx/layers/composite/FrameUniformityData.cpp +++ b/gfx/layers/composite/FrameUniformityData.cpp @@ -137,7 +137,8 @@ FrameUniformityData::ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext) uintptr_t layerAddr = iter->first; float uniformity = iter->second; - layers.AppendElement(); + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(layers.AppendElement(fallible)); dom::FrameUniformity& entry = layers.LastElement(); entry.mLayerAddress.Construct() = layerAddr; diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 6fe9886d60..0b2148c218 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -268,6 +268,8 @@ LayerManagerComposite::EndTransaction(DrawPaintedLayerCallback aCallback, { NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?"); NS_ASSERTION(!aCallback && !aCallbackData, "Not expecting callbacks here"); + NS_ASSERTION(!(aFlags & END_NO_COMPOSITE), + "Shouldn't get END_NO_COMPOSITE here"); mInTransaction = false; if (!mIsCompositorReady) { @@ -297,12 +299,6 @@ LayerManagerComposite::EndTransaction(DrawPaintedLayerCallback aCallback, } if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) { - if (aFlags & END_NO_COMPOSITE) { - // Apply pending tree updates before recomputing effective - // properties. - mRoot->ApplyPendingUpdatesToSubtree(); - } - // The results of our drawing always go directly into a pixel buffer, // so we don't need to pass any global transform here. mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4()); diff --git a/gfx/layers/ipc/AsyncTransactionTracker.cpp b/gfx/layers/ipc/AsyncTransactionTracker.cpp index 55fd309858..9cb8fd5296 100755 --- a/gfx/layers/ipc/AsyncTransactionTracker.cpp +++ b/gfx/layers/ipc/AsyncTransactionTracker.cpp @@ -12,29 +12,15 @@ namespace mozilla { namespace layers { -uint64_t AsyncTransactionTracker::sSerialCounter(0); -Mutex* AsyncTransactionTracker::sLock = nullptr; - -AsyncTransactionTracker::AsyncTransactionTracker() - : mSerial(GetNextSerial()) - , mCompletedMonitor("AsyncTransactionTracker.mCompleted") - , mCompleted(false) -{ -} - -AsyncTransactionTracker::~AsyncTransactionTracker() -{ -} - void -AsyncTransactionTracker::WaitComplete() +AsyncTransactionWaiter::WaitComplete() { MOZ_ASSERT(!InImageBridgeChildThread()); MonitorAutoLock mon(mCompletedMonitor); int count = 0; const int maxCount = 5; - while (!mCompleted && (count < maxCount)) { + while (mWaitCount > 0 && (count < maxCount)) { if (!NS_SUCCEEDED(mCompletedMonitor.Wait(PR_MillisecondsToInterval(10000)))) { NS_WARNING("Failed to wait Monitor"); return; @@ -45,29 +31,48 @@ AsyncTransactionTracker::WaitComplete() count++; } - if (!mCompleted) { + if (mWaitCount > 0) { printf_stderr("Timeout of waiting transaction complete."); } } +uint64_t AsyncTransactionTracker::sSerialCounter(0); +Mutex* AsyncTransactionTracker::sLock = nullptr; + +AsyncTransactionTracker::AsyncTransactionTracker(AsyncTransactionWaiter* aWaiter) + : mSerial(GetNextSerial()) + , mWaiter(aWaiter) + , mCompleted(false) +{ + if (mWaiter) { + mWaiter->IncrementWaitCount(); + } +} + +AsyncTransactionTracker::~AsyncTransactionTracker() +{ +} + void AsyncTransactionTracker::NotifyComplete() { - MonitorAutoLock mon(mCompletedMonitor); MOZ_ASSERT(!mCompleted); mCompleted = true; Complete(); - mCompletedMonitor.Notify(); + if (mWaiter) { + mWaiter->DecrementWaitCount(); + } } void AsyncTransactionTracker::NotifyCancel() { - MonitorAutoLock mon(mCompletedMonitor); MOZ_ASSERT(!mCompleted); mCompleted = true; Cancel(); - mCompletedMonitor.Notify(); + if (mWaiter) { + mWaiter->DecrementWaitCount(); + } } uint64_t AsyncTransactionTrackersHolder::sSerialCounter(0); @@ -119,7 +124,7 @@ AsyncTransactionTrackersHolder::HoldUntilComplete(AsyncTransactionTracker* aTran if (aTransactionTracker) { MutexAutoLock lock(*sHolderLock); - mAsyncTransactionTrackeres[aTransactionTracker->GetId()] = aTransactionTracker; + mAsyncTransactionTrackers[aTransactionTracker->GetId()] = aTransactionTracker; } } @@ -134,10 +139,10 @@ void AsyncTransactionTrackersHolder::TransactionCompletetedInternal(uint64_t aTransactionId) { std::map >::iterator it - = mAsyncTransactionTrackeres.find(aTransactionId); - if (it != mAsyncTransactionTrackeres.end()) { + = mAsyncTransactionTrackers.find(aTransactionId); + if (it != mAsyncTransactionTrackers.end()) { it->second->NotifyComplete(); - mAsyncTransactionTrackeres.erase(it); + mAsyncTransactionTrackers.erase(it); } } @@ -146,8 +151,8 @@ AsyncTransactionTrackersHolder::SetReleaseFenceHandle(FenceHandle& aReleaseFence uint64_t aTransactionId) { std::map >::iterator it - = mAsyncTransactionTrackeres.find(aTransactionId); - if (it != mAsyncTransactionTrackeres.end()) { + = mAsyncTransactionTrackers.find(aTransactionId); + if (it != mAsyncTransactionTrackers.end()) { it->second->SetReleaseFenceHandle(aReleaseFenceHandle); } } @@ -183,11 +188,11 @@ AsyncTransactionTrackersHolder::ClearAllAsyncTransactionTrackers() sHolderLock->Lock(); } std::map >::iterator it; - for (it = mAsyncTransactionTrackeres.begin(); - it != mAsyncTransactionTrackeres.end(); it++) { + for (it = mAsyncTransactionTrackers.begin(); + it != mAsyncTransactionTrackers.end(); it++) { it->second->NotifyCancel(); } - mAsyncTransactionTrackeres.clear(); + mAsyncTransactionTrackers.clear(); if (sHolderLock) { sHolderLock->Unlock(); } diff --git a/gfx/layers/ipc/AsyncTransactionTracker.h b/gfx/layers/ipc/AsyncTransactionTracker.h index 0bb976d48c..67ce861776 100644 --- a/gfx/layers/ipc/AsyncTransactionTracker.h +++ b/gfx/layers/ipc/AsyncTransactionTracker.h @@ -21,6 +21,46 @@ namespace layers { class TextureClient; class AsyncTransactionTrackersHolder; +/** + * Object that lets you wait for one or more async transactions to complete. + */ +class AsyncTransactionWaiter +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncTransactionWaiter) + + AsyncTransactionWaiter() + : mCompletedMonitor("AsyncTransactionWaiter") + , mWaitCount(0) + {} + + void IncrementWaitCount() + { + MonitorAutoLock lock(mCompletedMonitor); + ++mWaitCount; + } + void DecrementWaitCount() + { + MonitorAutoLock lock(mCompletedMonitor); + MOZ_ASSERT(mWaitCount > 0); + --mWaitCount; + if (mWaitCount == 0) { + mCompletedMonitor.Notify(); + } + } + + /** + * Wait until asynchronous transactions complete. + */ + void WaitComplete(); + +private: + ~AsyncTransactionWaiter() {} + + Monitor mCompletedMonitor; + uint32_t mWaitCount; +}; + /** * AsyncTransactionTracker tracks asynchronous transaction. * It is typically used for asynchronous layer transaction handling. @@ -31,17 +71,7 @@ class AsyncTransactionTracker public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncTransactionTracker) - AsyncTransactionTracker(); - - Monitor& GetReentrantMonitor() - { - return mCompletedMonitor; - } - - /** - * Wait until asynchronous transaction complete. - */ - void WaitComplete(); + explicit AsyncTransactionTracker(AsyncTransactionWaiter* aWaiter = nullptr); /** * Notify async transaction complete. @@ -100,8 +130,8 @@ protected: } uint64_t mSerial; - Monitor mCompletedMonitor; - bool mCompleted; + RefPtr mWaiter; + DebugOnly mCompleted; /** * gecko does not provide atomic operation for uint64_t. @@ -170,7 +200,7 @@ protected: uint64_t mSerial; bool mIsTrackersHolderDestroyed; - std::map > mAsyncTransactionTrackeres; + std::map > mAsyncTransactionTrackers; /** * gecko does not provide atomic operation for uint64_t. diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 38cd10b766..9f45e59673 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -844,6 +844,15 @@ CompositorParent::RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) return true; } +void +CompositorParent::Invalidate() +{ + if (mLayerManager && mLayerManager->GetRoot()) { + mLayerManager->AddInvalidRegion( + mLayerManager->GetRoot()->GetVisibleRegion().GetBounds()); + } +} + bool CompositorParent::RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) { @@ -897,6 +906,14 @@ CompositorParent::ScheduleRenderOnCompositorThread() CompositorLoop()->PostTask(FROM_HERE, renderTask); } +void +CompositorParent::InvalidateOnCompositorThread() +{ + CancelableTask *renderTask = NewRunnableMethod(this, &CompositorParent::Invalidate); + MOZ_ASSERT(CompositorLoop()); + CompositorLoop()->PostTask(FROM_HERE, renderTask); +} + void CompositorParent::PauseComposition() { diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 626cc7d367..ef6bf5d18e 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -297,6 +297,7 @@ public: // Can be called from any thread void ScheduleRenderOnCompositorThread(); void SchedulePauseOnCompositorThread(); + void InvalidateOnCompositorThread(); /** * Returns true if a surface was obtained and the resume succeeded; false * otherwise. @@ -451,6 +452,7 @@ protected: void ResumeCompositionAndResize(int width, int height); void ForceComposition(); void CancelCurrentCompositeTask(); + void Invalidate(); /** * Add a compositor to the global compositor map. diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 1b1f8aa32d..8b0b8b6b9e 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -407,20 +407,27 @@ void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient, nsRefPtr >(&UpdateImageClientNow, aClient, aContainer)); } -static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront, AsyncTransactionTracker* aStatus) +static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer, + bool aExceptFront, AsyncTransactionWaiter* aWaiter) { MOZ_ASSERT(aClient); sImageBridgeChildSingleton->BeginTransaction(); if (aContainer && !aExceptFront) { aContainer->ClearCurrentImage(); } - aClient->FlushAllImages(aExceptFront, aStatus); + aClient->FlushAllImages(aExceptFront, aWaiter); aClient->OnTransaction(); sImageBridgeChildSingleton->EndTransaction(); + // This decrement is balanced by the increment in FlushAllImages. + // If any AsyncTransactionTrackers were created by FlushAllImages and attached + // to aWaiter, aWaiter will not complete until those trackers all complete. + // Otherwise, aWaiter will be ready to complete now. + aWaiter->DecrementWaitCount(); } //static -void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront) +void ImageBridgeChild::FlushAllImages(ImageClient* aClient, + ImageContainer* aContainer, bool aExceptFront) { if (!IsCreated()) { return; @@ -430,16 +437,18 @@ void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aCon MOZ_ASSERT(!InImageBridgeChildThread()); if (InImageBridgeChildThread()) { NS_ERROR("ImageBridgeChild::FlushAllImages() is called on ImageBridge thread."); - return; - } + return; + } - RefPtr status = aClient->PrepareFlushAllImages(); + RefPtr waiter = new AsyncTransactionWaiter(); + // This increment is balanced by the decrement in FlushAllImagesSync + waiter->IncrementWaitCount(); sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, - NewRunnableFunction(&FlushAllImagesSync, aClient, aContainer, aExceptFront, status)); + NewRunnableFunction(&FlushAllImagesSync, aClient, aContainer, aExceptFront, waiter)); - status->WaitComplete(); + waiter->WaitComplete(); } void @@ -450,13 +459,13 @@ ImageBridgeChild::BeginTransaction() mTxn->Begin(); } -class MOZ_STACK_CLASS AutoRemoveTextures +class MOZ_STACK_CLASS AutoRemoveTexturesFromImageBridge { public: - explicit AutoRemoveTextures(ImageBridgeChild* aImageBridge) + explicit AutoRemoveTexturesFromImageBridge(ImageBridgeChild* aImageBridge) : mImageBridge(aImageBridge) {} - ~AutoRemoveTextures() + ~AutoRemoveTexturesFromImageBridge() { mImageBridge->RemoveTexturesIfNecessary(); } @@ -471,7 +480,7 @@ ImageBridgeChild::EndTransaction() MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?"); AutoEndTransaction _(mTxn); - AutoRemoveTextures autoRemoveTextures(this); + AutoRemoveTexturesFromImageBridge autoRemoveTextures(this); if (mTxn->IsEmpty()) { return; @@ -503,25 +512,7 @@ ImageBridgeChild::EndTransaction() } } for (nsTArray::size_type i = 0; i < replies.Length(); ++i) { - const EditReply& reply = replies[i]; - switch (reply.type()) { - case EditReply::TReturnReleaseFence: { - const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence(); - FenceHandle fence = rep.fence(); - PTextureChild* child = rep.textureChild(); - - if (!fence.IsValid() || !child) { - break; - } - RefPtr texture = TextureClient::AsTextureClient(child); - if (texture) { - texture->SetReleaseFenceHandle(fence); - } - break; - } - default: - NS_RUNTIMEABORT("not reached"); - } + NS_RUNTIMEABORT("not reached"); } SendPendingAsyncMessges(); } diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 7ae0d911bf..92260bcbd0 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -466,18 +466,10 @@ struct OpContentBufferSwap { nsIntRegion frontUpdatedRegion; }; -struct ReturnReleaseFence { - PCompositable compositable; - PTexture texture; - FenceHandle fence; -}; - // Unit of a "changeset reply". This is a weird abstraction, probably // only to be used for buffer swapping. union EditReply { OpContentBufferSwap; - - ReturnReleaseFence; }; union AsyncParentMessageData { diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 3256aa6fc9..b9e676d574 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -211,13 +211,6 @@ public: virtual void UseTiledLayerBuffer(CompositableClient* aCompositable, const SurfaceDescriptorTiles& aTileLayerDescriptor) override; - /** - * Notify the compositor that a compositable will be updated asynchronously - * through ImageBridge, using an ID to connect the protocols on the - * compositor side. - */ - void AttachAsyncCompositable(PLayerTransactionChild* aLayer, uint64_t aID); - virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, TextureClient* aTexture) override; diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 20a7e6db34..4b141e34a4 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -314,6 +314,7 @@ UNIFIED_SOURCES += [ 'LayerScope.cpp', 'LayersLogging.cpp', 'LayerSorter.cpp', + 'LayersTypes.cpp', 'opengl/CompositingRenderTargetOGL.cpp', 'opengl/CompositorOGL.cpp', 'opengl/CompositorOGLVR.cpp', diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 6a2af2f27e..d4dd8401a6 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -171,6 +171,14 @@ CompositorOGL::CleanupResources() ctx = mGLContext; } + if (!ctx->MakeCurrent()) { + // Leak resources! + mQuadVBO = 0; + mGLContext = nullptr; + mPrograms.clear(); + return; + } + for (std::map::iterator iter = mPrograms.begin(); iter != mPrograms.end(); iter++) { @@ -178,12 +186,6 @@ CompositorOGL::CleanupResources() } mPrograms.clear(); - if (!ctx->MakeCurrent()) { - mQuadVBO = 0; - mGLContext = nullptr; - return; - } - ctx->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0); if (mQuadVBO) { diff --git a/gfx/layers/opengl/GrallocTextureClient.cpp b/gfx/layers/opengl/GrallocTextureClient.cpp index 0b8776c81e..e45827655d 100644 --- a/gfx/layers/opengl/GrallocTextureClient.cpp +++ b/gfx/layers/opengl/GrallocTextureClient.cpp @@ -72,17 +72,17 @@ GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) } void -GrallocTextureClientOGL::SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) +GrallocTextureClientOGL::SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) { - mRemoveFromCompositableTracker = aTracker; + mRemoveFromCompositableWaiter = aWaiter; } void GrallocTextureClientOGL::WaitForBufferOwnership(bool aWaitReleaseFence) { - if (mRemoveFromCompositableTracker) { - mRemoveFromCompositableTracker->WaitComplete(); - mRemoveFromCompositableTracker = nullptr; + if (mRemoveFromCompositableWaiter) { + mRemoveFromCompositableWaiter->WaitComplete(); + mRemoveFromCompositableWaiter = nullptr; } if (!aWaitReleaseFence) { diff --git a/gfx/layers/opengl/GrallocTextureClient.h b/gfx/layers/opengl/GrallocTextureClient.h index ea9379f496..71d4defd40 100644 --- a/gfx/layers/opengl/GrallocTextureClient.h +++ b/gfx/layers/opengl/GrallocTextureClient.h @@ -60,7 +60,7 @@ public: virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override; - virtual void SetRemoveFromCompositableTracker(AsyncTransactionTracker* aTracker) override; + virtual void SetRemoveFromCompositableWaiter(AsyncTransactionWaiter* aWaiter) override; virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override; @@ -127,7 +127,7 @@ protected: */ MaybeMagicGrallocBufferHandle mGrallocHandle; - RefPtr mRemoveFromCompositableTracker; + RefPtr mRemoveFromCompositableWaiter; android::sp mGraphicBuffer; diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index f1bdc9a008..b2dcb87dad 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -311,7 +311,7 @@ gfxDWriteFontFamily::LocalizedName(nsAString &aLocalizedName) return; } - if (!famName.SetLength(length + 1)) { + if (!famName.SetLength(length + 1, fallible)) { // Eeep - running out of memory. Unlikely to end well. return; } @@ -400,7 +400,7 @@ gfxDWriteFontEntry::CopyFontTable(uint32_t aTableTag, uint32_t tableSize = ::GetFontData(dc.GetDC(), tagBE, 0, nullptr, 0); if (tableSize != GDI_ERROR) { - if (aBuffer.SetLength(tableSize)) { + if (aBuffer.SetLength(tableSize, fallible)) { ::GetFontData(dc.GetDC(), tagBE, 0, aBuffer.Elements(), aBuffer.Length()); return NS_OK; @@ -428,7 +428,7 @@ gfxDWriteFontEntry::CopyFontTable(uint32_t aTableTag, return NS_ERROR_FAILURE; } - if (aBuffer.SetLength(len)) { + if (aBuffer.SetLength(len, fallible)) { memcpy(aBuffer.Elements(), tableData, len); rv = NS_OK; } else { @@ -1117,7 +1117,7 @@ gfxDWriteFontList::GetFontsFromCollection(IDWriteFontCollection* aCollection) continue; } - if (!enName.SetLength(length + 1)) { + if (!enName.SetLength(length + 1, fallible)) { // Eeep - running out of memory. Unlikely to end well. continue; } @@ -1166,7 +1166,7 @@ gfxDWriteFontList::GetFontsFromCollection(IDWriteFontCollection* aCollection) continue; } - if (!localizedName.SetLength(nameLen + 1)) { + if (!localizedName.SetLength(nameLen + 1, fallible)) { continue; } @@ -1401,7 +1401,7 @@ static HRESULT GetFamilyName(IDWriteFont *aFont, nsString& aFamilyName) return hr; } - if (!name.SetLength(length + 1)) { + if (!name.SetLength(length + 1, fallible)) { return E_FAIL; } hr = familyNames->GetString(index, name.Elements(), length + 1); @@ -1582,7 +1582,7 @@ DirectWriteFontInfo::LoadFontFamilyData(const nsAString& aFamilyName) nsAutoTArray famName; uint32_t len = aFamilyName.Length(); - famName.SetLength(len + 1); + famName.SetLength(len + 1, fallible); memcpy(famName.Elements(), aFamilyName.BeginReading(), len * sizeof(char16_t)); famName[len] = 0; diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index c51df43cbb..61f3829b5d 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -532,7 +532,7 @@ FT2FontEntry::CopyFontTable(uint32_t aTableTag, return NS_ERROR_FAILURE; } - if (!aBuffer.SetLength(len)) { + if (!aBuffer.SetLength(len, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } uint8_t *buf = aBuffer.Elements(); diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index fc349b8154..4b3987f280 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -489,7 +489,7 @@ PrepareFontOptions(FcPattern* aPattern, { NS_ASSERTION(aFontOptions, "null font options passed to PrepareFontOptions"); - // xxx - taken from the gfxPangoFonts code, needs to be reviewed + // xxx - taken from the gfxFontconfigFonts code, needs to be reviewed FcBool printing; if (FcPatternGetBool(aPattern, PRINTING_FC_PROPERTY, 0, &printing) != @@ -801,7 +801,7 @@ gfxFontconfigFontEntry::CopyFontTable(uint32_t aTableTag, if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nullptr, &length) != 0) { return NS_ERROR_NOT_AVAILABLE; } - if (!aBuffer.SetLength(length)) { + if (!aBuffer.SetLength(length, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, aBuffer.Elements(), &length) != 0) { diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 722172ad24..92f2bdbe8d 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1845,7 +1845,7 @@ protected: // (and with variantCaps set to normal). // Default implementation relies on gfxFontEntry::CreateFontInstance; // backends that don't implement that will need to override this and use - // an alternative technique. (gfxPangoFonts, I'm looking at you...) + // an alternative technique. (gfxFontconfigFonts, I'm looking at you...) virtual already_AddRefed GetSmallCapsFont(); // subclasses may provide (possibly hinted) glyph widths (in font units); diff --git a/gfx/thebes/gfxPangoFonts.cpp b/gfx/thebes/gfxFontconfigFonts.cpp similarity index 99% rename from gfx/thebes/gfxPangoFonts.cpp rename to gfx/thebes/gfxFontconfigFonts.cpp index c68a6d7a16..5ea65e534c 100644 --- a/gfx/thebes/gfxPangoFonts.cpp +++ b/gfx/thebes/gfxFontconfigFonts.cpp @@ -15,7 +15,7 @@ #ifdef MOZ_WIDGET_QT #include "gfxQtPlatform.h" #endif -#include "gfxPangoFonts.h" +#include "gfxFontconfigFonts.h" #include "gfxFT2FontBase.h" #include "gfxFT2Utils.h" #include "harfbuzz/hb.h" @@ -184,9 +184,11 @@ public: { cairo_font_face_reference(mFontFace); cairo_font_face_set_user_data(mFontFace, &sFontEntryKey, this, nullptr); - mPatterns.AppendElement(); + // mPatterns is an nsAutoTArray with 1 space always available, so the // AppendElement always succeeds. + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible)); mPatterns[0] = aFontPattern; FcChar8 *name; @@ -248,7 +250,7 @@ gfxSystemFcFontEntry::CopyFontTable(uint32_t aTableTag, if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nullptr, &length) != 0) { return NS_ERROR_NOT_AVAILABLE; } - if (!aBuffer.SetLength(length)) { + if (!aBuffer.SetLength(length, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } if (FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, aBuffer.Elements(), &length) != 0) { @@ -419,7 +421,7 @@ public: const nsTArray< nsCountedRef >& aPatterns) : gfxUserFcFontEntry(aFontName, aWeight, aStretch, aItalic) { - if (!mPatterns.SetCapacity(aPatterns.Length())) + if (!mPatterns.SetCapacity(aPatterns.Length(), fallible)) return; // OOM for (uint32_t i = 0; i < aPatterns.Length(); ++i) { @@ -429,7 +431,8 @@ public: AdjustPatternToCSS(pattern); - mPatterns.AppendElement(); + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible)); mPatterns[i].own(pattern); } mIsLocalUserFont = true; @@ -617,7 +620,8 @@ gfxDownloadedFcFontEntry::InitPattern() AddDownloadedFontEntry(pattern, this); // There is never more than one pattern - mPatterns.AppendElement(); + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(mPatterns.AppendElement(fallible)); mPatterns[0].own(pattern); } diff --git a/gfx/thebes/gfxPangoFonts.h b/gfx/thebes/gfxFontconfigFonts.h similarity index 97% rename from gfx/thebes/gfxPangoFonts.h rename to gfx/thebes/gfxFontconfigFonts.h index d14bd6d3ab..44d9a7c248 100644 --- a/gfx/thebes/gfxPangoFonts.h +++ b/gfx/thebes/gfxFontconfigFonts.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef GFX_PANGOFONTS_H -#define GFX_PANGOFONTS_H +#ifndef GFX_FONTCONFIG_FONTS_H +#define GFX_FONTCONFIG_FONTS_H #include "cairo.h" #include "gfxTypes.h" @@ -102,4 +102,4 @@ private: static FT_Library GetFTLibrary(); }; -#endif /* GFX_PANGOFONTS_H */ +#endif /* GFX_FONTCONFIG_FONTS_H */ diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index ff94535a85..1509748e8f 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -245,7 +245,7 @@ GDIFontEntry::CopyFontTable(uint32_t aTableTag, NativeEndian::swapToBigEndian(aTableTag), 0, nullptr, 0); if (tableSize != GDI_ERROR) { - if (aBuffer.SetLength(tableSize)) { + if (aBuffer.SetLength(tableSize, fallible)) { ::GetFontData(dc.GetDC(), NativeEndian::swapToBigEndian(aTableTag), 0, aBuffer.Elements(), tableSize); @@ -1039,7 +1039,7 @@ int CALLBACK GDIFontInfo::EnumerateFontsForFamily( nameSize = ::GetFontData(hdc, kNAME, 0, nullptr, 0); if (nameSize != GDI_ERROR && nameSize > 0 && - nameData.SetLength(nameSize)) { + nameData.SetLength(nameSize, fallible)) { ::GetFontData(hdc, kNAME, 0, nameData.Elements(), nameSize); // face names @@ -1082,7 +1082,7 @@ int CALLBACK GDIFontInfo::EnumerateFontsForFamily( cmapSize = ::GetFontData(hdc, kCMAP, 0, nullptr, 0); if (cmapSize != GDI_ERROR && cmapSize > 0 && - cmapData.SetLength(cmapSize)) { + cmapData.SetLength(cmapSize, fallible)) { ::GetFontData(hdc, kCMAP, 0, cmapData.Elements(), cmapSize); bool cmapLoaded = false; bool unicodeFont = false, symbolFont = false; diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 61f2bdccc2..bda072ff18 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -14,7 +14,7 @@ #include "gfx2DGlue.h" #include "gfxFcPlatformFontList.h" #include "gfxFontconfigUtils.h" -#include "gfxPangoFonts.h" +#include "gfxFontconfigFonts.h" #include "gfxContext.h" #include "gfxUserFontSet.h" #include "gfxUtils.h" diff --git a/gfx/thebes/gfxQtPlatform.cpp b/gfx/thebes/gfxQtPlatform.cpp index 2ad787ca27..5691f70aae 100644 --- a/gfx/thebes/gfxQtPlatform.cpp +++ b/gfx/thebes/gfxQtPlatform.cpp @@ -23,7 +23,7 @@ #include "gfxQPainterSurface.h" #include "nsUnicodeProperties.h" -#include "gfxPangoFonts.h" +#include "gfxFontconfigFonts.h" #include "gfxContext.h" #include "gfxUserFontSet.h" diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build index c7593327cf..fbf3e40b74 100644 --- a/gfx/thebes/moz.build +++ b/gfx/thebes/moz.build @@ -101,9 +101,9 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': ] elif CONFIG['MOZ_WIDGET_GTK']: EXPORTS += [ + 'gfxFontconfigFonts.h', 'gfxFT2FontBase.h', 'gfxGdkNativeRenderer.h', - 'gfxPangoFonts.h', 'gfxPDFSurface.h', 'gfxPlatformGtk.h', 'gfxPSSurface.h', @@ -111,11 +111,11 @@ elif CONFIG['MOZ_WIDGET_GTK']: SOURCES += [ 'gfxFcPlatformFontList.cpp', + 'gfxFontconfigFonts.cpp', 'gfxFontconfigUtils.cpp', 'gfxFT2FontBase.cpp', 'gfxFT2Utils.cpp', 'gfxGdkNativeRenderer.cpp', - 'gfxPangoFonts.cpp', 'gfxPDFSurface.cpp', 'gfxPlatformGtk.cpp', 'gfxPSSurface.cpp', @@ -133,18 +133,18 @@ elif CONFIG['MOZ_WIDGET_GTK']: elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt': EXPORTS += [ + 'gfxFontconfigFonts.h', 'gfxFT2FontBase.h', - 'gfxPangoFonts.h', 'gfxPDFSurface.h', 'gfxQPainterSurface.h', 'gfxQtNativeRenderer.h', 'gfxQtPlatform.h', ] SOURCES += [ + 'gfxFontconfigFonts.cpp', 'gfxFontconfigUtils.cpp', 'gfxFT2FontBase.cpp', 'gfxFT2Utils.cpp', - 'gfxPangoFonts.cpp', 'gfxPDFSurface.cpp', 'gfxQPainterSurface.cpp', 'gfxQtPlatform.cpp', diff --git a/image/SourceBuffer.cpp b/image/SourceBuffer.cpp index 6f250e23bc..f5c875e395 100644 --- a/image/SourceBuffer.cpp +++ b/image/SourceBuffer.cpp @@ -78,7 +78,7 @@ SourceBuffer::AppendChunk(Maybe&& aChunk) return NS_ERROR_OUT_OF_MEMORY; } - if (MOZ_UNLIKELY(!mChunks.AppendElement(Move(*aChunk)))) { + if (MOZ_UNLIKELY(!mChunks.AppendElement(Move(*aChunk), fallible))) { return NS_ERROR_OUT_OF_MEMORY; } diff --git a/intl/lwbrk/nsPangoBreaker.cpp b/intl/lwbrk/nsPangoBreaker.cpp index e54ba443be..8d5104c42d 100644 --- a/intl/lwbrk/nsPangoBreaker.cpp +++ b/intl/lwbrk/nsPangoBreaker.cpp @@ -50,7 +50,7 @@ NS_GetComplexLineBreaks(const char16_t* aText, uint32_t aLength, // pango_break (pango 1.16.2) only analyses text before the // first NUL (but sets one extra attr). Workaround loop to call // pango_break again to analyse after the NUL is done somewhere else - // (gfx/thebes/gfxPangoFonts.cpp: SetupClusterBoundaries()). + // (gfx/thebes/gfxFontconfigFonts.cpp: SetupClusterBoundaries()). // So, we do the same here for pango_get_log_attrs. break; } diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 4dd79ccbd1..cf4858b384 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -526,7 +526,7 @@ struct ParamTraits > } for (uint32_t index = 0; index < length; index++) { - E* element = aResult->AppendElement(); + E* element = aResult->AppendElement(mozilla::fallible); MOZ_ASSERT(element); if (!ReadParam(aMsg, aIter, element)) { return false; diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 3e9a19855f..481a05d6a0 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -5397,7 +5397,7 @@ public: rect.mY = iterRect->Y(); rect.mWidth = iterRect->Width(); rect.mHeight = iterRect->Height(); - aRectangles.AppendElement(rect); + aRectangles.AppendElement(rect, fallible); } } diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index a5b7c99a21..415900b2a6 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -1015,25 +1015,25 @@ GetSelectionStates(int16_t aReason) { dom::Sequence states; if (aReason & nsISelectionListener::DRAG_REASON) { - states.AppendElement(SelectionState::Drag); + states.AppendElement(SelectionState::Drag, fallible); } if (aReason & nsISelectionListener::MOUSEDOWN_REASON) { - states.AppendElement(SelectionState::Mousedown); + states.AppendElement(SelectionState::Mousedown, fallible); } if (aReason & nsISelectionListener::MOUSEUP_REASON) { - states.AppendElement(SelectionState::Mouseup); + states.AppendElement(SelectionState::Mouseup, fallible); } if (aReason & nsISelectionListener::KEYPRESS_REASON) { - states.AppendElement(SelectionState::Keypress); + states.AppendElement(SelectionState::Keypress, fallible); } if (aReason & nsISelectionListener::SELECTALL_REASON) { - states.AppendElement(SelectionState::Selectall); + states.AppendElement(SelectionState::Selectall, fallible); } if (aReason & nsISelectionListener::COLLAPSETOSTART_REASON) { - states.AppendElement(SelectionState::Collapsetostart); + states.AppendElement(SelectionState::Collapsetostart, fallible); } if (aReason & nsISelectionListener::COLLAPSETOEND_REASON) { - states.AppendElement(SelectionState::Collapsetoend); + states.AppendElement(SelectionState::Collapsetoend, fallible); } return states; } @@ -1058,7 +1058,7 @@ SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection, SelectionState aState) { dom::Sequence state; - state.AppendElement(aState); + state.AppendElement(aState, fallible); DispatchSelectionStateChangedEvent(aSelection, state); } diff --git a/layout/base/TouchCaret.cpp b/layout/base/TouchCaret.cpp index bfcc1c788f..69ce98e860 100644 --- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -1151,7 +1151,7 @@ TouchCaret::DispatchTapEvent() sel->Stringify(init.mSelectedText); dom::Sequence state; - state.AppendElement(dom::SelectionState::Taponcaret); + state.AppendElement(dom::SelectionState::Taponcaret, fallible); init.mStates = state; nsRefPtr event = diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 8a2e87c856..9d5dd342d1 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1961,7 +1961,7 @@ nsPresContext::MediaFeatureValuesChanged(nsRestyleHint aRestyleHint, // Note that we intentionally send the notifications to media query // list in the order they were created and, for each list, to the // listeners in the order added. - MediaQueryList::NotifyList notifyList; + nsTArray notifyList; for (PRCList *l = PR_LIST_HEAD(mDocument->MediaQueryLists()); l != mDocument->MediaQueryLists(); l = PR_NEXT_LINK(l)) { MediaQueryList *mql = static_cast(l); diff --git a/layout/style/MediaQueryList.cpp b/layout/style/MediaQueryList.cpp index 4f6f0f6ba5..069e049c46 100644 --- a/layout/style/MediaQueryList.cpp +++ b/layout/style/MediaQueryList.cpp @@ -103,10 +103,11 @@ MediaQueryList::AddListener(MediaQueryListListener& aListener) } } - mCallbacks.AppendElement(&aListener); - if (!HasListeners()) { - // Append failed; undo the AddRef above. - NS_RELEASE_THIS(); + if (!mCallbacks.AppendElement(&aListener, fallible)) { + if (!HasListeners()) { + // Append failed; undo the AddRef above. + NS_RELEASE_THIS(); + } } } @@ -170,7 +171,8 @@ MediaQueryList::RecomputeMatches() } void -MediaQueryList::MediumFeaturesChanged(NotifyList &aListenersToNotify) +MediaQueryList::MediumFeaturesChanged( + nsTArray& aListenersToNotify) { mMatchesValid = false; @@ -179,7 +181,7 @@ MediaQueryList::MediumFeaturesChanged(NotifyList &aListenersToNotify) RecomputeMatches(); if (mMatches != oldMatches) { for (uint32_t i = 0, i_end = mCallbacks.Length(); i != i_end; ++i) { - HandleChangeData *d = aListenersToNotify.AppendElement(); + HandleChangeData *d = aListenersToNotify.AppendElement(fallible); if (d) { d->mql = this; d->callback = mCallbacks[i]; diff --git a/layout/style/MediaQueryList.h b/layout/style/MediaQueryList.h index 144696be33..e0587a0a5b 100644 --- a/layout/style/MediaQueryList.h +++ b/layout/style/MediaQueryList.h @@ -48,11 +48,8 @@ public: nsRefPtr callback; }; - typedef FallibleTArray< nsRefPtr > CallbackList; - typedef FallibleTArray NotifyList; - // Appends listeners that need notification to aListenersToNotify - void MediumFeaturesChanged(NotifyList &aListenersToNotify); + void MediumFeaturesChanged(nsTArray& aListenersToNotify); bool HasListeners() const { return !mCallbacks.IsEmpty(); } @@ -88,7 +85,7 @@ private: nsRefPtr mMediaList; bool mMatches; bool mMatchesValid; - CallbackList mCallbacks; + nsTArray> mCallbacks; }; } // namespace dom diff --git a/media/libstagefright/binding/Index.cpp b/media/libstagefright/binding/Index.cpp index 5eca7f0e09..dc9c4ebcfc 100644 --- a/media/libstagefright/binding/Index.cpp +++ b/media/libstagefright/binding/Index.cpp @@ -244,7 +244,7 @@ Index::Index(const nsTArray& aIndex, if (aIndex.IsEmpty()) { mMoofParser = new MoofParser(aSource, aTrackId, aIsAudio, aMonitor); } else { - if (!mIndex.SetCapacity(aIndex.Length())) { + if (!mIndex.SetCapacity(aIndex.Length(), fallible)) { // OOM. return; } @@ -257,7 +257,8 @@ Index::Index(const nsTArray& aIndex, indice.end_composition); sample.mDecodeTime = indice.start_decode; sample.mSync = indice.sync; - MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample)); + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample, fallible)); } } } diff --git a/media/libstagefright/binding/MP4Metadata.cpp b/media/libstagefright/binding/MP4Metadata.cpp index 9824698d81..eec762d624 100644 --- a/media/libstagefright/binding/MP4Metadata.cpp +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -71,7 +71,7 @@ ConvertIndex(FallibleTArray& aDest, const nsTArray& aIndex, int64_t aMediaTime) { - if (!aDest.SetCapacity(aIndex.Length())) { + if (!aDest.SetCapacity(aIndex.Length(), mozilla::fallible)) { return false; } for (size_t i = 0; i < aIndex.Length(); i++) { @@ -83,7 +83,8 @@ ConvertIndex(FallibleTArray& aDest, indice.end_composition = s_indice.end_composition - aMediaTime; indice.start_decode = s_indice.start_decode; indice.sync = s_indice.sync; - MOZ_ALWAYS_TRUE(aDest.AppendElement(indice)); + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(aDest.AppendElement(indice, mozilla::fallible)); } return true; } diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp index db23d1f86b..eab362f4f9 100644 --- a/media/libstagefright/binding/MoofParser.cpp +++ b/media/libstagefright/binding/MoofParser.cpp @@ -528,7 +528,7 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u uint64_t decodeTime = *aDecodeTime; nsTArray> timeRanges; - if (!mIndex.SetCapacity(sampleCount)) { + if (!mIndex.SetCapacity(sampleCount, fallible)) { LOG(Moof, "Out of Memory"); return false; } @@ -561,7 +561,8 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, u // because every audio sample is a keyframe. sample.mSync = !(sampleFlags & 0x1010000) || aIsAudio; - MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample)); + // FIXME: Make this infallible after bug 968520 is done. + MOZ_ALWAYS_TRUE(mIndex.AppendElement(sample, fallible)); mMdatRange = mMdatRange.Extents(sample.mByteRange); } diff --git a/media/libstagefright/stubs/include/media/stagefright/foundation/AMessage.h b/media/libstagefright/stubs/include/media/stagefright/foundation/AMessage.h index 679ee52b10..f22439dd9d 100644 --- a/media/libstagefright/stubs/include/media/stagefright/foundation/AMessage.h +++ b/media/libstagefright/stubs/include/media/stagefright/foundation/AMessage.h @@ -4,6 +4,8 @@ #ifndef A_MESSAGE_H_ #define A_MESSAGE_H_ +#include + namespace stagefright { struct AMessage : public RefBase { diff --git a/media/libstagefright/stubs/include/ui/GraphicBuffer.h b/media/libstagefright/stubs/include/ui/GraphicBuffer.h index a23ab76857..47fa5dbada 100644 --- a/media/libstagefright/stubs/include/ui/GraphicBuffer.h +++ b/media/libstagefright/stubs/include/ui/GraphicBuffer.h @@ -4,6 +4,8 @@ #ifndef GRAPHIC_BUFFER_H_ #define GRAPHIC_BUFFER_H_ +#include + namespace stagefright { class GraphicBuffer : public RefBase { diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index 142d77c5bd..c22c4347f7 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -2939,7 +2939,7 @@ static void ToRTCIceCandidateStats( cand.mMozLocalTransport.Construct( NS_ConvertASCIItoUTF16(c->local_addr.transport.c_str())); } - report->mIceCandidateStats.Value().AppendElement(cand); + report->mIceCandidateStats.Value().AppendElement(cand, fallible); } } @@ -2976,7 +2976,7 @@ static void RecordIceStats_s( s.mMozPriority.Construct(p->priority); s.mSelected.Construct(p->selected); s.mState.Construct(RTCStatsIceCandidatePairState(p->state)); - report->mIceCandidatePairStats.Value().AppendElement(s); + report->mIceCandidatePairStats.Value().AppendElement(s, fallible); } std::vector candidates; @@ -3055,7 +3055,8 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) { s.mBytesReceived.Construct(bytesReceived); s.mPacketsLost.Construct(packetsLost); s.mMozRtt.Construct(rtt); - query->report->mInboundRTPStreamStats.Value().AppendElement(s); + query->report->mInboundRTPStreamStats.Value().AppendElement(s, + fallible); } } // Then, fill in local side (with cross-link to remote only if present) @@ -3092,7 +3093,8 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) { s.mDroppedFrames.Construct(droppedFrames); } } - query->report->mOutboundRTPStreamStats.Value().AppendElement(s); + query->report->mOutboundRTPStreamStats.Value().AppendElement(s, + fallible); } break; } @@ -3124,7 +3126,8 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) { s.mIsRemote = true; s.mPacketsSent.Construct(packetsSent); s.mBytesSent.Construct(bytesSent); - query->report->mOutboundRTPStreamStats.Value().AppendElement(s); + query->report->mOutboundRTPStreamStats.Value().AppendElement(s, + fallible); } } // Then, fill in local side (with cross-link to remote only if present) @@ -3178,7 +3181,8 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) { s.mDiscardedPackets.Construct(discardedPackets); } } - query->report->mInboundRTPStreamStats.Value().AppendElement(s); + query->report->mInboundRTPStreamStats.Value().AppendElement(s, + fallible); break; } } diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp index b4fdd351b7..e9ea4d1176 100644 --- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp +++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp @@ -271,14 +271,14 @@ OnStatsReport_m(WebrtcGlobalChild* aThisChild, } for (auto&& query : *aQueryList) { - request->mResult.mReports.Value().AppendElement(*(query->report)); + request->mResult.mReports.Value().AppendElement(*(query->report), fallible); } // Reports saved for closed/destroyed PeerConnections auto ctx = PeerConnectionCtx::GetInstance(); if (ctx) { for (auto&& pc : ctx->mStatsForClosedPeerConnections) { - request->mResult.mReports.Value().AppendElement(pc); + request->mResult.mReports.Value().AppendElement(pc, fallible); } } @@ -322,9 +322,9 @@ static void OnGetLogging_m(WebrtcGlobalChild* aThisChild, if (!aLogList->empty()) { for (auto& line : *aLogList) { - nsLogs.AppendElement(NS_ConvertUTF8toUTF16(line.c_str())); + nsLogs.AppendElement(NS_ConvertUTF8toUTF16(line.c_str()), fallible); } - nsLogs.AppendElement(NS_LITERAL_STRING("+++++++ END ++++++++")); + nsLogs.AppendElement(NS_LITERAL_STRING("+++++++ END ++++++++"), fallible); } unused << aThisChild->SendGetLogResult(aRequestId, nsLogs); @@ -343,9 +343,11 @@ static void OnGetLogging_m(WebrtcGlobalChild* aThisChild, if (!aLogList->empty()) { for (auto& line : *aLogList) { - request->mResult.AppendElement(NS_ConvertUTF8toUTF16(line.c_str())); + request->mResult.AppendElement(NS_ConvertUTF8toUTF16(line.c_str()), + fallible); } - request->mResult.AppendElement(NS_LITERAL_STRING("+++++++ END ++++++++")); + request->mResult.AppendElement(NS_LITERAL_STRING("+++++++ END ++++++++"), + fallible); } request->Complete(); @@ -626,7 +628,7 @@ WebrtcGlobalParent::RecvGetStatsResult(const int& aRequestId, } for (auto&& s : Stats) { - request->mResult.mReports.Value().AppendElement(s); + request->mResult.mReports.Value().AppendElement(s, fallible); } auto next = request->GetNextParent(); @@ -1005,7 +1007,7 @@ static void StoreLongTermICEStatisticsImpl_m( PeerConnectionCtx *ctx = GetPeerConnectionCtx(); if (ctx) { - ctx->mStatsForClosedPeerConnections.AppendElement(*query->report); + ctx->mStatsForClosedPeerConnections.AppendElement(*query->report, fallible); } } diff --git a/netwerk/base/Dashboard.cpp b/netwerk/base/Dashboard.cpp index d1438c564d..82bfd2cc5d 100644 --- a/netwerk/base/Dashboard.cpp +++ b/netwerk/base/Dashboard.cpp @@ -298,7 +298,6 @@ LookupHelper::OnLookupComplete(nsICancelable *aRequest, nsresult LookupHelper::ConstructAnswer(LookupArgument *aArgument) { - nsIDNSRecord *aRecord = aArgument->mRecord; AutoSafeJSContext cx; @@ -312,10 +311,15 @@ LookupHelper::ConstructAnswer(LookupArgument *aArgument) bool hasMore; aRecord->HasMore(&hasMore); while (hasMore) { - nsCString nextAddress; - aRecord->GetNextAddrAsString(nextAddress); - CopyASCIItoUTF16(nextAddress, *addresses.AppendElement()); - aRecord->HasMore(&hasMore); + nsString* nextAddress = addresses.AppendElement(fallible); + if (!nextAddress) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCString nextAddressASCII; + aRecord->GetNextAddrAsString(nextAddressASCII); + CopyASCIItoUTF16(nextAddressASCII, *nextAddress); + aRecord->HasMore(&hasMore); } } else { dict.mAnswer = false; @@ -393,7 +397,7 @@ Dashboard::GetSockets(SocketData *aSocketData) } for (uint32_t i = 0; i < socketData->mData.Length(); i++) { - mozilla::dom::SocketElement &mSocket = *sockets.AppendElement(); + dom::SocketElement &mSocket = *sockets.AppendElement(fallible); CopyASCIItoUTF16(socketData->mData[i].host, mSocket.mHost); mSocket.mPort = socketData->mData[i].port; mSocket.mActive = socketData->mData[i].active; @@ -463,7 +467,7 @@ Dashboard::GetHttpConnections(HttpData *aHttpData) } for (uint32_t i = 0; i < httpData->mData.Length(); i++) { - HttpConnectionElement &connection = *connections.AppendElement(); + HttpConnectionElement &connection = *connections.AppendElement(fallible); CopyASCIItoUTF16(httpData->mData[i].host, connection.mHost); connection.mPort = httpData->mData[i].port; @@ -487,7 +491,7 @@ Dashboard::GetHttpConnections(HttpData *aHttpData) } for (uint32_t j = 0; j < httpData->mData[i].active.Length(); j++) { - HttpConnInfo &info = *active.AppendElement(); + HttpConnInfo &info = *active.AppendElement(fallible); info.mRtt = httpData->mData[i].active[j].rtt; info.mTtl = httpData->mData[i].active[j].ttl; info.mProtocolVersion = @@ -495,14 +499,14 @@ Dashboard::GetHttpConnections(HttpData *aHttpData) } for (uint32_t j = 0; j < httpData->mData[i].idle.Length(); j++) { - HttpConnInfo &info = *idle.AppendElement(); + HttpConnInfo &info = *idle.AppendElement(fallible); info.mRtt = httpData->mData[i].idle[j].rtt; info.mTtl = httpData->mData[i].idle[j].ttl; info.mProtocolVersion = httpData->mData[i].idle[j].protocolVersion; } for (uint32_t j = 0; j < httpData->mData[i].halfOpens.Length(); j++) { - HalfOpenInfoDict &info = *halfOpens.AppendElement(); + HalfOpenInfoDict &info = *halfOpens.AppendElement(fallible); info.mSpeculative = httpData->mData[i].halfOpens[j].speculative; } } @@ -626,7 +630,7 @@ Dashboard::GetWebSocketConnections(WebSocketRequest *aWsRequest) } for (uint32_t i = 0; i < mWs.data.Length(); i++) { - mozilla::dom::WebSocketElement &websocket = *websockets.AppendElement(); + dom::WebSocketElement &websocket = *websockets.AppendElement(fallible); CopyASCIItoUTF16(mWs.data[i].mHost, websocket.mHostport); websocket.mMsgsent = mWs.data[i].mMsgSent; websocket.mMsgreceived = mWs.data[i].mMsgReceived; @@ -699,7 +703,7 @@ Dashboard::GetDNSCacheEntries(DnsData *dnsData) } for (uint32_t i = 0; i < dnsData->mData.Length(); i++) { - mozilla::dom::DnsCacheEntry &entry = *entries.AppendElement(); + dom::DnsCacheEntry &entry = *entries.AppendElement(fallible); entry.mHostaddr.Construct(); Sequence &addrs = entry.mHostaddr.Value(); @@ -713,7 +717,7 @@ Dashboard::GetDNSCacheEntries(DnsData *dnsData) for (uint32_t j = 0; j < dnsData->mData[i].hostaddr.Length(); j++) { CopyASCIItoUTF16(dnsData->mData[i].hostaddr[j], - *addrs.AppendElement()); + *addrs.AppendElement(fallible)); } if (dnsData->mData[i].family == PR_AF_INET6) { diff --git a/netwerk/base/nsUDPSocket.cpp b/netwerk/base/nsUDPSocket.cpp index df0487ed01..a0741c6ebc 100644 --- a/netwerk/base/nsUDPSocket.cpp +++ b/netwerk/base/nsUDPSocket.cpp @@ -1124,10 +1124,10 @@ class SendRequestRunnable: public nsRunnable { public: SendRequestRunnable(nsUDPSocket *aSocket, const NetAddr &aAddr, - FallibleTArray &aData) + FallibleTArray&& aData) : mSocket(aSocket) , mAddr(aAddr) - , mData(aData) + , mData(Move(aData)) { } NS_DECL_NSIRUNNABLE @@ -1174,7 +1174,7 @@ nsUDPSocket::Send(const nsACString &aHost, uint16_t aPort, *_retval = 0; FallibleTArray fallibleArray; - if (!fallibleArray.InsertElementsAt(0, aData, aDataLength)) { + if (!fallibleArray.InsertElementsAt(0, aData, aDataLength, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1232,12 +1232,13 @@ nsUDPSocket::SendWithAddress(const NetAddr *aAddr, const uint8_t *aData, *_retval = count; } else { FallibleTArray fallibleArray; - if (!fallibleArray.InsertElementsAt(0, aData, aDataLength)) { + if (!fallibleArray.InsertElementsAt(0, aData, aDataLength, fallible)) { return NS_ERROR_OUT_OF_MEMORY; } - nsresult rv = mSts->Dispatch(new SendRequestRunnable(this, *aAddr, fallibleArray), - NS_DISPATCH_NORMAL); + nsresult rv = mSts->Dispatch( + new SendRequestRunnable(this, *aAddr, Move(fallibleArray)), + NS_DISPATCH_NORMAL); NS_ENSURE_SUCCESS(rv, rv); *_retval = aDataLength; } diff --git a/widget/gonk/nsScreenManagerGonk.h b/widget/gonk/nsScreenManagerGonk.h index 6629ce3a41..6dd8854bd5 100644 --- a/widget/gonk/nsScreenManagerGonk.h +++ b/widget/gonk/nsScreenManagerGonk.h @@ -23,6 +23,8 @@ #include "nsBaseScreen.h" #include "nsIScreenManager.h" +#include + class nsRunnable; class nsWindow; diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index bb9dcb737b..25e3aec426 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -1176,6 +1176,31 @@ public: // // Mutation methods // + + template + typename ActualAlloc::ResultType Assign( + const nsTArray_Impl& aOther) + { + return ActualAlloc::ConvertBoolToResultType( + !!ReplaceElementsAt(0, Length(), + aOther.Elements(), aOther.Length())); + } + + template + /* MOZ_WARN_UNUSED_RESULT */ + bool Assign(const nsTArray_Impl& aOther, + const mozilla::fallible_t&) + { + return Assign(aOther); + } + + template + void Assign(nsTArray_Impl&& aOther) + { + Clear(); + SwapElements(aOther); + } + // This method call the destructor on each element of the array, empties it, // but does not shrink the array's capacity. // See also SetLengthAndRetainStorage. @@ -2285,6 +2310,12 @@ public: } }; +template +struct nsTArray_CopyChooser> +{ + typedef nsTArray_CopyWithConstructors> Type; +}; + // Assert that nsAutoTArray doesn't have any extra padding inside. // // It's important that the data stored in this auto array takes up a multiple of diff --git a/xpcom/io/nsPipe3.cpp b/xpcom/io/nsPipe3.cpp index 260d87b91e..3522d99963 100644 --- a/xpcom/io/nsPipe3.cpp +++ b/xpcom/io/nsPipe3.cpp @@ -1377,10 +1377,12 @@ nsPipeInputStream::SetEOF() return NS_ERROR_NOT_IMPLEMENTED; } -#define COMPARE(s1, s2, i) \ - (aIgnoreCase \ - ? nsCRT::strncasecmp((const char *)s1, (const char *)s2, (uint32_t)i) \ - : nsCRT::strncmp((const char *)s1, (const char *)s2, (uint32_t)i)) +static bool strings_equal(bool aIgnoreCase, + const char* aS1, const char* aS2, uint32_t aLen) +{ + return aIgnoreCase + ? !nsCRT::strncasecmp(aS1, aS2, aLen) : !nsCRT::strncmp(aS1, aS2, aLen); +} NS_IMETHODIMP nsPipeInputStream::Search(const char* aForString, @@ -1410,7 +1412,7 @@ nsPipeInputStream::Search(const char* aForString, // check if the string is in the buffer segment for (i = 0; i < len1 - strLen + 1; i++) { - if (COMPARE(&cursor1[i], aForString, strLen) == 0) { + if (strings_equal(aIgnoreCase, &cursor1[i], aForString, strLen)) { *aFound = true; *aOffsetSearchedTo = offset + i; LOG((" result [aFound=%u offset=%u]\n", *aFound, *aOffsetSearchedTo)); @@ -1442,8 +1444,8 @@ nsPipeInputStream::Search(const char* aForString, uint32_t strPart2Len = strLen - strPart1Len; const char* strPart2 = &aForString[strLen - strPart2Len]; uint32_t bufSeg1Offset = len1 - strPart1Len; - if (COMPARE(&cursor1[bufSeg1Offset], aForString, strPart1Len) == 0 && - COMPARE(cursor2, strPart2, strPart2Len) == 0) { + if (strings_equal(aIgnoreCase, &cursor1[bufSeg1Offset], aForString, strPart1Len) && + strings_equal(aIgnoreCase, cursor2, strPart2, strPart2Len)) { *aFound = true; *aOffsetSearchedTo = offset - strPart1Len; LOG((" result [aFound=%u offset=%u]\n", *aFound, *aOffsetSearchedTo)); diff --git a/xpcom/tests/gtest/TestTArray.cpp b/xpcom/tests/gtest/TestTArray.cpp new file mode 100644 index 0000000000..86364de3e6 --- /dev/null +++ b/xpcom/tests/gtest/TestTArray.cpp @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsTArray.h" +#include "gtest/gtest.h" + +using namespace mozilla; + +namespace TestTArray { + +const nsTArray& DummyArray() +{ + static nsTArray sArray; + if (sArray.IsEmpty()) { + const int data[] = {4, 1, 2, 8}; + sArray.AppendElements(data, ArrayLength(data)); + } + return sArray; +} + +// This returns an invalid nsTArray with a huge length in order to test that +// fallible operations actually fail. +#ifdef DEBUG +const nsTArray& FakeHugeArray() +{ + static nsTArray sArray; + if (sArray.IsEmpty()) { + sArray.AppendElement(); + ((nsTArrayHeader*)sArray.DebugGetHeader())->mLength = UINT32_MAX; + } + return sArray; +} +#endif + +TEST(TArray, assign) +{ + nsTArray array; + array.Assign(DummyArray()); + ASSERT_EQ(DummyArray(), array); + + ASSERT_TRUE(array.Assign(DummyArray(), fallible)); + ASSERT_EQ(DummyArray(), array); + +#ifdef DEBUG + ASSERT_FALSE(array.Assign(FakeHugeArray(), fallible)); +#endif + + nsTArray array2; + array2.Assign(Move(array)); + ASSERT_TRUE(array.IsEmpty()); + ASSERT_EQ(DummyArray(), array2); +} + +} diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index b2343b494b..74a31eaf09 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -18,6 +18,7 @@ UNIFIED_SOURCES += [ 'TestStrings.cpp', 'TestStringStream.cpp', 'TestSynchronization.cpp', + 'TestTArray.cpp', 'TestThreadPool.cpp', 'TestTimeStamp.cpp', 'TestUTF.cpp',