void BluetoothService::SetEnabled(bool aEnabled) { MOZ_ASSERT(NS_IsMainThread()); AutoInfallibleTArray<BluetoothParent*, 10> childActors; GetAllBluetoothActors(childActors); for (uint32_t index = 0; index < childActors.Length(); index++) { unused << childActors[index]->SendEnabled(aEnabled); } if (aEnabled) { BluetoothManagerList::ForwardIterator iter(mLiveManagers); nsString managerPath = NS_LITERAL_STRING("/"); /** * Re-register managers since table mBluetoothSignalObserverTable was * cleared after turned off bluetooth */ while (iter.HasMore()) { RegisterBluetoothSignalHandler(managerPath, (BluetoothSignalObserver*)iter.GetNext()); } } else { mBluetoothSignalObserverTable.Clear(); } /** * mEnabled: real status of bluetooth * aEnabled: expected status of bluetooth */ if (mEnabled == aEnabled) { NS_WARNING("Bluetooth has already been enabled/disabled before\ or the toggling is failed."); }
void ClientLayerManager::ForwardTransaction() { mPhase = PHASE_FORWARD; // forward this transaction's changeset to our LayerManagerComposite bool sent; AutoInfallibleTArray<EditReply, 10> replies; if (HasShadowManager() && mForwarder->EndTransaction(&replies, &sent)) { for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; switch (reply.type()) { case EditReply::TOpContentBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap")); const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap(); CompositableChild* compositableChild = static_cast<CompositableChild*>(obs.compositableChild()); ContentClientRemote* contentClient = static_cast<ContentClientRemote*>(compositableChild->GetCompositableClient()); MOZ_ASSERT(contentClient); contentClient->SwapBuffers(obs.frontUpdatedRegion()); break; } case EditReply::TOpTextureSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap")); const OpTextureSwap& ots = reply.get_OpTextureSwap(); CompositableChild* compositableChild = static_cast<CompositableChild*>(ots.compositableChild()); MOZ_ASSERT(compositableChild); compositableChild->GetCompositableClient() ->SetDescriptorFromReply(ots.textureId(), ots.image()); break; } default: NS_RUNTIMEABORT("not reached"); } } if (sent) { mNeedsComposite = false; } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); }
void BluetoothService::SetEnabled(bool aEnabled) { MOZ_ASSERT(NS_IsMainThread()); if (aEnabled == mEnabled) { // Nothing to do, maybe something failed. return; } mEnabled = aEnabled; AutoInfallibleTArray<BluetoothParent*, 10> childActors; GetAllBluetoothActors(childActors); for (uint32_t index = 0; index < childActors.Length(); index++) { unused << childActors[index]->SendEnabled(aEnabled); } BluetoothManagerList::ForwardIterator iter(mLiveManagers); while (iter.HasMore()) { if (NS_FAILED(iter.GetNext()->FireEnabledDisabledEvent(aEnabled))) { NS_WARNING("FireEnabledDisabledEvent failed!"); } } }
void BluetoothService::SetEnabled(bool aEnabled) { MOZ_ASSERT(NS_IsMainThread()); AutoInfallibleTArray<BluetoothParent*, 10> childActors; GetAllBluetoothActors(childActors); for (uint32_t index = 0; index < childActors.Length(); index++) { unused << childActors[index]->SendEnabled(aEnabled); } if (!aEnabled) { /** * Remove all handlers except BluetoothManager when turning off bluetooth * since it is possible that the event 'onAdapterAdded' would be fired after * BluetoothManagers of child process are registered. Please see Bug 827759 * for more details. */ mBluetoothSignalObserverTable.Enumerate( RemoveObserversExceptBluetoothManager, nullptr); } /** * mEnabled: real status of bluetooth * aEnabled: expected status of bluetooth */ if (mEnabled == aEnabled) { NS_WARNING("Bluetooth has already been enabled/disabled before\ or the toggling is failed."); }
// static bool PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject, NPIdentifier** aIdentifiers, uint32_t* aCount) { if (aObject->_class != GetClass()) { NS_ERROR("Don't know what kind of object this is!"); return false; } ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); if (object->invalidated) { NS_WARNING("Calling method on an invalidated object!"); return false; } ProtectedActor<PluginScriptableObjectParent> actor(object->parent); if (!actor) { return false; } NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject); if (!npn) { NS_ERROR("No netscape funcs!"); return false; } AutoInfallibleTArray<PPluginIdentifierParent*, 10> identifiers; bool success; if (!actor->CallEnumerate(&identifiers, &success)) { NS_WARNING("Failed to send message!"); return false; } if (!success) { return false; } *aCount = identifiers.Length(); if (!*aCount) { *aIdentifiers = nullptr; return true; } *aIdentifiers = (NPIdentifier*)npn->memalloc(*aCount * sizeof(NPIdentifier)); if (!*aIdentifiers) { NS_ERROR("Out of memory!"); return false; } for (uint32_t index = 0; index < *aCount; index++) { PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(identifiers[index]); (*aIdentifiers)[index] = id->ToNPIdentifier(); } return true; }
void ImageBridgeChild::EndTransaction() { MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?"); AutoEndTransaction _(mTxn); if (mTxn->IsEmpty()) { return; } AutoInfallibleTArray<CompositableOperation, 10> cset; cset.SetCapacity(mTxn->mOperations.size()); if (!mTxn->mOperations.empty()) { cset.AppendElements(&mTxn->mOperations.front(), mTxn->mOperations.size()); } ShadowLayerForwarder::PlatformSyncBeforeUpdate(); AutoInfallibleTArray<EditReply, 10> replies; if (mTxn->mSwapRequired) { if (!SendUpdate(cset, &replies)) { NS_WARNING("could not send async texture transaction"); return; } } else { // If we don't require a swap we can call SendUpdateNoSwap which // assumes that aReplies is empty (DEBUG assertion) if (!SendUpdateNoSwap(cset)) { NS_WARNING("could not send async texture transaction (no swap)"); return; } } for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; switch (reply.type()) { case EditReply::TOpTextureSwap: { const OpTextureSwap& ots = reply.get_OpTextureSwap(); CompositableChild* compositableChild = static_cast<CompositableChild*>(ots.compositableChild()); MOZ_ASSERT(compositableChild); compositableChild->GetCompositableClient() ->SetDescriptorFromReply(ots.textureId(), ots.image()); break; } default: NS_RUNTIMEABORT("not reached"); } } }
static nscoord ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState, nsIFrame *aDescendantFrame) { nsIFrame *ancestorFrame = aAncestorReflowState.frame->FirstInFlow(); if (aDescendantFrame == ancestorFrame) { return aAncestorReflowState.ComputedWidth(); } AutoInfallibleTArray<nsIFrame*, 16> frames; for (nsIFrame *f = aDescendantFrame; f != ancestorFrame; f = f->GetParent()->FirstInFlow()) { frames.AppendElement(f); } // This ignores the width contributions made by scrollbars, though in // reality we don't have any scrollbars on the sorts of devices on // which we use font inflation, so it's not a problem. But it may // occasionally cause problems when writing tests on desktop. uint32_t len = frames.Length(); nsHTMLReflowState *reflowStates = static_cast<nsHTMLReflowState*> (moz_xmalloc(sizeof(nsHTMLReflowState) * len)); nsPresContext *presContext = aDescendantFrame->PresContext(); for (uint32_t i = 0; i < len; ++i) { const nsHTMLReflowState &parentReflowState = (i == 0) ? aAncestorReflowState : reflowStates[i - 1]; nsIFrame *frame = frames[len - i - 1]; WritingMode wm = frame->GetWritingMode(); LogicalSize availSize = parentReflowState.ComputedSize(wm); availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; MOZ_ASSERT(frame->GetParent()->FirstInFlow() == parentReflowState.frame->FirstInFlow(), "bad logic in this function"); new (reflowStates + i) nsHTMLReflowState(presContext, parentReflowState, frame, availSize); } MOZ_ASSERT(reflowStates[len - 1].frame == aDescendantFrame, "bad logic in this function"); nscoord result = reflowStates[len - 1].ComputedWidth(); for (uint32_t i = len; i-- != 0; ) { reflowStates[i].~nsHTMLReflowState(); } moz_free(reflowStates); return result; }
// static bool PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject, NPIdentifier** aIdentifiers, uint32_t* aCount) { AssertPluginThread(); if (aObject->_class != GetClass()) { NS_RUNTIMEABORT("Don't know what kind of object this is!"); } ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject); if (object->invalidated) { NS_WARNING("Calling method on an invalidated object!"); return false; } ProtectedActor<PluginScriptableObjectChild> actor(object->parent); NS_ASSERTION(actor, "This shouldn't ever be null!"); NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); AutoInfallibleTArray<PPluginIdentifierChild*, 10> identifiers; bool success; actor->CallEnumerate(&identifiers, &success); if (!success) { return false; } *aCount = identifiers.Length(); if (!*aCount) { *aIdentifiers = nsnull; return true; } *aIdentifiers = reinterpret_cast<NPIdentifier*>( PluginModuleChild::sBrowserFuncs.memalloc(*aCount * sizeof(NPIdentifier))); if (!*aIdentifiers) { NS_ERROR("Out of memory!"); return false; } for (PRUint32 index = 0; index < *aCount; index++) { (*aIdentifiers)[index] = static_cast<PPluginIdentifierChild*>(identifiers[index]); } return true; }
void BluetoothService::SetEnabled(bool aEnabled) { MOZ_ASSERT(NS_IsMainThread()); AutoInfallibleTArray<BluetoothParent*, 10> childActors; GetAllBluetoothActors(childActors); for (uint32_t index = 0; index < childActors.Length(); index++) { unused << childActors[index]->SendEnabled(aEnabled); } if (aEnabled) { BluetoothManagerList::ForwardIterator iter(mLiveManagers); nsString managerPath = NS_LITERAL_STRING("/"); /** * Re-register managers since table mBluetoothSignalObserverTable was * cleared after turned off bluetooth */ while (iter.HasMore()) { RegisterBluetoothSignalHandler(managerPath, (BluetoothSignalObserver*)iter.GetNext()); } } else { mBluetoothSignalObserverTable.Clear(); } /** * mEnabled: real status of bluetooth * aEnabled: expected status of bluetooth */ if (mEnabled == aEnabled) { /** * The process of toggling should be over here, so we set gToggleInProgress * back to false here. Note that, we don't fire onenabled/ondisabled in * this case. */ NS_WARNING("Bluetooth has already been enabled/disabled before.\ Skip fire onenabled/ondisabled events here."); gToggleInProgress = false; return; }
static nscoord ComputeDescendantWidth(const nsHTMLReflowState& aAncestorReflowState, nsIFrame *aDescendantFrame) { nsIFrame *ancestorFrame = aAncestorReflowState.frame->GetFirstInFlow(); if (aDescendantFrame == ancestorFrame) { return aAncestorReflowState.ComputedWidth(); } AutoInfallibleTArray<nsIFrame*, 16> frames; for (nsIFrame *f = aDescendantFrame; f != ancestorFrame; f = f->GetParent()->GetFirstInFlow()) { frames.AppendElement(f); } PRUint32 len = frames.Length(); nsHTMLReflowState *reflowStates = static_cast<nsHTMLReflowState*> (moz_xmalloc(sizeof(nsHTMLReflowState) * len)); nsPresContext *presContext = aDescendantFrame->PresContext(); for (PRUint32 i = 0; i < len; ++i) { const nsHTMLReflowState &parentReflowState = (i == 0) ? aAncestorReflowState : reflowStates[i - 1]; nsSize availSize(parentReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE); nsIFrame *frame = frames[len - i - 1]; NS_ABORT_IF_FALSE(frame->GetParent()->GetFirstInFlow() == parentReflowState.frame->GetFirstInFlow(), "bad logic in this function"); new (reflowStates + i) nsHTMLReflowState(presContext, parentReflowState, frame, availSize); } NS_ABORT_IF_FALSE(reflowStates[len - 1].frame == aDescendantFrame, "bad logic in this function"); nscoord result = reflowStates[len - 1].ComputedWidth(); for (PRUint32 i = len; i-- != 0; ) { reflowStates[i].~nsHTMLReflowState(); } moz_free(reflowStates); return result; }
void BluetoothService::SetEnabled(bool aEnabled) { MOZ_ASSERT(NS_IsMainThread()); AutoInfallibleTArray<BluetoothParent*, 10> childActors; GetAllBluetoothActors(childActors); for (uint32_t index = 0; index < childActors.Length(); index++) { unused << childActors[index]->SendEnabled(aEnabled); } /** * mEnabled: real status of bluetooth * aEnabled: expected status of bluetooth */ if (mEnabled == aEnabled) { BT_WARNING("Bluetooth is already %s, or the toggling failed.", mEnabled ? "enabled" : "disabled"); } mEnabled = aEnabled; }
bool ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, const nsIntRegion& aRegionToClear, uint64_t aId, bool aScheduleComposite, uint32_t aPaintSequenceNumber, bool aIsRepeatTransaction, bool* aSent) { *aSent = false; MOZ_ASSERT(aId); PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation", js::ProfileEntry::Category::GRAPHICS); RenderTraceScope rendertrace("Foward Transaction", "000091"); NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?"); DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes(); if (mDiagnosticTypes != diagnostics) { mDiagnosticTypes = diagnostics; mTxn->AddEdit(OpSetDiagnosticTypes(diagnostics)); } AutoTxnEnd _(mTxn); if (mTxn->Empty() && !mTxn->RotationChanged() && !mWindowOverlayChanged) { MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?) and no rotation event, skipping Update()")); return true; } MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers...")); MOZ_LAYERS_LOG(("[LayersForwarder] building transaction...")); // We purposely add attribute-change ops to the final changeset // before we add paint ops. This allows layers to record the // attribute changes before new pixels arrive, which can be useful // for setting up back/front buffers. RenderTraceScope rendertrace2("Foward Transaction", "000092"); for (ShadowableLayerSet::const_iterator it = mTxn->mMutants.begin(); it != mTxn->mMutants.end(); ++it) { ShadowableLayer* shadow = *it; Layer* mutant = shadow->AsLayer(); NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?"); LayerAttributes attrs; CommonLayerAttributes& common = attrs.common(); common.visibleRegion() = mutant->GetVisibleRegion(); common.eventRegions() = mutant->GetEventRegions(); common.postXScale() = mutant->GetPostXScale(); common.postYScale() = mutant->GetPostYScale(); common.transform() = mutant->GetBaseTransform(); common.contentFlags() = mutant->GetContentFlags(); common.opacity() = mutant->GetOpacity(); common.useClipRect() = !!mutant->GetClipRect(); common.clipRect() = (common.useClipRect() ? *mutant->GetClipRect() : nsIntRect()); common.isFixedPosition() = mutant->GetIsFixedPosition(); common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor(); common.fixedPositionMargin() = mutant->GetFixedPositionMargins(); common.isStickyPosition() = mutant->GetIsStickyPosition(); if (mutant->GetIsStickyPosition()) { common.stickyScrollContainerId() = mutant->GetStickyScrollContainerId(); common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter(); common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner(); } common.scrollbarTargetContainerId() = mutant->GetScrollbarTargetContainerId(); common.scrollbarDirection() = mutant->GetScrollbarDirection(); common.mixBlendMode() = (int8_t)mutant->GetMixBlendMode(); common.forceIsolatedGroup() = mutant->GetForceIsolatedGroup(); if (Layer* maskLayer = mutant->GetMaskLayer()) { common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer()); } else { common.maskLayerChild() = nullptr; } common.maskLayerParent() = nullptr; common.animations() = mutant->GetAnimations(); common.invalidRegion() = mutant->GetInvalidRegion(); attrs.specific() = null_t(); mutant->FillSpecificAttributes(attrs.specific()); MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant)); mTxn->AddEdit(OpSetLayerAttributes(nullptr, Shadow(shadow), attrs)); } AutoInfallibleTArray<Edit, 10> cset; size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size(); NS_ABORT_IF_FALSE(nCsets > 0 || mWindowOverlayChanged, "should have bailed by now"); cset.SetCapacity(nCsets); if (!mTxn->mCset.empty()) { cset.AppendElements(&mTxn->mCset.front(), mTxn->mCset.size()); } // Paints after non-paint ops, including attribute changes. See // above. if (!mTxn->mPaints.empty()) { cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size()); } mWindowOverlayChanged = false; TargetConfig targetConfig(mTxn->mTargetBounds, mTxn->mTargetRotation, mTxn->mClientBounds, mTxn->mTargetOrientation, aRegionToClear); if (!IsSameProcess()) { MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send...")); PlatformSyncBeforeUpdate(); } profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END); if (mTxn->mSwapRequired) { MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); RenderTraceScope rendertrace3("Forward Transaction", "000093"); if (!HasShadowManager() || !mShadowManager->IPCOpen() || !mShadowManager->SendUpdate(cset, aId, targetConfig, mIsFirstPaint, aScheduleComposite, aPaintSequenceNumber, aIsRepeatTransaction, aReplies)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return false; } } else { // If we don't require a swap we can call SendUpdateNoSwap which // assumes that aReplies is empty (DEBUG assertion) MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction...")); RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093"); if (!HasShadowManager() || !mShadowManager->IPCOpen() || !mShadowManager->SendUpdateNoSwap(cset, aId, targetConfig, mIsFirstPaint, aPaintSequenceNumber, aScheduleComposite, aIsRepeatTransaction)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return false; } } *aSent = true; mIsFirstPaint = false; MOZ_LAYERS_LOG(("[LayersForwarder] ... done")); return true; }
void ClientLayerManager::ForwardTransaction(bool aScheduleComposite) { mPhase = PHASE_FORWARD; mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(); TimeStamp transactionStart; if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) { transactionStart = mTransactionIdAllocator->GetTransactionStart(); } else { transactionStart = mTransactionStart; } // forward this transaction's changeset to our LayerManagerComposite bool sent; AutoInfallibleTArray<EditReply, 10> replies; if (mForwarder->EndTransaction(&replies, mRegionToClear, mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber, mIsRepeatTransaction, transactionStart, &sent)) { for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; switch (reply.type()) { case EditReply::TOpContentBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap")); const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap(); CompositableClient* compositable = CompositableClient::FromIPDLActor(obs.compositableChild()); ContentClientRemote* contentClient = static_cast<ContentClientRemote*>(compositable); MOZ_ASSERT(contentClient); contentClient->SwapBuffers(obs.frontUpdatedRegion()); break; } case EditReply::TOpTextureSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap")); const OpTextureSwap& ots = reply.get_OpTextureSwap(); CompositableClient* compositable = CompositableClient::FromIPDLActor(ots.compositableChild()); MOZ_ASSERT(compositable); compositable->SetDescriptorFromReply(ots.textureId(), ots.image()); break; } case EditReply::TReturnReleaseFence: { const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence(); FenceHandle fence = rep.fence(); PTextureChild* child = rep.textureChild(); if (!fence.IsValid() || !child) { break; } RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child); if (texture) { texture->SetReleaseFenceHandle(fence); } break; } default: NS_RUNTIMEABORT("not reached"); } } if (sent) { mNeedsComposite = false; } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } if (!sent) { // Clear the transaction id so that it doesn't get returned // unless we forwarded to somewhere that doesn't actually // have a compositor. mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId); } mForwarder->RemoveTexturesIfNecessary(); mForwarder->SendPendingAsyncMessge(); mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); }
void nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, dom::Element* aTarget, dom::DocumentTimeline* aTimeline, AnimationPtrArray& aAnimations) { MOZ_ASSERT(aAnimations.IsEmpty(), "expect empty array"); ResolvedStyleCache resolvedStyles; const nsStyleDisplay *disp = aStyleContext->StyleDisplay(); nsRefPtr<nsStyleContext> styleWithoutAnimation; for (size_t animIdx = 0, animEnd = disp->mAnimationNameCount; animIdx != animEnd; ++animIdx) { const StyleAnimation& src = disp->mAnimations[animIdx]; // CSS Animations whose animation-name does not match a @keyframes rule do // not generate animation events. This includes when the animation-name is // "none" which is represented by an empty name in the StyleAnimation. // Since such animations neither affect style nor dispatch events, we do // not generate a corresponding Animation for them. nsCSSKeyframesRule* rule = src.GetName().IsEmpty() ? nullptr : mPresContext->StyleSet()->KeyframesRuleForName(src.GetName()); if (!rule) { continue; } nsRefPtr<CSSAnimation> dest = new CSSAnimation(aTimeline); aAnimations.AppendElement(dest); AnimationTiming timing; timing.mIterationDuration = TimeDuration::FromMilliseconds(src.GetDuration()); timing.mDelay = TimeDuration::FromMilliseconds(src.GetDelay()); timing.mIterationCount = src.GetIterationCount(); timing.mDirection = src.GetDirection(); timing.mFillMode = src.GetFillMode(); nsRefPtr<KeyframeEffectReadOnly> destEffect = new KeyframeEffectReadOnly(mPresContext->Document(), aTarget, aStyleContext->GetPseudoType(), timing, src.GetName()); dest->SetEffect(destEffect); if (src.GetPlayState() == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED) { dest->PauseFromStyle(); } else { dest->PlayFromStyle(); } // While current drafts of css3-animations say that later keyframes // with the same key entirely replace earlier ones (no cascading), // this is a bad idea and contradictory to the rest of CSS. So // we're going to keep all the keyframes for each key and then do // the replacement on a per-property basis rather than a per-rule // basis, just like everything else in CSS. AutoInfallibleTArray<KeyframeData, 16> sortedKeyframes; for (uint32_t ruleIdx = 0, ruleEnd = rule->StyleRuleCount(); ruleIdx != ruleEnd; ++ruleIdx) { css::Rule* cssRule = rule->GetStyleRuleAt(ruleIdx); MOZ_ASSERT(cssRule, "must have rule"); MOZ_ASSERT(cssRule->GetType() == css::Rule::KEYFRAME_RULE, "must be keyframe rule"); nsCSSKeyframeRule *kfRule = static_cast<nsCSSKeyframeRule*>(cssRule); const nsTArray<float> &keys = kfRule->GetKeys(); for (uint32_t keyIdx = 0, keyEnd = keys.Length(); keyIdx != keyEnd; ++keyIdx) { float key = keys[keyIdx]; // FIXME (spec): The spec doesn't say what to do with // out-of-range keyframes. We'll ignore them. if (0.0f <= key && key <= 1.0f) { KeyframeData *data = sortedKeyframes.AppendElement(); data->mKey = key; data->mIndex = ruleIdx; data->mRule = kfRule; } } } sortedKeyframes.Sort(KeyframeDataComparator()); if (sortedKeyframes.Length() == 0) { // no segments continue; } // Record the properties that are present in any keyframe rules we // are using. nsCSSPropertySet properties; for (uint32_t kfIdx = 0, kfEnd = sortedKeyframes.Length(); kfIdx != kfEnd; ++kfIdx) { css::Declaration *decl = sortedKeyframes[kfIdx].mRule->Declaration(); for (uint32_t propIdx = 0, propEnd = decl->Count(); propIdx != propEnd; ++propIdx) { nsCSSProperty prop = decl->GetPropertyAt(propIdx); if (prop != eCSSPropertyExtra_variable) { // CSS Variables are not animatable properties.AddProperty(prop); } } } for (nsCSSProperty prop = nsCSSProperty(0); prop < eCSSProperty_COUNT_no_shorthands; prop = nsCSSProperty(prop + 1)) { if (!properties.HasProperty(prop) || nsCSSProps::kAnimTypeTable[prop] == eStyleAnimType_None) { continue; } // Build a list of the keyframes to use for this property. This // means we need every keyframe with the property in it, except // for those keyframes where a later keyframe with the *same key* // also has the property. AutoInfallibleTArray<uint32_t, 16> keyframesWithProperty; float lastKey = 100.0f; // an invalid key for (uint32_t kfIdx = 0, kfEnd = sortedKeyframes.Length(); kfIdx != kfEnd; ++kfIdx) { KeyframeData &kf = sortedKeyframes[kfIdx]; if (!kf.mRule->Declaration()->HasProperty(prop)) { continue; } if (kf.mKey == lastKey) { // Replace previous occurrence of same key. keyframesWithProperty[keyframesWithProperty.Length() - 1] = kfIdx; } else { keyframesWithProperty.AppendElement(kfIdx); } lastKey = kf.mKey; } AnimationProperty &propData = *destEffect->Properties().AppendElement(); propData.mProperty = prop; propData.mWinsInCascade = true; KeyframeData *fromKeyframe = nullptr; nsRefPtr<nsStyleContext> fromContext; bool interpolated = true; for (uint32_t wpIdx = 0, wpEnd = keyframesWithProperty.Length(); wpIdx != wpEnd; ++wpIdx) { uint32_t kfIdx = keyframesWithProperty[wpIdx]; KeyframeData &toKeyframe = sortedKeyframes[kfIdx]; nsRefPtr<nsStyleContext> toContext = resolvedStyles.Get(mPresContext, aStyleContext, toKeyframe.mRule); if (fromKeyframe) { interpolated = interpolated && BuildSegment(propData.mSegments, prop, src, fromKeyframe->mKey, fromContext, fromKeyframe->mRule->Declaration(), toKeyframe.mKey, toContext); } else { if (toKeyframe.mKey != 0.0f) { // There's no data for this property at 0%, so use the // cascaded value above us. if (!styleWithoutAnimation) { styleWithoutAnimation = mPresContext->StyleSet()-> ResolveStyleWithoutAnimation(aTarget, aStyleContext, eRestyle_AllHintsWithAnimations); } interpolated = interpolated && BuildSegment(propData.mSegments, prop, src, 0.0f, styleWithoutAnimation, nullptr, toKeyframe.mKey, toContext); } } fromContext = toContext; fromKeyframe = &toKeyframe; } if (fromKeyframe->mKey != 1.0f) { // There's no data for this property at 100%, so use the // cascaded value above us. if (!styleWithoutAnimation) { styleWithoutAnimation = mPresContext->StyleSet()-> ResolveStyleWithoutAnimation(aTarget, aStyleContext, eRestyle_AllHintsWithAnimations); } interpolated = interpolated && BuildSegment(propData.mSegments, prop, src, fromKeyframe->mKey, fromContext, fromKeyframe->mRule->Declaration(), 1.0f, styleWithoutAnimation); } // If we failed to build any segments due to inability to // interpolate, remove the property from the animation. (It's not // clear if this is the right thing to do -- we could run some of // the segments, but it's really not clear whether we should skip // values (which?) or skip segments, so best to skip the whole // thing for now.) if (!interpolated) { destEffect->Properties().RemoveElementAt( destEffect->Properties().Length() - 1); } } } }
PRBool ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies) { NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?"); AutoTxnEnd _(mTxn); if (mTxn->Empty()) { MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?), skipping Update()")); return PR_TRUE; } MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers...")); for (PRUint32 i = 0; i < mTxn->mDyingBuffers.Length(); ++i) { DestroySharedSurface(&mTxn->mDyingBuffers[i]); } MOZ_LAYERS_LOG(("[LayersForwarder] building transaction...")); // We purposely add attribute-change ops to the final changeset // before we add paint ops. This allows layers to record the // attribute changes before new pixels arrive, which can be useful // for setting up back/front buffers. for (ShadowableLayerSet::const_iterator it = mTxn->mMutants.begin(); it != mTxn->mMutants.end(); ++it) { ShadowableLayer* shadow = *it; Layer* mutant = shadow->AsLayer(); NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?"); LayerAttributes attrs; CommonLayerAttributes& common = attrs.common(); common.visibleRegion() = mutant->GetVisibleRegion(); common.transform() = mutant->GetTransform(); common.contentFlags() = mutant->GetContentFlags(); common.opacity() = mutant->GetOpacity(); common.useClipRect() = !!mutant->GetClipRect(); common.clipRect() = (common.useClipRect() ? *mutant->GetClipRect() : nsIntRect()); common.isFixedPosition() = mutant->GetIsFixedPosition(); common.useTileSourceRect() = !!mutant->GetTileSourceRect(); common.tileSourceRect() = (common.useTileSourceRect() ? *mutant->GetTileSourceRect() : nsIntRect()); attrs.specific() = null_t(); mutant->FillSpecificAttributes(attrs.specific()); mTxn->AddEdit(OpSetLayerAttributes(NULL, Shadow(shadow), attrs)); } AutoInfallibleTArray<Edit, 10> cset; size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size(); NS_ABORT_IF_FALSE(nCsets > 0, "should have bailed by now"); cset.SetCapacity(nCsets); if (!mTxn->mCset.empty()) { cset.AppendElements(&mTxn->mCset.front(), mTxn->mCset.size()); } // Paints after non-paint ops, including attribute changes. See // above. if (!mTxn->mPaints.empty()) { cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size()); } MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send...")); PlatformSyncBeforeUpdate(); MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); if (!mShadowManager->SendUpdate(cset, aReplies)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return PR_FALSE; } MOZ_LAYERS_LOG(("[LayersForwarder] ... done")); return PR_TRUE; }
nsresult BluetoothService::HandleShutdown() { MOZ_ASSERT(NS_IsMainThread()); // This is a two phase shutdown. First we notify all child processes that // bluetooth is going away, and then we wait for them to acknowledge. Then we // close down all the bluetooth machinery. gInShutdown = true; Cleanup(); AutoInfallibleTArray<BluetoothParent*, 10> childActors; GetAllBluetoothActors(childActors); if (!childActors.IsEmpty()) { // Notify child processes that they should stop using bluetooth now. for (uint32_t index = 0; index < childActors.Length(); index++) { childActors[index]->BeginShutdown(); } // Create a timer to ensure that we don't wait forever for a child process // or the bluetooth threads to finish. If we don't get a timer or can't use // it for some reason then we skip all the waiting entirely since we really // can't afford to hang on shutdown. nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID); MOZ_ASSERT(timer); if (timer) { bool timeExceeded = false; if (NS_SUCCEEDED(timer->InitWithFuncCallback(ShutdownTimeExceeded, &timeExceeded, DEFAULT_SHUTDOWN_TIMER_MS, nsITimer::TYPE_ONE_SHOT))) { nsIThread* currentThread = NS_GetCurrentThread(); MOZ_ASSERT(currentThread); // Wait for those child processes to acknowledge. while (!timeExceeded && !childActors.IsEmpty()) { if (!NS_ProcessNextEvent(currentThread)) { MOZ_ASSERT(false, "Something horribly wrong here!"); break; } GetAllBluetoothActors(childActors); } if (NS_FAILED(timer->Cancel())) { MOZ_NOT_REACHED("Failed to cancel shutdown timer, this will crash!"); } } else { MOZ_ASSERT(false, "Failed to initialize shutdown timer!"); } } } if (IsEnabled() && NS_FAILED(StartStopBluetooth(false))) { MOZ_ASSERT(false, "Failed to deliver stop message!"); } return NS_OK; }
bool ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies) { SAMPLE_LABEL("ShadowLayerForwarder", "EndTranscation"); RenderTraceScope rendertrace("Foward Transaction", "000091"); NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to"); NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?"); AutoTxnEnd _(mTxn); if (mTxn->Empty()) { MOZ_LAYERS_LOG(("[LayersForwarder] 0-length cset (?), skipping Update()")); return true; } MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers...")); for (PRUint32 i = 0; i < mTxn->mDyingBuffers.Length(); ++i) { DestroySharedSurface(&mTxn->mDyingBuffers[i]); } MOZ_LAYERS_LOG(("[LayersForwarder] building transaction...")); // We purposely add attribute-change ops to the final changeset // before we add paint ops. This allows layers to record the // attribute changes before new pixels arrive, which can be useful // for setting up back/front buffers. RenderTraceScope rendertrace2("Foward Transaction", "000092"); for (ShadowableLayerSet::const_iterator it = mTxn->mMutants.begin(); it != mTxn->mMutants.end(); ++it) { ShadowableLayer* shadow = *it; Layer* mutant = shadow->AsLayer(); NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?"); LayerAttributes attrs; CommonLayerAttributes& common = attrs.common(); common.visibleRegion() = mutant->GetVisibleRegion(); common.transform() = mutant->GetTransform(); common.contentFlags() = mutant->GetContentFlags(); common.opacity() = mutant->GetOpacity(); common.useClipRect() = !!mutant->GetClipRect(); common.clipRect() = (common.useClipRect() ? *mutant->GetClipRect() : nsIntRect()); common.isFixedPosition() = mutant->GetIsFixedPosition(); if (Layer* maskLayer = mutant->GetMaskLayer()) { common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer()); } else { common.maskLayerChild() = NULL; } common.maskLayerParent() = NULL; attrs.specific() = null_t(); mutant->FillSpecificAttributes(attrs.specific()); mTxn->AddEdit(OpSetLayerAttributes(NULL, Shadow(shadow), attrs)); } AutoInfallibleTArray<Edit, 10> cset; size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size(); NS_ABORT_IF_FALSE(nCsets > 0, "should have bailed by now"); cset.SetCapacity(nCsets); if (!mTxn->mCset.empty()) { cset.AppendElements(&mTxn->mCset.front(), mTxn->mCset.size()); } // Paints after non-paint ops, including attribute changes. See // above. if (!mTxn->mPaints.empty()) { cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size()); } MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send...")); PlatformSyncBeforeUpdate(); if (mTxn->mSwapRequired) { MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); RenderTraceScope rendertrace3("Forward Transaction", "000093"); if (!mShadowManager->SendUpdate(cset, mIsFirstPaint, aReplies)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return false; } } else { // If we don't require a swap we can call SendUpdateNoSwap which // assumes that aReplies is empty (DEBUG assertion) MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction...")); RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093"); if (!mShadowManager->SendUpdateNoSwap(cset, mIsFirstPaint)) { MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!")); return false; } } mIsFirstPaint = false; MOZ_LAYERS_LOG(("[LayersForwarder] ... done")); return true; }
void ClientLayerManager::ForwardTransaction(bool aScheduleComposite) { TimeStamp start = TimeStamp::Now(); if (mForwarder->GetSyncObject()) { mForwarder->GetSyncObject()->FinalizeFrame(); } mPhase = PHASE_FORWARD; mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(); TimeStamp transactionStart; if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) { transactionStart = mTransactionIdAllocator->GetTransactionStart(); } else { transactionStart = mTransactionStart; } // forward this transaction's changeset to our LayerManagerComposite bool sent; AutoInfallibleTArray<EditReply, 10> replies; if (mForwarder->EndTransaction(&replies, mRegionToClear, mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber, mIsRepeatTransaction, transactionStart, &sent)) { for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; switch (reply.type()) { case EditReply::TOpContentBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap")); const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap(); CompositableClient* compositable = CompositableClient::FromIPDLActor(obs.compositableChild()); ContentClientRemote* contentClient = static_cast<ContentClientRemote*>(compositable); MOZ_ASSERT(contentClient); contentClient->SwapBuffers(obs.frontUpdatedRegion()); break; } default: NS_RUNTIMEABORT("not reached"); } } if (sent) { mNeedsComposite = false; } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } if (!sent) { // Clear the transaction id so that it doesn't get returned // unless we forwarded to somewhere that doesn't actually // have a compositor. mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId); } mForwarder->RemoveTexturesIfNecessary(); mForwarder->RemoveCompositablesIfNecessary(); mForwarder->SendPendingAsyncMessges(); mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); TabChild* window = mWidget->GetOwningTabChild(); if (window) { TimeStamp end = TimeStamp::Now(); window->DidRequestComposite(start, end); } }
void nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, InfallibleTArray<ElementAnimation>& aAnimations) { NS_ABORT_IF_FALSE(aAnimations.IsEmpty(), "expect empty array"); ResolvedStyleCache resolvedStyles; const nsStyleDisplay *disp = aStyleContext->StyleDisplay(); TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh(); for (uint32_t animIdx = 0, animEnd = disp->mAnimationNameCount; animIdx != animEnd; ++animIdx) { const nsAnimation& aSrc = disp->mAnimations[animIdx]; ElementAnimation& aDest = *aAnimations.AppendElement(); aDest.mName = aSrc.GetName(); aDest.mIterationCount = aSrc.GetIterationCount(); aDest.mDirection = aSrc.GetDirection(); aDest.mFillMode = aSrc.GetFillMode(); aDest.mPlayState = aSrc.GetPlayState(); aDest.mDelay = TimeDuration::FromMilliseconds(aSrc.GetDelay()); aDest.mStartTime = now; if (aDest.IsPaused()) { aDest.mPauseStart = now; } else { aDest.mPauseStart = TimeStamp(); } aDest.mIterationDuration = TimeDuration::FromMilliseconds(aSrc.GetDuration()); nsCSSKeyframesRule *rule = KeyframesRuleFor(aDest.mName); if (!rule) { // no segments continue; } // While current drafts of css3-animations say that later keyframes // with the same key entirely replace earlier ones (no cascading), // this is a bad idea and contradictory to the rest of CSS. So // we're going to keep all the keyframes for each key and then do // the replacement on a per-property basis rather than a per-rule // basis, just like everything else in CSS. AutoInfallibleTArray<KeyframeData, 16> sortedKeyframes; for (uint32_t ruleIdx = 0, ruleEnd = rule->StyleRuleCount(); ruleIdx != ruleEnd; ++ruleIdx) { css::Rule* cssRule = rule->GetStyleRuleAt(ruleIdx); NS_ABORT_IF_FALSE(cssRule, "must have rule"); NS_ABORT_IF_FALSE(cssRule->GetType() == css::Rule::KEYFRAME_RULE, "must be keyframe rule"); nsCSSKeyframeRule *kfRule = static_cast<nsCSSKeyframeRule*>(cssRule); const nsTArray<float> &keys = kfRule->GetKeys(); for (uint32_t keyIdx = 0, keyEnd = keys.Length(); keyIdx != keyEnd; ++keyIdx) { float key = keys[keyIdx]; // FIXME (spec): The spec doesn't say what to do with // out-of-range keyframes. We'll ignore them. // (And PercentageHashKey currently assumes we either ignore or // clamp them.) if (0.0f <= key && key <= 1.0f) { KeyframeData *data = sortedKeyframes.AppendElement(); data->mKey = key; data->mIndex = ruleIdx; data->mRule = kfRule; } } } sortedKeyframes.Sort(KeyframeDataComparator()); if (sortedKeyframes.Length() == 0) { // no segments continue; } // Record the properties that are present in any keyframe rules we // are using. nsCSSPropertySet properties; for (uint32_t kfIdx = 0, kfEnd = sortedKeyframes.Length(); kfIdx != kfEnd; ++kfIdx) { css::Declaration *decl = sortedKeyframes[kfIdx].mRule->Declaration(); for (uint32_t propIdx = 0, propEnd = decl->Count(); propIdx != propEnd; ++propIdx) { properties.AddProperty(decl->OrderValueAt(propIdx)); } } for (nsCSSProperty prop = nsCSSProperty(0); prop < eCSSProperty_COUNT_no_shorthands; prop = nsCSSProperty(prop + 1)) { if (!properties.HasProperty(prop) || nsCSSProps::kAnimTypeTable[prop] == eStyleAnimType_None) { continue; } // Build a list of the keyframes to use for this property. This // means we need every keyframe with the property in it, except // for those keyframes where a later keyframe with the *same key* // also has the property. AutoInfallibleTArray<uint32_t, 16> keyframesWithProperty; float lastKey = 100.0f; // an invalid key for (uint32_t kfIdx = 0, kfEnd = sortedKeyframes.Length(); kfIdx != kfEnd; ++kfIdx) { KeyframeData &kf = sortedKeyframes[kfIdx]; if (!kf.mRule->Declaration()->HasProperty(prop)) { continue; } if (kf.mKey == lastKey) { // Replace previous occurrence of same key. keyframesWithProperty[keyframesWithProperty.Length() - 1] = kfIdx; } else { keyframesWithProperty.AppendElement(kfIdx); } lastKey = kf.mKey; } AnimationProperty &propData = *aDest.mProperties.AppendElement(); propData.mProperty = prop; KeyframeData *fromKeyframe = nullptr; nsRefPtr<nsStyleContext> fromContext; bool interpolated = true; for (uint32_t wpIdx = 0, wpEnd = keyframesWithProperty.Length(); wpIdx != wpEnd; ++wpIdx) { uint32_t kfIdx = keyframesWithProperty[wpIdx]; KeyframeData &toKeyframe = sortedKeyframes[kfIdx]; nsRefPtr<nsStyleContext> toContext = resolvedStyles.Get(mPresContext, aStyleContext, toKeyframe.mRule); if (fromKeyframe) { interpolated = interpolated && BuildSegment(propData.mSegments, prop, aSrc, fromKeyframe->mKey, fromContext, fromKeyframe->mRule->Declaration(), toKeyframe.mKey, toContext); } else { if (toKeyframe.mKey != 0.0f) { // There's no data for this property at 0%, so use the // cascaded value above us. interpolated = interpolated && BuildSegment(propData.mSegments, prop, aSrc, 0.0f, aStyleContext, nullptr, toKeyframe.mKey, toContext); } } fromContext = toContext; fromKeyframe = &toKeyframe; } if (fromKeyframe->mKey != 1.0f) { // There's no data for this property at 100%, so use the // cascaded value above us. interpolated = interpolated && BuildSegment(propData.mSegments, prop, aSrc, fromKeyframe->mKey, fromContext, fromKeyframe->mRule->Declaration(), 1.0f, aStyleContext); } // If we failed to build any segments due to inability to // interpolate, remove the property from the animation. (It's not // clear if this is the right thing to do -- we could run some of // the segments, but it's really not clear whether we should skip // values (which?) or skip segments, so best to skip the whole // thing for now.) if (!interpolated) { aDest.mProperties.RemoveElementAt(aDest.mProperties.Length() - 1); } } } }
void ClientLayerManager::ForwardTransaction() { mPhase = PHASE_FORWARD; // forward this transaction's changeset to our LayerManagerComposite AutoInfallibleTArray<EditReply, 10> replies; if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies)) { for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) { const EditReply& reply = replies[i]; switch (reply.type()) { case EditReply::TOpContentBufferSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap")); const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap(); CompositableChild* compositableChild = static_cast<CompositableChild*>(obs.compositableChild()); ContentClientRemote* contentClient = static_cast<ContentClientRemote*>(compositableChild->GetCompositableClient()); MOZ_ASSERT(contentClient); contentClient->SwapBuffers(obs.frontUpdatedRegion()); break; } case EditReply::TOpTextureSwap: { MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap")); const OpTextureSwap& ots = reply.get_OpTextureSwap(); CompositableChild* compositableChild = static_cast<CompositableChild*>(ots.compositableChild()); MOZ_ASSERT(compositableChild); compositableChild->GetCompositableClient() ->SetDescriptorFromReply(ots.textureId(), ots.image()); break; } case EditReply::TReplyTextureRemoved: { // XXX - to manage reuse of gralloc buffers, we'll need to add some // glue code here to find the TextureClient and invoke a callback to // let the camera know that the gralloc buffer is not used anymore on // the compositor side and that it can reuse it. break; } default: NS_RUNTIMEABORT("not reached"); } } } else if (HasShadowManager()) { NS_WARNING("failed to forward Layers transaction"); } mPhase = PHASE_NONE; // this may result in Layers being deleted, which results in // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); }