void VorbisDataDecoder::Drain() { MOZ_ASSERT(mCallback->OnReaderTaskQueue()); mTaskQueue->Dispatch(NewRunnableMethod(this, &VorbisDataDecoder::ProcessDrain)); }
/* ===== Helpers ============================ */ CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) { switch (aType) { case nsIContentPolicy::TYPE_IMAGE: case nsIContentPolicy::TYPE_IMAGESET: return nsIContentSecurityPolicy::IMG_SRC_DIRECTIVE; // BLock XSLT as script, see bug 910139 case nsIContentPolicy::TYPE_XSLT: case nsIContentPolicy::TYPE_SCRIPT: case nsIContentPolicy::TYPE_INTERNAL_SCRIPT: case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD: return nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_STYLESHEET: return nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_FONT: return nsIContentSecurityPolicy::FONT_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_MEDIA: return nsIContentSecurityPolicy::MEDIA_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_WEB_MANIFEST: return nsIContentSecurityPolicy::WEB_MANIFEST_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_INTERNAL_WORKER: case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER: case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER: return nsIContentSecurityPolicy::CHILD_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_SUBDOCUMENT: return nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_WEBSOCKET: case nsIContentPolicy::TYPE_XMLHTTPREQUEST: case nsIContentPolicy::TYPE_BEACON: case nsIContentPolicy::TYPE_FETCH: return nsIContentSecurityPolicy::CONNECT_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_OBJECT: case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: return nsIContentSecurityPolicy::OBJECT_SRC_DIRECTIVE; case nsIContentPolicy::TYPE_XBL: case nsIContentPolicy::TYPE_PING: case nsIContentPolicy::TYPE_DTD: case nsIContentPolicy::TYPE_OTHER: return nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE; // csp shold not block top level loads, e.g. in case // of a redirect. case nsIContentPolicy::TYPE_DOCUMENT: // CSP can not block csp reports case nsIContentPolicy::TYPE_CSP_REPORT: return nsIContentSecurityPolicy::NO_DIRECTIVE; // Fall through to error for all other directives default: MOZ_ASSERT(false, "Can not map nsContentPolicyType to CSPDirective"); } return nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE; }
explicit WorkerFetchResponseEndBase(PromiseWorkerProxy* aPromiseProxy) : mPromiseProxy(aPromiseProxy) { MOZ_ASSERT(mPromiseProxy); }
void SetLocationForGlobal(JSObject *global, const nsACString& location) { MOZ_ASSERT(global); CompartmentPrivate::Get(global)->SetLocation(location); }
MacIOSurfaceTextureData::MacIOSurfaceTextureData(MacIOSurface* aSurface) : mSurface(aSurface) { MOZ_ASSERT(mSurface); }
int NrIceResolver::cancel(void *obj, void *handle) { MOZ_ALWAYS_TRUE(obj); MOZ_ASSERT(handle); ASSERT_ON_THREAD(static_cast<NrIceResolver *>(obj)->sts_thread_); return static_cast<PendingResolution *>(handle)->cancel(); }
void LayerManagerComposite::PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget, IntRect aClipRect, bool aGrayscaleEffect, bool aInvertEffect, float aContrastEffect) { MOZ_ASSERT(mTwoPassTmpTarget); // This is currently true, so just making sure that any new use of this // method is flagged for investigation MOZ_ASSERT(aInvertEffect || aGrayscaleEffect || aContrastEffect != 0.0); mCompositor->SetRenderTarget(aPreviousTarget); EffectChain effectChain(RootLayer()); Matrix5x4 effectMatrix; if (aGrayscaleEffect) { // R' = G' = B' = luminance // R' = 0.2126*R + 0.7152*G + 0.0722*B // G' = 0.2126*R + 0.7152*G + 0.0722*B // B' = 0.2126*R + 0.7152*G + 0.0722*B Matrix5x4 grayscaleMatrix(0.2126f, 0.2126f, 0.2126f, 0, 0.7152f, 0.7152f, 0.7152f, 0, 0.0722f, 0.0722f, 0.0722f, 0, 0, 0, 0, 1, 0, 0, 0, 0); effectMatrix = grayscaleMatrix; } if (aInvertEffect) { // R' = 1 - R // G' = 1 - G // B' = 1 - B Matrix5x4 colorInvertMatrix(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 1, 1, 1, 0); effectMatrix = effectMatrix * colorInvertMatrix; } if (aContrastEffect != 0.0) { // Multiplying with: // R' = (1 + c) * (R - 0.5) + 0.5 // G' = (1 + c) * (G - 0.5) + 0.5 // B' = (1 + c) * (B - 0.5) + 0.5 float cP1 = aContrastEffect + 1; float hc = 0.5*aContrastEffect; Matrix5x4 contrastMatrix( cP1, 0, 0, 0, 0, cP1, 0, 0, 0, 0, cP1, 0, 0, 0, 0, 1, -hc, -hc, -hc, 0); effectMatrix = effectMatrix * contrastMatrix; } effectChain.mPrimaryEffect = new EffectRenderTarget(mTwoPassTmpTarget); effectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX] = new EffectColorMatrix(effectMatrix); gfx::Rect clipRectF(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); mCompositor->DrawQuad(Rect(Point(0, 0), Size(mTwoPassTmpTarget->GetSize())), clipRectF, effectChain, 1., Matrix4x4()); }
CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, ErrorResult& aRv, const char* aExecutionReason, ExceptionHandling aExceptionHandling, JS::Realm* aRealm, bool aIsJSImplementedWebIDL) : mCx(nullptr), mRealm(aRealm), mErrorResult(aRv), mExceptionHandling(aExceptionHandling), mIsMainThread(NS_IsMainThread()) { CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get(); if (ccjs) { ccjs->EnterMicroTask(); } // Compute the caller's subject principal (if necessary) early, before we // do anything that might perturb the relevant state. nsIPrincipal* webIDLCallerPrincipal = nullptr; if (aIsJSImplementedWebIDL) { webIDLCallerPrincipal = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller(); } JSObject* wrappedCallback = aCallback->CallbackPreserveColor(); if (!wrappedCallback) { aRv.ThrowDOMException( NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING( "Cannot execute callback from a nuked compartment.")); return; } nsIGlobalObject* globalObject = nullptr; { // First, find the real underlying callback. JSObject* realCallback = js::UncheckedUnwrap(wrappedCallback); // Check that it's ok to run this callback. JS-implemented WebIDL is always // OK to run, since it runs with Chrome privileges anyway. if (mIsMainThread && !aIsJSImplementedWebIDL) { // Make sure to use realCallback to get the global of the callback // object, not the wrapper. if (!xpc::Scriptability::Get(realCallback).Allowed()) { aRv.ThrowDOMException( NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING( "Refusing to execute function from global in which " "script is disabled.")); return; } } // Now get the global for this callback. Note that for the case of // JS-implemented WebIDL we never have a window here. nsGlobalWindowInner* win = mIsMainThread && !aIsJSImplementedWebIDL ? xpc::WindowGlobalOrNull(realCallback) : nullptr; if (win) { // We don't want to run script in windows that have been navigated away // from. if (!win->HasActiveDocument()) { aRv.ThrowDOMException( NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function from window " "whose document is no longer active.")); return; } globalObject = win; } else { // No DOM Window. Store the global. globalObject = xpc::NativeGlobal(realCallback); MOZ_ASSERT(globalObject); } } // Bail out if there's no useful global. if (!globalObject->HasJSGlobal()) { aRv.ThrowDOMException( NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function from global which is " "being torn down.")); return; } mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread); mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal); nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull(); if (incumbent) { // The callback object traces its incumbent JS global, so in general it // should be alive here. However, it's possible that we could run afoul // of the same IPC global weirdness described above, wherein the // nsIGlobalObject has severed its reference to the JS global. Let's just // be safe here, so that nobody has to waste a day debugging gaia-ui tests. if (!incumbent->HasJSGlobal()) { aRv.ThrowDOMException( NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function because our " "incumbent global is being torn down.")); return; } mAutoIncumbentScript.emplace(incumbent); } JSContext* cx = mAutoEntryScript->cx(); // Unmark the callable (by invoking CallbackOrNull() and not the // CallbackPreserveColor() variant), and stick it in a Rooted before it can // go gray again. // Nothing before us in this function can trigger a CC, so it's safe to wait // until here it do the unmark. This allows us to construct mRootedCallable // with the cx from mAutoEntryScript, avoiding the cost of finding another // JSContext. (Rooted<> does not care about requests or compartments.) mRootedCallable.emplace(cx, aCallback->CallbackOrNull()); mRootedCallableGlobal.emplace(cx, aCallback->CallbackGlobalOrNull()); mAsyncStack.emplace(cx, aCallback->GetCreationStack()); if (*mAsyncStack) { mAsyncStackSetter.emplace(cx, *mAsyncStack, aExecutionReason); } // Enter the realm of our callback, so we can actually work with it. // // Note that if the callback is a wrapper, this will not be the same // realm that we ended up in with mAutoEntryScript above, because the // entry point is based off of the unwrapped callback (realCallback). mAr.emplace(cx, *mRootedCallableGlobal); // And now we're ready to go. mCx = cx; }
void ContentHostBase::Composite(EffectChain& aEffectChain, float aOpacity, const gfx::Matrix4x4& aTransform, const Point& aOffset, const Filter& aFilter, const Rect& aClipRect, const nsIntRegion* aVisibleRegion, TiledLayerProperties* aLayerProperties) { NS_ASSERTION(aVisibleRegion, "Requires a visible region"); if (!mTextureHost || !mTextureHost->Lock()) { return; } RefPtr<TexturedEffect> effect = CreateTexturedEffect(mTextureHost, aFilter); aEffectChain.mPrimaryEffect = effect; nsIntRegion tmpRegion; const nsIntRegion* renderRegion; if (PaintWillResample()) { // If we're resampling, then the texture image will contain exactly the // entire visible region's bounds, and we should draw it all in one quad // to avoid unexpected aliasing. tmpRegion = aVisibleRegion->GetBounds(); renderRegion = &tmpRegion; } else { renderRegion = aVisibleRegion; } nsIntRegion region(*renderRegion); nsIntPoint origin = GetOriginOffset(); region.MoveBy(-origin); // translate into TexImage space, buffer origin might not be at texture (0,0) // Figure out the intersecting draw region TextureSource* source = mTextureHost; MOZ_ASSERT(source); gfx::IntSize texSize = source->GetSize(); nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height); textureRect.MoveBy(region.GetBounds().TopLeft()); nsIntRegion subregion; subregion.And(region, textureRect); if (subregion.IsEmpty()) { // Region is empty, nothing to draw mTextureHost->Unlock(); return; } nsIntRegion screenRects; nsIntRegion regionRects; // Collect texture/screen coordinates for drawing nsIntRegionRectIterator iter(subregion); while (const nsIntRect* iterRect = iter.Next()) { nsIntRect regionRect = *iterRect; nsIntRect screenRect = regionRect; screenRect.MoveBy(origin); screenRects.Or(screenRects, screenRect); regionRects.Or(regionRects, regionRect); } TileIterator* tileIter = source->AsTileIterator(); TileIterator* iterOnWhite = nullptr; if (tileIter) { tileIter->BeginTileIteration(); } if (mTextureHostOnWhite) { iterOnWhite = mTextureHostOnWhite->AsTileIterator(); MOZ_ASSERT(!tileIter || tileIter->GetTileCount() == iterOnWhite->GetTileCount(), "Tile count mismatch on component alpha texture"); if (iterOnWhite) { iterOnWhite->BeginTileIteration(); } } bool usingTiles = (tileIter && tileIter->GetTileCount() > 1); do { if (iterOnWhite) { MOZ_ASSERT(iterOnWhite->GetTileRect() == tileIter->GetTileRect(), "component alpha textures should be the same size."); } nsIntRect texRect = tileIter ? tileIter->GetTileRect() : nsIntRect(0, 0, texSize.width, texSize.height); // Draw texture. If we're using tiles, we do repeating manually, as texture // repeat would cause each individual tile to repeat instead of the // compound texture as a whole. This involves drawing at most 4 sections, // 2 for each axis that has texture repeat. for (int y = 0; y < (usingTiles ? 2 : 1); y++) { for (int x = 0; x < (usingTiles ? 2 : 1); x++) { nsIntRect currentTileRect(texRect); currentTileRect.MoveBy(x * texSize.width, y * texSize.height); nsIntRegionRectIterator screenIter(screenRects); nsIntRegionRectIterator regionIter(regionRects); const nsIntRect* screenRect; const nsIntRect* regionRect; while ((screenRect = screenIter.Next()) && (regionRect = regionIter.Next())) { nsIntRect tileScreenRect(*screenRect); nsIntRect tileRegionRect(*regionRect); // When we're using tiles, find the intersection between the tile // rect and this region rect. Tiling is then handled by the // outer for-loops and modifying the tile rect. if (usingTiles) { tileScreenRect.MoveBy(-origin); tileScreenRect = tileScreenRect.Intersect(currentTileRect); tileScreenRect.MoveBy(origin); if (tileScreenRect.IsEmpty()) continue; tileRegionRect = regionRect->Intersect(currentTileRect); tileRegionRect.MoveBy(-currentTileRect.TopLeft()); } gfx::Rect rect(tileScreenRect.x, tileScreenRect.y, tileScreenRect.width, tileScreenRect.height); effect->mTextureCoords = Rect(Float(tileRegionRect.x) / texRect.width, Float(tileRegionRect.y) / texRect.height, Float(tileRegionRect.width) / texRect.width, Float(tileRegionRect.height) / texRect.height); GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform, aOffset); } } } if (iterOnWhite) { iterOnWhite->NextTile(); } } while (usingTiles && tileIter->NextTile()); if (tileIter) { tileIter->EndTileIteration(); } if (iterOnWhite) { iterOnWhite->EndTileIteration(); } mTextureHost->Unlock(); }
void BasicCompositor::DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, const EffectChain &aEffectChain, gfx::Float aOpacity, const gfx::Matrix4x4& aTransform, const gfx::Rect& aVisibleRect) { RefPtr<DrawTarget> buffer = mRenderTarget->mDrawTarget; // For 2D drawing, |dest| and |buffer| are the same surface. For 3D drawing, // |dest| is a temporary surface. RefPtr<DrawTarget> dest = buffer; AutoRestoreTransform autoRestoreTransform(dest); Matrix newTransform; Rect transformBounds; Matrix4x4 new3DTransform; IntPoint offset = mRenderTarget->GetOrigin(); if (aTransform.Is2D()) { newTransform = aTransform.As2D(); } else { // Create a temporary surface for the transform. dest = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(RoundOut(aRect).Size(), SurfaceFormat::B8G8R8A8); if (!dest) { return; } dest->SetTransform(Matrix::Translation(-aRect.x, -aRect.y)); // Get the bounds post-transform. transformBounds = aTransform.TransformAndClipBounds(aRect, Rect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height)); transformBounds.RoundOut(); if (transformBounds.IsEmpty()) { return; } // Propagate the coordinate offset to our 2D draw target. newTransform = Matrix::Translation(transformBounds.x, transformBounds.y); // When we apply the 3D transformation, we do it against a temporary // surface, so undo the coordinate offset. new3DTransform = Matrix4x4::Translation(aRect.x, aRect.y, 0) * aTransform; } buffer->PushClipRect(aClipRect); newTransform.PostTranslate(-offset.x, -offset.y); buffer->SetTransform(newTransform); RefPtr<SourceSurface> sourceMask; Matrix maskTransform; if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) { EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get()); sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(dest); if (!sourceMask) { gfxWarning() << "Invalid sourceMask effect"; } MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!"); MOZ_ASSERT(!effectMask->mIs3D); maskTransform = effectMask->mMaskTransform.As2D(); maskTransform.PreTranslate(-offset.x, -offset.y); } CompositionOp blendMode = CompositionOp::OP_OVER; if (Effect* effect = aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get()) { blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode; } switch (aEffectChain.mPrimaryEffect->mType) { case EffectTypes::SOLID_COLOR: { EffectSolidColor* effectSolidColor = static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get()); bool unboundedOp = !IsOperatorBoundByMask(blendMode); if (unboundedOp) { dest->PushClipRect(aRect); } FillRectWithMask(dest, aRect, effectSolidColor->mColor, DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform); if (unboundedOp) { dest->PopClip(); } break; } case EffectTypes::RGB: { TexturedEffect* texturedEffect = static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get()); TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic(); if (source && texturedEffect->mPremultiplied) { DrawSurfaceWithTextureCoords(dest, aRect, source->GetSurface(dest), texturedEffect->mTextureCoords, texturedEffect->mFilter, DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform); } else if (source) { SourceSurface* srcSurf = source->GetSurface(dest); if (srcSurf) { RefPtr<DataSourceSurface> srcData = srcSurf->GetDataSurface(); // Yes, we re-create the premultiplied data every time. // This might be better with a cache, eventually. RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData); DrawSurfaceWithTextureCoords(dest, aRect, premultData, texturedEffect->mTextureCoords, texturedEffect->mFilter, DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform); } } else { gfxDevCrash(LogReason::IncompatibleBasicTexturedEffect) << "Bad for basic with " << texturedEffect->mTexture->Name() << " and " << gfx::hexa(sourceMask); } break; } case EffectTypes::YCBCR: { NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!"); break; } case EffectTypes::RENDER_TARGET: { EffectRenderTarget* effectRenderTarget = static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get()); RefPtr<BasicCompositingRenderTarget> surface = static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get()); RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot(); DrawSurfaceWithTextureCoords(dest, aRect, sourceSurf, effectRenderTarget->mTextureCoords, effectRenderTarget->mFilter, DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform); break; } case EffectTypes::COMPONENT_ALPHA: { NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!"); break; } default: { NS_RUNTIMEABORT("Invalid effect type!"); break; } } if (!aTransform.Is2D()) { dest->Flush(); RefPtr<SourceSurface> snapshot = dest->Snapshot(); RefPtr<DataSourceSurface> source = snapshot->GetDataSurface(); RefPtr<DataSourceSurface> temp = Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8 #ifdef MOZ_ENABLE_SKIA , true #endif ); if (NS_WARN_IF(!temp)) { buffer->PopClip(); return; } Transform(temp, source, new3DTransform, transformBounds.TopLeft()); transformBounds.MoveTo(0, 0); buffer->DrawSurface(temp, transformBounds, transformBounds); } buffer->PopClip(); }
// Private destructor, to discourage deletion outside of Release(): ~URLProxy() { MOZ_ASSERT(!mURL); }
void ReleaseIPDLReference() { MOZ_ASSERT(mIPCOpen == true); mIPCOpen = false; Release(); }
// AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor // and DestroyIPDLActor, respectively. We intentionally make them private to prevent misuse. // The purpose of these methods is to be aware of when the IPC system around this // actor goes down: mIPCOpen is then set to false. void AddIPDLReference() { MOZ_ASSERT(mIPCOpen == false); mIPCOpen = true; AddRef(); }
/* static */ Connection* Connection::CreateForWindow(nsPIDOMWindowInner* aWindow) { MOZ_ASSERT(aWindow); return new ConnectionMainThread(aWindow); }
DrawableSurface RasterImage::LookupFrame(const IntSize& aSize, uint32_t aFlags, PlaybackType aPlaybackType) { MOZ_ASSERT(NS_IsMainThread()); // If we're opaque, we don't need to care about premultiplied alpha, because // that can only matter for frames with transparency. if (IsOpaque()) { aFlags &= ~FLAG_DECODE_NO_PREMULTIPLY_ALPHA; } IntSize requestedSize = CanDownscaleDuringDecode(aSize, aFlags) ? aSize : mSize; if (requestedSize.IsEmpty()) { return DrawableSurface(); // Can't decode to a surface of zero size. } LookupResult result = LookupFrameInternal(requestedSize, aFlags, aPlaybackType); if (!result && !mHasSize) { // We can't request a decode without knowing our intrinsic size. Give up. return DrawableSurface(); } if (result.Type() == MatchType::NOT_FOUND || result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND || ((aFlags & FLAG_SYNC_DECODE) && !result)) { // We don't have a copy of this frame, and there's no decoder working on // one. (Or we're sync decoding and the existing decoder hasn't even started // yet.) Trigger decoding so it'll be available next time. MOZ_ASSERT(aPlaybackType != PlaybackType::eAnimated || !mAnimationState || mAnimationState->KnownFrameCount() < 1, "Animated frames should be locked"); bool ranSync = Decode(requestedSize, aFlags, aPlaybackType); // If we can or did sync decode, we should already have the frame. if (ranSync || (aFlags & FLAG_SYNC_DECODE)) { result = LookupFrameInternal(requestedSize, aFlags, aPlaybackType); } } if (!result) { // We still weren't able to get a frame. Give up. return DrawableSurface(); } if (result.Surface()->GetCompositingFailed()) { return DrawableSurface(); } MOZ_ASSERT(!result.Surface()->GetIsPaletted(), "Should not have a paletted frame"); // Sync decoding guarantees that we got the frame, but if it's owned by an // async decoder that's currently running, the contents of the frame may not // be available yet. Make sure we get everything. if (mHasSourceData && (aFlags & FLAG_SYNC_DECODE)) { result.Surface()->WaitUntilFinished(); } // If we could have done some decoding in this function we need to check if // that decoding encountered an error and hence aborted the surface. We want // to avoid calling IsAborted if we weren't passed any sync decode flag because // IsAborted acquires the monitor for the imgFrame. if (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST) && result.Surface()->IsAborted()) { return DrawableSurface(); } return Move(result.Surface()); }
ContentBridgeParent* nsIContentParent::AsContentBridgeParent() { MOZ_ASSERT(IsContentBridgeParent()); return static_cast<ContentBridgeParent*>(this); }
bool RasterImage::SetMetadata(const ImageMetadata& aMetadata, bool aFromMetadataDecode) { MOZ_ASSERT(NS_IsMainThread()); if (mError) { return true; } if (aMetadata.HasSize()) { IntSize size = aMetadata.GetSize(); if (size.width < 0 || size.height < 0) { NS_WARNING("Image has negative intrinsic size"); DoError(); return true; } MOZ_ASSERT(aMetadata.HasOrientation()); Orientation orientation = aMetadata.GetOrientation(); // If we already have a size, check the new size against the old one. if (mHasSize && (size != mSize || orientation != mOrientation)) { NS_WARNING("Image changed size or orientation on redecode! " "This should not happen!"); DoError(); return true; } // Set the size and flag that we have it. mSize = size; mOrientation = orientation; mHasSize = true; } if (mHasSize && aMetadata.HasAnimation() && !mAnimationState) { // We're becoming animated, so initialize animation stuff. mAnimationState.emplace(mAnimationMode); mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize); // We don't support discarding animated images (See bug 414259). // Lock the image and throw away the key. LockImage(); if (!aFromMetadataDecode) { // The metadata decode reported that this image isn't animated, but we // discovered that it actually was during the full decode. This is a // rare failure that only occurs for corrupt images. To recover, we need // to discard all existing surfaces and redecode. return false; } } if (mAnimationState) { mAnimationState->SetLoopCount(aMetadata.GetLoopCount()); mAnimationState->SetFirstFrameTimeout(aMetadata.GetFirstFrameTimeout()); if (aMetadata.HasLoopLength()) { mAnimationState->SetLoopLength(aMetadata.GetLoopLength()); } if (aMetadata.HasFirstFrameRefreshArea()) { mAnimationState ->SetFirstFrameRefreshArea(aMetadata.GetFirstFrameRefreshArea()); } } if (aMetadata.HasHotspot()) { IntPoint hotspot = aMetadata.GetHotspot(); nsCOMPtr<nsISupportsPRUint32> intwrapx = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID); nsCOMPtr<nsISupportsPRUint32> intwrapy = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID); intwrapx->SetData(hotspot.x); intwrapy->SetData(hotspot.y); Set("hotspotX", intwrapx); Set("hotspotY", intwrapy); } return true; }
void EventListenerManager::AddEventListenerInternal( const EventListenerHolder& aListenerHolder, uint32_t aType, nsIAtom* aTypeAtom, const nsAString& aTypeString, const EventListenerFlags& aFlags, bool aHandler, bool aAllEvents) { MOZ_ASSERT((NS_IsMainThread() && aType && aTypeAtom) || // Main thread (!NS_IsMainThread() && aType && !aTypeString.IsEmpty()) || // non-main-thread aAllEvents, "Missing type"); // all-events listener if (!aListenerHolder || mClearingListeners) { return; } // Since there is no public API to call us with an EventListenerHolder, we // know that there's an EventListenerHolder on the stack holding a strong ref // to the listener. Listener* listener; uint32_t count = mListeners.Length(); for (uint32_t i = 0; i < count; i++) { listener = &mListeners.ElementAt(i); // mListener == aListenerHolder is the last one, since it can be a bit slow. if (listener->mListenerIsHandler == aHandler && listener->mFlags == aFlags && EVENT_TYPE_EQUALS(listener, aType, aTypeAtom, aTypeString, aAllEvents) && listener->mListener == aListenerHolder) { return; } } mNoListenerForEvent = NS_EVENT_NULL; mNoListenerForEventAtom = nullptr; listener = aAllEvents ? mListeners.InsertElementAt(0) : mListeners.AppendElement(); listener->mListener = aListenerHolder; MOZ_ASSERT(aType < PR_UINT16_MAX); listener->mEventType = aType; listener->mTypeString = aTypeString; listener->mTypeAtom = aTypeAtom; listener->mFlags = aFlags; listener->mListenerIsHandler = aHandler; listener->mHandlerIsString = false; listener->mAllEvents = aAllEvents; // Detect the type of event listener. nsCOMPtr<nsIXPConnectWrappedJS> wjs; if (aFlags.mListenerIsJSListener) { MOZ_ASSERT(!aListenerHolder.HasWebIDLCallback()); listener->mListenerType = Listener::eJSEventListener; } else if (aListenerHolder.HasWebIDLCallback()) { listener->mListenerType = Listener::eWebIDLListener; } else if ((wjs = do_QueryInterface(aListenerHolder.GetXPCOMCallback()))) { listener->mListenerType = Listener::eWrappedJSListener; } else { listener->mListenerType = Listener::eNativeListener; } if (aFlags.mInSystemGroup) { mMayHaveSystemGroupListeners = true; } if (aFlags.mCapture) { mMayHaveCapturingListeners = true; } if (aType == NS_AFTERPAINT) { mMayHavePaintEventListener = true; nsPIDOMWindow* window = GetInnerWindowForTarget(); if (window) { window->SetHasPaintEventListeners(); } } else if (aType >= NS_MUTATION_START && aType <= NS_MUTATION_END) { // For mutation listeners, we need to update the global bit on the DOM window. // Otherwise we won't actually fire the mutation event. mMayHaveMutationListeners = true; // Go from our target to the nearest enclosing DOM window. nsPIDOMWindow* window = GetInnerWindowForTarget(); if (window) { nsCOMPtr<nsIDocument> doc = window->GetExtantDoc(); if (doc) { doc->WarnOnceAbout(nsIDocument::eMutationEvent); } // If aType is NS_MUTATION_SUBTREEMODIFIED, we need to listen all // mutations. nsContentUtils::HasMutationListeners relies on this. window->SetMutationListeners((aType == NS_MUTATION_SUBTREEMODIFIED) ? kAllMutationBits : MutationBitForEventType(aType)); } } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) { EnableDevice(NS_DEVICE_ORIENTATION); } else if (aTypeAtom == nsGkAtoms::ondeviceproximity || aTypeAtom == nsGkAtoms::onuserproximity) { EnableDevice(NS_DEVICE_PROXIMITY); } else if (aTypeAtom == nsGkAtoms::ondevicelight) { EnableDevice(NS_DEVICE_LIGHT); } else if (aTypeAtom == nsGkAtoms::ondevicemotion) { EnableDevice(NS_DEVICE_MOTION); #ifdef MOZ_B2G } else if (aTypeAtom == nsGkAtoms::onmoztimechange) { nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow(); if (window) { window->EnableTimeChangeNotifications(); } } else if (aTypeAtom == nsGkAtoms::onmoznetworkupload) { nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow(); if (window) { window->EnableNetworkEvent(NS_NETWORK_UPLOAD_EVENT); } } else if (aTypeAtom == nsGkAtoms::onmoznetworkdownload) { nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow(); if (window) { window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT); } #endif // MOZ_B2G } else if (aTypeAtom == nsGkAtoms::ontouchstart || aTypeAtom == nsGkAtoms::ontouchend || aTypeAtom == nsGkAtoms::ontouchmove || aTypeAtom == nsGkAtoms::ontouchcancel) { mMayHaveTouchEventListener = true; nsPIDOMWindow* window = GetInnerWindowForTarget(); // we don't want touchevent listeners added by scrollbars to flip this flag // so we ignore listeners created with system event flag if (window && !aFlags.mInSystemGroup) { window->SetHasTouchEventListeners(); } } else if (aTypeAtom == nsGkAtoms::onwheel || aTypeAtom == nsGkAtoms::onDOMMouseScroll || aTypeAtom == nsHtml5Atoms::onmousewheel) { mMayHaveScrollWheelEventListener = true; nsPIDOMWindow* window = GetInnerWindowForTarget(); // we don't want touchevent listeners added by scrollbars to flip this flag // so we ignore listeners created with system event flag if (window && !aFlags.mInSystemGroup) { window->SetHasScrollWheelEventListeners(); } } else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) { nsPIDOMWindow* window = GetInnerWindowForTarget(); if (aTypeAtom == nsGkAtoms::onpointerenter || aTypeAtom == nsGkAtoms::onpointerleave) { mMayHavePointerEnterLeaveEventListener = true; if (window) { #ifdef DEBUG nsCOMPtr<nsIDocument> d = window->GetExtantDoc(); NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d), "Please do not use pointerenter/leave events in chrome. " "They are slower than pointerover/out!"); #endif window->SetHasPointerEnterLeaveEventListeners(); } } } else if (aTypeAtom == nsGkAtoms::onmouseenter || aTypeAtom == nsGkAtoms::onmouseleave) { mMayHaveMouseEnterLeaveEventListener = true; nsPIDOMWindow* window = GetInnerWindowForTarget(); if (window) { #ifdef DEBUG nsCOMPtr<nsIDocument> d = window->GetExtantDoc(); NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d), "Please do not use mouseenter/leave events in chrome. " "They are slower than mouseover/out!"); #endif window->SetHasMouseEnterLeaveEventListeners(); } #ifdef MOZ_GAMEPAD } else if (aType >= NS_GAMEPAD_START && aType <= NS_GAMEPAD_END) { nsPIDOMWindow* window = GetInnerWindowForTarget(); if (window) { window->SetHasGamepadEventListener(); } #endif } if (aTypeAtom && mTarget) { mTarget->EventListenerAdded(aTypeAtom); } }
NrIceResolver::~NrIceResolver() { MOZ_ASSERT(!allocated_resolvers_); delete vtbl_; }
nsresult EventListenerManager::SetEventHandler(nsIAtom* aName, const nsAString& aBody, bool aDeferCompilation, bool aPermitUntrustedEvents, Element* aElement) { nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIScriptGlobalObject> global = GetScriptGlobalAndDocument(getter_AddRefs(doc)); if (!global) { // This can happen; for example this document might have been // loaded as data. return NS_OK; } #ifdef DEBUG nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(global); if (win) { MOZ_ASSERT(win->IsInnerWindow(), "We should not have an outer window here!"); } #endif nsresult rv = NS_OK; // return early preventing the event listener from being added // 'doc' is fetched above if (doc) { // Don't allow adding an event listener if the document is sandboxed // without 'allow-scripts'. if (doc->GetSandboxFlags() & SANDBOXED_SCRIPTS) { return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr<nsIContentSecurityPolicy> csp; rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp)); NS_ENSURE_SUCCESS(rv, rv); if (csp) { bool inlineOK = true; bool reportViolations = false; rv = csp->GetAllowsInlineScript(&reportViolations, &inlineOK); NS_ENSURE_SUCCESS(rv, rv); if (reportViolations) { // gather information to log with violation report nsIURI* uri = doc->GetDocumentURI(); nsAutoCString asciiSpec; if (uri) uri->GetAsciiSpec(asciiSpec); nsAutoString scriptSample, attr, tagName(NS_LITERAL_STRING("UNKNOWN")); aName->ToString(attr); nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mTarget)); if (domNode) domNode->GetNodeName(tagName); // build a "script sample" based on what we know about this element scriptSample.Assign(attr); scriptSample.AppendLiteral(" attribute on "); scriptSample.Append(tagName); scriptSample.AppendLiteral(" element"); csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_INLINE_SCRIPT, NS_ConvertUTF8toUTF16(asciiSpec), scriptSample, 0, EmptyString(), EmptyString()); } // return early if CSP wants us to block inline scripts if (!inlineOK) { return NS_OK; } } } // This might be the first reference to this language in the global // We must init the language before we attempt to fetch its context. if (NS_FAILED(global->EnsureScriptEnvironment())) { NS_WARNING("Failed to setup script environment for this language"); // but fall through and let the inevitable failure below handle it. } nsIScriptContext* context = global->GetScriptContext(); NS_ENSURE_TRUE(context, NS_ERROR_FAILURE); NS_ENSURE_STATE(global->GetGlobalJSObject()); Listener* listener = SetEventHandlerInternal(aName, EmptyString(), TypedEventHandler(), aPermitUntrustedEvents); if (!aDeferCompilation) { return CompileEventHandlerInternal(listener, &aBody, aElement); } return NS_OK; }
void LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion) { PROFILER_LABEL("LayerManagerComposite", "Render", js::ProfileEntry::Category::GRAPHICS); if (mDestroyed) { NS_WARNING("Call on destroyed layer manager"); return; } // At this time, it doesn't really matter if these preferences change // during the execution of the function; we should be safe in all // permutations. However, may as well just get the values onces and // then use them, just in case the consistency becomes important in // the future. bool invertVal = gfxPrefs::LayersEffectInvert(); bool grayscaleVal = gfxPrefs::LayersEffectGrayscale(); float contrastVal = gfxPrefs::LayersEffectContrast(); bool haveLayerEffects = (invertVal || grayscaleVal || contrastVal != 0.0); // Set LayerScope begin/end frame LayerScopeAutoFrame frame(PR_Now()); // Dump to console if (gfxPrefs::LayersDump()) { this->Dump(); } else if (profiler_feature_active("layersdump")) { std::stringstream ss; Dump(ss); profiler_log(ss.str().c_str()); } // Dump to LayerScope Viewer if (LayerScope::CheckSendable()) { // Create a LayersPacket, dump Layers into it and transfer the // packet('s ownership) to LayerScope. auto packet = MakeUnique<layerscope::Packet>(); layerscope::LayersPacket* layersPacket = packet->mutable_layers(); this->Dump(layersPacket); LayerScope::SendLayerDump(Move(packet)); } /** Our more efficient but less powerful alter ego, if one is available. */ RefPtr<Composer2D> composer2D; composer2D = mCompositor->GetWidget()->GetComposer2D(); // We can't use composert2D if we have layer effects if (!mTarget && !haveLayerEffects && gfxPrefs::Composer2DCompositionEnabled() && composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot, mCompositor->GetWidget(), mGeometryChanged)) { LayerScope::SetHWComposed(); if (mFPS) { double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now()); if (gfxPrefs::LayersDrawFPS()) { printf_stderr("HWComposer: FPS is %g\n", fps); } } mCompositor->EndFrameForExternalComposition(Matrix()); mLastFrameMissedHWC = false; return; } else if (!mTarget && !haveLayerEffects) { mLastFrameMissedHWC = !!composer2D; } { PROFILER_LABEL("LayerManagerComposite", "PreRender", js::ProfileEntry::Category::GRAPHICS); if (!mCompositor->GetWidget()->PreRender(this)) { return; } } ParentLayerIntRect clipRect; Rect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height); Rect actualBounds; CompositorBench(mCompositor, bounds); if (mRoot->GetClipRect()) { clipRect = *mRoot->GetClipRect(); Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); mCompositor->BeginFrame(aInvalidRegion, &rect, bounds, nullptr, &actualBounds); } else { gfx::Rect rect; mCompositor->BeginFrame(aInvalidRegion, nullptr, bounds, &rect, &actualBounds); clipRect = ParentLayerIntRect(rect.x, rect.y, rect.width, rect.height); } if (actualBounds.IsEmpty()) { mCompositor->GetWidget()->PostRender(this); return; } // Allow widget to render a custom background. mCompositor->GetWidget()->DrawWindowUnderlay(this, IntRect(actualBounds.x, actualBounds.y, actualBounds.width, actualBounds.height)); RefPtr<CompositingRenderTarget> previousTarget; if (haveLayerEffects) { previousTarget = PushGroupForLayerEffects(); } else { mTwoPassTmpTarget = nullptr; } // Render our layers. RootLayer()->Prepare(ViewAs<RenderTargetPixel>(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot)); RootLayer()->RenderLayer(clipRect.ToUnknownRect()); if (!mRegionToClear.IsEmpty()) { nsIntRegionRectIterator iter(mRegionToClear); const IntRect *r; while ((r = iter.Next())) { mCompositor->ClearRect(Rect(r->x, r->y, r->width, r->height)); } } if (mTwoPassTmpTarget) { MOZ_ASSERT(haveLayerEffects); PopGroupForLayerEffects(previousTarget, clipRect.ToUnknownRect(), grayscaleVal, invertVal, contrastVal); } // Allow widget to render a custom foreground. mCompositor->GetWidget()->DrawWindowOverlay( this, LayoutDeviceIntRect(actualBounds.x, actualBounds.y, actualBounds.width, actualBounds.height)); // Debugging RenderDebugOverlay(actualBounds); { PROFILER_LABEL("LayerManagerComposite", "EndFrame", js::ProfileEntry::Category::GRAPHICS); mCompositor->EndFrame(); mCompositor->SetDispAcquireFence(mRoot, mCompositor->GetWidget()); // Call after EndFrame() } if (composer2D) { composer2D->Render(mCompositor->GetWidget()); } mCompositor->GetWidget()->PostRender(this); RecordFrame(); }
nsresult EventListenerManager::CompileEventHandlerInternal(Listener* aListener, const nsAString* aBody, Element* aElement) { MOZ_ASSERT(aListener->GetJSEventHandler()); MOZ_ASSERT(aListener->mHandlerIsString, "Why are we compiling a non-string JS listener?"); JSEventHandler* jsEventHandler = aListener->GetJSEventHandler(); MOZ_ASSERT(!jsEventHandler->GetTypedEventHandler().HasEventHandler(), "What is there to compile?"); nsresult result = NS_OK; nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIScriptGlobalObject> global = GetScriptGlobalAndDocument(getter_AddRefs(doc)); NS_ENSURE_STATE(global); // Activate JSAPI, and make sure that exceptions are reported on the right // Window. AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(global))) { return NS_ERROR_UNEXPECTED; } jsapi.TakeOwnershipOfErrorReporting(); JSContext* cx = jsapi.cx(); nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom; nsIAtom* attrName = typeAtom; // Flag us as not a string so we don't keep trying to compile strings which // can't be compiled. aListener->mHandlerIsString = false; // mTarget may not be an Element if it's a window and we're // getting an inline event listener forwarded from <html:body> or // <html:frameset> or <xul:window> or the like. // XXX I don't like that we have to reference content from // here. The alternative is to store the event handler string on // the JSEventHandler itself, and that still doesn't address // the arg names issue. nsCOMPtr<Element> element = do_QueryInterface(mTarget); MOZ_ASSERT(element || aBody, "Where will we get our body?"); nsAutoString handlerBody; const nsAString* body = aBody; if (!aBody) { if (aListener->mTypeAtom == nsGkAtoms::onSVGLoad) { attrName = nsGkAtoms::onload; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGUnload) { attrName = nsGkAtoms::onunload; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGResize) { attrName = nsGkAtoms::onresize; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGScroll) { attrName = nsGkAtoms::onscroll; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGZoom) { attrName = nsGkAtoms::onzoom; } else if (aListener->mTypeAtom == nsGkAtoms::onbeginEvent) { attrName = nsGkAtoms::onbegin; } else if (aListener->mTypeAtom == nsGkAtoms::onrepeatEvent) { attrName = nsGkAtoms::onrepeat; } else if (aListener->mTypeAtom == nsGkAtoms::onendEvent) { attrName = nsGkAtoms::onend; } element->GetAttr(kNameSpaceID_None, attrName, handlerBody); body = &handlerBody; aElement = element; } aListener = nullptr; uint32_t lineNo = 0; nsAutoCString url (NS_LITERAL_CSTRING("-moz-evil:lying-event-listener")); MOZ_ASSERT(body); MOZ_ASSERT(aElement); nsIURI *uri = aElement->OwnerDoc()->GetDocumentURI(); if (uri) { uri->GetSpec(url); lineNo = 1; } nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget); uint32_t argCount; const char **argNames; nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(), typeAtom, win, &argCount, &argNames); JSAddonId *addonId = MapURIToAddonID(uri); // Wrap the event target, so that we can use it as the scope for the event // handler. Note that mTarget is different from aElement in the <body> case, // where mTarget is a Window. // // The wrapScope doesn't really matter here, because the target will create // its reflector in the proper scope, and then we'll enter that compartment. JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject()); JS::Rooted<JS::Value> v(cx); { JSAutoCompartment ac(cx, wrapScope); nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v, /* aAllowWrapping = */ false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } if (addonId) { JS::Rooted<JSObject*> vObj(cx, &v.toObject()); JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId)); if (!addonScope) { return NS_ERROR_FAILURE; } JSAutoCompartment ac(cx, addonScope); // Wrap our event target into the addon scope, since that's where we want to // do all our work. if (!JS_WrapValue(cx, &v)) { return NS_ERROR_FAILURE; } } JS::Rooted<JSObject*> target(cx, &v.toObject()); JSAutoCompartment ac(cx, target); // Now that we've entered the compartment we actually care about, create our // scope chain. Note that we start with |element|, not aElement, because // mTarget is different from aElement in the <body> case, where mTarget is a // Window, and in that case we do not want the scope chain to include the body // or the document. JS::AutoObjectVector scopeChain(cx); if (!nsJSUtils::GetScopeChainForElement(cx, element, scopeChain)) { return NS_ERROR_OUT_OF_MEMORY; } nsDependentAtomString str(attrName); // Most of our names are short enough that we don't even have to malloc // the JS string stuff, so don't worry about playing games with // refcounting XPCOM stringbuffers. JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length())); NS_ENSURE_TRUE(jsStr, NS_ERROR_OUT_OF_MEMORY); // Get the reflector for |aElement|, so that we can pass to setElement. if (NS_WARN_IF(!GetOrCreateDOMReflector(cx, target, aElement, &v))) { return NS_ERROR_FAILURE; } JS::CompileOptions options(cx); options.setIntroductionType("eventHandler") .setFileAndLine(url.get(), lineNo) .setVersion(JSVERSION_DEFAULT) .setElement(&v.toObject()) .setElementAttributeName(jsStr); JS::Rooted<JSObject*> handler(cx); result = nsJSUtils::CompileFunction(jsapi, scopeChain, options, nsAtomCString(typeAtom), argCount, argNames, *body, handler.address()); NS_ENSURE_SUCCESS(result, result); NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE); if (jsEventHandler->EventName() == nsGkAtoms::onerror && win) { nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback = new OnErrorEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr); jsEventHandler->SetHandler(handlerCallback); } else if (jsEventHandler->EventName() == nsGkAtoms::onbeforeunload && win) { nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback = new OnBeforeUnloadEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr); jsEventHandler->SetHandler(handlerCallback); } else { nsRefPtr<EventHandlerNonNull> handlerCallback = new EventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr); jsEventHandler->SetHandler(handlerCallback); } return result; }
void SetLocationForGlobal(JSObject *global, nsIURI *locationURI) { MOZ_ASSERT(global); CompartmentPrivate::Get(global)->SetLocationURI(locationURI); }
bool RasterImage::Decode(const IntSize& aSize, uint32_t aFlags, PlaybackType aPlaybackType) { MOZ_ASSERT(NS_IsMainThread()); if (mError) { return false; } // If we don't have a size yet, we can't do any other decoding. if (!mHasSize) { mWantFullDecode = true; return false; } // We're about to decode again, which may mean that some of the previous sizes // we've decoded at aren't useful anymore. We can allow them to expire from // the cache by unlocking them here. When the decode finishes, it will send an // invalidation that will cause all instances of this image to redraw. If this // image is locked, any surfaces that are still useful will become locked // again when LookupFrame touches them, and the remainder will eventually // expire. SurfaceCache::UnlockEntries(ImageKey(this)); // Determine which flags we need to decode this image with. DecoderFlags decoderFlags = DefaultDecoderFlags(); if (aFlags & FLAG_ASYNC_NOTIFY) { decoderFlags |= DecoderFlags::ASYNC_NOTIFY; } if (mTransient) { decoderFlags |= DecoderFlags::IMAGE_IS_TRANSIENT; } if (mHasBeenDecoded) { decoderFlags |= DecoderFlags::IS_REDECODE; } SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags); if (IsOpaque()) { // If there's no transparency, it doesn't matter whether we premultiply // alpha or not. surfaceFlags &= ~SurfaceFlags::NO_PREMULTIPLY_ALPHA; } // Create a decoder. RefPtr<IDecodingTask> task; if (mAnimationState && aPlaybackType == PlaybackType::eAnimated) { task = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this), mSourceBuffer, mSize, decoderFlags, surfaceFlags); } else { task = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this), mSourceBuffer, mSize, aSize, decoderFlags, surfaceFlags); } // Make sure DecoderFactory was able to create a decoder successfully. if (!task) { return false; } mDecodeCount++; // We're ready to decode; start the decoder. return LaunchDecodingTask(task, this, aFlags, mHasSourceData); }
BasicWaveFormCache::BasicWaveFormCache(uint32_t aSampleRate) : mSampleRate(aSampleRate) { MOZ_ASSERT(NS_IsMainThread()); }
RasterImage::HandleErrorWorker::HandleErrorWorker(RasterImage* aImage) : mImage(aImage) { MOZ_ASSERT(mImage, "Should have image"); }
nsresult RtspMediaResource::OnConnected(uint8_t aTrackIdx, nsIStreamingProtocolMetaData *meta) { if (mIsConnected) { for (uint32_t i = 0 ; i < mTrackBuffer.Length(); ++i) { mTrackBuffer[i]->Start(); } return NS_OK; } uint8_t tracks; mMediaStreamController->GetTotalTracks(&tracks); uint64_t duration = 0; for (int i = 0; i < tracks; ++i) { nsCString rtspTrackId("RtspTrack"); rtspTrackId.AppendInt(i); nsCOMPtr<nsIStreamingProtocolMetaData> trackMeta; mMediaStreamController->GetTrackMetaData(i, getter_AddRefs(trackMeta)); MOZ_ASSERT(trackMeta); trackMeta->GetDuration(&duration); // Here is a heuristic to estimate the slot size. // For video track, calculate the width*height. // For audio track, use the BUFFER_SLOT_DEFAULT_SIZE because the w*h is 0. // Finally clamp them into (BUFFER_SLOT_DEFAULT_SIZE,BUFFER_SLOT_MAX_SIZE) uint32_t w, h; uint32_t slotSize; trackMeta->GetWidth(&w); trackMeta->GetHeight(&h); slotSize = clamped((int32_t)(w * h), BUFFER_SLOT_DEFAULT_SIZE, BUFFER_SLOT_MAX_SIZE); mTrackBuffer.AppendElement(new RtspTrackBuffer(rtspTrackId.get(), i, slotSize)); mTrackBuffer[i]->Start(); } // If the duration is 0, imply the stream is live stream. if (duration) { // Not live stream. mRealTime = false; bool seekable = true; mDecoder->SetInfinite(false); mDecoder->SetTransportSeekable(seekable); mDecoder->SetDuration(duration); } else { // Live stream. // Check the preference "media.realtime_decoder.enabled". if (!Preferences::GetBool("media.realtime_decoder.enabled", false)) { // Give up, report error to media element. nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(mDecoder, &MediaDecoder::DecodeError); NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); return NS_ERROR_FAILURE; } else { mRealTime = true; bool seekable = false; mDecoder->SetInfinite(true); mDecoder->SetTransportSeekable(seekable); mDecoder->SetMediaSeekable(seekable); } } // Fires an initial progress event and sets up the stall counter so stall events // fire if no download occurs within the required time frame. mDecoder->Progress(false); MediaDecoderOwner* owner = mDecoder->GetMediaOwner(); NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE); dom::HTMLMediaElement* element = owner->GetMediaElement(); NS_ENSURE_TRUE(element, NS_ERROR_FAILURE); element->FinishDecoderSetup(mDecoder, this); mIsConnected = true; return NS_OK; }
void RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus, const ImageMetadata& aMetadata, const DecoderTelemetry& aTelemetry, Progress aProgress, const IntRect& aInvalidRect, const Maybe<uint32_t>& aFrameCount, DecoderFlags aDecoderFlags, SurfaceFlags aSurfaceFlags) { MOZ_ASSERT(NS_IsMainThread()); // If the decoder detected an error, log it to the error console. if (aStatus.mShouldReportError) { ReportDecoderError(); } // Record all the metadata the decoder gathered about this image. bool metadataOK = SetMetadata(aMetadata, aStatus.mWasMetadataDecode); if (!metadataOK) { // This indicates a serious error that requires us to discard all existing // surfaces and redecode to recover. We'll drop the results from this // decoder on the floor, since they aren't valid. RecoverFromInvalidFrames(mSize, FromSurfaceFlags(aSurfaceFlags)); return; } MOZ_ASSERT(mError || mHasSize || !aMetadata.HasSize(), "SetMetadata should've gotten a size"); if (!aStatus.mWasMetadataDecode && aStatus.mFinished) { // Flag that we've been decoded before. mHasBeenDecoded = true; } // Send out any final notifications. NotifyProgress(aProgress, aInvalidRect, aFrameCount, aDecoderFlags, aSurfaceFlags); if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) && mHasBeenDecoded && mAnimationState) { // We've finished a full decode of all animation frames and our AnimationState // has been notified about them all, so let it know not to expect anymore. mAnimationState->SetDoneDecoding(true); } // Do some telemetry if this isn't a metadata decode. if (!aStatus.mWasMetadataDecode) { if (aTelemetry.mChunkCount) { Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, aTelemetry.mChunkCount); } if (aStatus.mFinished) { Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME, int32_t(aTelemetry.mDecodeTime.ToMicroseconds())); if (aTelemetry.mSpeedHistogram) { Telemetry::Accumulate(*aTelemetry.mSpeedHistogram, aTelemetry.Speed()); } } } // Only act on errors if we have no usable frames from the decoder. if (aStatus.mHadError && (!mAnimationState || mAnimationState->KnownFrameCount() == 0)) { DoError(); } else if (aStatus.mWasMetadataDecode && !mHasSize) { DoError(); } // XXX(aosmond): Can we get this far without mFinished == true? if (aStatus.mFinished && aStatus.mWasMetadataDecode) { // If we were waiting to fire the load event, go ahead and fire it now. if (mLoadProgress) { NotifyForLoadEvent(*mLoadProgress); mLoadProgress = Nothing(); NotifyProgress(FLAG_ONLOAD_UNBLOCKED); } // If we were a metadata decode and a full decode was requested, do it. if (mWantFullDecode) { mWantFullDecode = false; RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT); } } }
static already_AddRefed<const webgl::LinkedProgramInfo> QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl) { WebGLContext* const webgl = prog->mContext; RefPtr<webgl::LinkedProgramInfo> info(new webgl::LinkedProgramInfo(prog)); GLuint maxAttribLenWithNull = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint*)&maxAttribLenWithNull); if (maxAttribLenWithNull < 1) maxAttribLenWithNull = 1; GLuint maxUniformLenWithNull = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint*)&maxUniformLenWithNull); if (maxUniformLenWithNull < 1) maxUniformLenWithNull = 1; GLuint maxUniformBlockLenWithNull = 0; if (gl->IsSupported(gl::GLFeature::uniform_buffer_object)) { gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, (GLint*)&maxUniformBlockLenWithNull); if (maxUniformBlockLenWithNull < 1) maxUniformBlockLenWithNull = 1; } GLuint maxTransformFeedbackVaryingLenWithNull = 0; if (gl->IsSupported(gl::GLFeature::transform_feedback2)) { gl->fGetProgramiv(prog->mGLName, LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, (GLint*)&maxTransformFeedbackVaryingLenWithNull); if (maxTransformFeedbackVaryingLenWithNull < 1) maxTransformFeedbackVaryingLenWithNull = 1; } #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("maxAttribLenWithNull: %d\n", maxAttribLenWithNull); printf_stderr("maxUniformLenWithNull: %d\n", maxUniformLenWithNull); printf_stderr("maxUniformBlockLenWithNull: %d\n", maxUniformBlockLenWithNull); #endif // Attribs GLuint numActiveAttribs = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, (GLint*)&numActiveAttribs); for (GLuint i = 0; i < numActiveAttribs; i++) { nsAutoCString mappedName; mappedName.SetLength(maxAttribLenWithNull - 1); GLsizei lengthWithoutNull = 0; GLint elemCount = 0; // `size` GLenum elemType = 0; // `type` gl->fGetActiveAttrib(prog->mGLName, i, mappedName.Length()+1, &lengthWithoutNull, &elemCount, &elemType, mappedName.BeginWriting()); GLenum error = gl->fGetError(); if (error != LOCAL_GL_NO_ERROR) { gfxCriticalNote << "Failed to do glGetActiveAttrib: " << error; } mappedName.SetLength(lengthWithoutNull); // Attribs can't be arrays, so we can skip some of the mess we have in the Uniform // path. nsDependentCString userName; if (!prog->FindAttribUserNameByMappedName(mappedName, &userName)) userName.Rebind(mappedName, 0); /////// const GLint loc = gl->fGetAttribLocation(prog->mGLName, mappedName.BeginReading()); if (loc == -1) { MOZ_ASSERT(mappedName == "gl_InstanceID", "Active attrib should have a location."); continue; } #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("[attrib %i: %i] %s/%s\n", i, loc, mappedName.BeginReading(), userName.BeginReading()); printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull); #endif /////// const bool isArray = false; const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount, elemType, isArray, userName, mappedName); const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc)}; info->attribs.push_back(attrib); } // Uniforms const bool needsCheckForArrays = gl->WorkAroundDriverBugs(); GLuint numActiveUniforms = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORMS, (GLint*)&numActiveUniforms); for (GLuint i = 0; i < numActiveUniforms; i++) { nsAutoCString mappedName; mappedName.SetLength(maxUniformLenWithNull - 1); GLsizei lengthWithoutNull = 0; GLint elemCount = 0; // `size` GLenum elemType = 0; // `type` gl->fGetActiveUniform(prog->mGLName, i, mappedName.Length()+1, &lengthWithoutNull, &elemCount, &elemType, mappedName.BeginWriting()); mappedName.SetLength(lengthWithoutNull); /////// nsAutoCString baseMappedName; bool isArray; size_t arrayIndex; if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex)) MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver."); // Note that for good drivers, `isArray` should already be correct. // However, if FindUniform succeeds, it will be validator-guaranteed correct. /////// nsAutoCString baseUserName; if (!prog->FindUniformByMappedName(baseMappedName, &baseUserName, &isArray)) { // Validator likely missing. baseUserName = baseMappedName; if (needsCheckForArrays && !isArray) { // By GLES 3, GetUniformLocation("foo[0]") should return -1 if `foo` is // not an array. Our current linux Try slaves return the location of `foo` // anyways, though. std::string mappedNameStr = baseMappedName.BeginReading(); mappedNameStr += "[0]"; GLint loc = gl->fGetUniformLocation(prog->mGLName, mappedNameStr.c_str()); if (loc != -1) isArray = true; } } /////// #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("[uniform %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(), (int)isArray, baseMappedName.BeginReading(), baseUserName.BeginReading()); printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull); printf_stderr(" isArray: %d\n", (int)isArray); #endif /////// const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount, elemType, isArray, baseUserName, baseMappedName); auto* uniform = new webgl::UniformInfo(activeInfo); info->uniforms.push_back(uniform); if (uniform->mSamplerTexList) { info->uniformSamplers.push_back(uniform); } } // Uniform Blocks // (no sampler types allowed!) if (gl->IsSupported(gl::GLFeature::uniform_buffer_object)) { GLuint numActiveUniformBlocks = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_UNIFORM_BLOCKS, (GLint*)&numActiveUniformBlocks); for (GLuint i = 0; i < numActiveUniformBlocks; i++) { nsAutoCString mappedName; mappedName.SetLength(maxUniformBlockLenWithNull - 1); GLint lengthWithoutNull; gl->fGetActiveUniformBlockiv(prog->mGLName, i, LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH, &lengthWithoutNull); gl->fGetActiveUniformBlockName(prog->mGLName, i, maxUniformBlockLenWithNull, &lengthWithoutNull, mappedName.BeginWriting()); mappedName.SetLength(lengthWithoutNull); nsAutoCString baseMappedName; bool isArray; size_t arrayIndex; if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex)) MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver."); nsAutoCString baseUserName; if (!prog->FindUniformBlockByMappedName(baseMappedName, &baseUserName, &isArray)) { baseUserName = baseMappedName; if (needsCheckForArrays && !isArray) { std::string mappedNameStr = baseMappedName.BeginReading(); mappedNameStr += "[0]"; GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName, mappedNameStr.c_str()); if (loc != LOCAL_GL_INVALID_INDEX) isArray = true; } } //// GLuint dataSize = 0; gl->fGetActiveUniformBlockiv(prog->mGLName, i, LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE, (GLint*)&dataSize); #ifdef DUMP_SHADERVAR_MAPPINGS printf_stderr("[uniform block %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(), (int)isArray, baseMappedName.BeginReading(), baseUserName.BeginReading()); printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull); printf_stderr(" isArray: %d\n", (int)isArray); #endif auto* block = new webgl::UniformBlockInfo(webgl, baseUserName, baseMappedName, dataSize); info->uniformBlocks.push_back(block); } } // Transform feedback varyings if (gl->IsSupported(gl::GLFeature::transform_feedback2)) { GLuint numTransformFeedbackVaryings = 0; gl->fGetProgramiv(prog->mGLName, LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS, (GLint*)&numTransformFeedbackVaryings); for (GLuint i = 0; i < numTransformFeedbackVaryings; i++) { nsAutoCString mappedName; mappedName.SetLength(maxTransformFeedbackVaryingLenWithNull - 1); GLint lengthWithoutNull; GLsizei elemCount; GLenum elemType; gl->fGetTransformFeedbackVarying(prog->mGLName, i, maxTransformFeedbackVaryingLenWithNull, &lengthWithoutNull, &elemCount, &elemType, mappedName.BeginWriting()); mappedName.SetLength(lengthWithoutNull); //// nsAutoCString baseMappedName; bool isArray; size_t arrayIndex; if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex)) MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver."); nsAutoCString baseUserName; if (!prog->FindVaryingByMappedName(mappedName, &baseUserName, &isArray)) { baseUserName = baseMappedName; if (needsCheckForArrays && !isArray) { std::string mappedNameStr = baseMappedName.BeginReading(); mappedNameStr += "[0]"; GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName, mappedNameStr.c_str()); if (loc != LOCAL_GL_INVALID_INDEX) isArray = true; } } //// const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount, elemType, isArray, baseUserName, mappedName); info->transformFeedbackVaryings.push_back(activeInfo); } } // Frag outputs prog->EnumerateFragOutputs(info->fragDataMap); return info.forget(); }
void VorbisDataDecoder::ProcessDrain() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); mCallback->DrainComplete(); }