Example #1
0
void
VectorImage::OnSVGDocumentLoaded()
{
  MOZ_ASSERT(mSVGDocumentWrapper->GetRootSVGElem(),
             "Should have parsed successfully");
  MOZ_ASSERT(!mIsFullyLoaded && !mHaveAnimations,
             "These flags shouldn't get set until OnSVGDocumentLoaded. "
             "Duplicate calls to OnSVGDocumentLoaded?");

  CancelAllListeners();

  // XXX Flushing is wasteful if embedding frame hasn't had initial reflow.
  mSVGDocumentWrapper->FlushLayout();

  mIsFullyLoaded = true;
  mHaveAnimations = mSVGDocumentWrapper->IsAnimated();

  // Start listening to our image for rendering updates.
  mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);

  // Tell *our* observers that we're done loading.
  if (mProgressTracker) {
    mProgressTracker->SyncNotifyProgress(FLAG_SIZE_AVAILABLE |
                                         FLAG_HAS_TRANSPARENCY |
                                         FLAG_FRAME_COMPLETE |
                                         FLAG_DECODE_COMPLETE |
                                         FLAG_ONLOAD_UNBLOCKED,
                                         GetMaxSizedIntRect());
  }

  EvaluateAnimation();
}
Example #2
0
void
ImageResource::DecrementAnimationConsumers()
{
  NS_ABORT_IF_FALSE(mAnimationConsumers >= 1, "Invalid no. of animation consumers!");
  mAnimationConsumers--;
  EvaluateAnimation();
}
Example #3
0
//******************************************************************************
NS_IMETHODIMP
RasterImage::ResetAnimation()
{
  if (mError) {
    return NS_ERROR_FAILURE;
    }

  mPendingAnimation = false;

  if (mAnimationMode == kDontAnimMode || !mAnimationState ||
      mAnimationState->GetCurrentAnimationFrameIndex() == 0) {
    return NS_OK;
  }

  mAnimationFinished = false;

  if (mAnimating) {
    StopAnimation();
  }

  MOZ_ASSERT(mAnimationState, "Should have AnimationState");
  mAnimationState->ResetAnimation();

  NotifyProgress(NoProgress, mAnimationState->FirstFrameRefreshArea());

  // Start the animation again. It may not have been running before, if
  // mAnimationFinished was true before entering this function.
  EvaluateAnimation();

  return NS_OK;
}
Example #4
0
VectorImage::RequestRefresh(const TimeStamp& aTime)
{
  if (HadRecentRefresh(aTime)) {
    return;
  }

  EvaluateAnimation();

  mSVGDocumentWrapper->TickRefreshDriver();

  if (mHasPendingInvalidation) {
    SendInvalidationNotifications();
    mHasPendingInvalidation = false;
  }
}
Example #5
0
void
VectorImage::OnSVGDocumentLoaded()
{
  MOZ_ASSERT(mSVGDocumentWrapper->GetRootSVGElem(),
             "Should have parsed successfully");
  MOZ_ASSERT(!mIsFullyLoaded && !mHaveAnimations,
             "These flags shouldn't get set until OnSVGDocumentLoaded. "
             "Duplicate calls to OnSVGDocumentLoaded?");

  CancelAllListeners();

  // XXX Flushing is wasteful if embedding frame hasn't had initial reflow.
  mSVGDocumentWrapper->FlushLayout();

  mIsFullyLoaded = true;
  mHaveAnimations = mSVGDocumentWrapper->IsAnimated();

  // Start listening to our image for rendering updates.
  mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);

  // ProgressTracker::SyncNotifyProgress may release us, so ensure we
  // stick around long enough to complete our work.
  RefPtr<VectorImage> kungFuDeathGrip(this);

  // Tell *our* observers that we're done loading.
  if (mProgressTracker) {
    Progress progress = FLAG_SIZE_AVAILABLE |
                        FLAG_HAS_TRANSPARENCY |
                        FLAG_FRAME_COMPLETE |
                        FLAG_DECODE_COMPLETE |
                        FLAG_ONLOAD_UNBLOCKED;

    if (mHaveAnimations) {
      progress |= FLAG_IS_ANIMATED;
    }

    // Merge in any saved progress from OnImageDataComplete.
    if (mLoadProgress) {
      progress |= *mLoadProgress;
      mLoadProgress = Nothing();
    }

    mProgressTracker->SyncNotifyProgress(progress, GetMaxSizedIntRect());
  }

  EvaluateAnimation();
}
Example #6
0
nsresult
ImageResource::SetAnimationModeInternal(uint16_t aAnimationMode)
{
  if (mError)
    return NS_ERROR_FAILURE;

  NS_ASSERTION(aAnimationMode == kNormalAnimMode ||
               aAnimationMode == kDontAnimMode ||
               aAnimationMode == kLoopOnceAnimMode,
               "Wrong Animation Mode is being set!");

  mAnimationMode = aAnimationMode;

  EvaluateAnimation();

  return NS_OK;
}
Example #7
0
/* attribute unsigned short animationMode; */
NS_IMETHODIMP
Image::SetAnimationMode(PRUint16 aAnimationMode)
{
  if (mError)
    return NS_ERROR_FAILURE;

  NS_ASSERTION(aAnimationMode == kNormalAnimMode ||
               aAnimationMode == kDontAnimMode ||
               aAnimationMode == kLoopOnceAnimMode,
               "Wrong Animation Mode is being set!");
  
  mAnimationMode = aAnimationMode;

  EvaluateAnimation();

  return NS_OK;
}
Example #8
0
VectorImage::RequestRefresh(const TimeStamp& aTime)
{
  if (HadRecentRefresh(aTime)) {
    return;
  }

  PendingAnimationTracker* tracker =
    mSVGDocumentWrapper->GetDocument()->GetPendingAnimationTracker();
  if (tracker && ShouldAnimate()) {
    tracker->TriggerPendingAnimationsOnNextTick(aTime);
  }

  EvaluateAnimation();

  mSVGDocumentWrapper->TickRefreshDriver();

  if (mHasPendingInvalidation) {
    mHasPendingInvalidation = false;
    SendInvalidationNotifications();
  }
}
Example #9
0
/* void onStopRequest(in nsIRequest request, in nsISupports ctxt,
                      in nsresult status); */
NS_IMETHODIMP
VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
                           nsresult aStatus)
{
  if (mError)
    return NS_ERROR_FAILURE;

  NS_ABORT_IF_FALSE(!mIsFullyLoaded && !mHaveAnimations,
                    "these flags shouldn't get set until OnStopRequest. "
                    "Duplicate calls to OnStopRequest?");

  nsresult rv = mSVGDocumentWrapper->OnStopRequest(aRequest, aCtxt, aStatus);
  if (!mSVGDocumentWrapper->ParsedSuccessfully()) {
    // XXXdholbert Need to do something more here -- right now, this just
    // makes us draw the "object" icon, rather than the (jagged) "broken image"
    // icon.  See bug 594505.
    mError = true;
    return rv;
  }

  mIsFullyLoaded = true;
  mHaveAnimations = mSVGDocumentWrapper->IsAnimated();

  // Start listening to our image for rendering updates
  mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);

  // Tell *our* observers that we're done loading
  nsCOMPtr<imgIDecoderObserver> observer = do_QueryReferent(mObserver);
  if (observer) {
    // NOTE: This signals that width/height are available.
    observer->OnStartContainer(nsnull, this);

    observer->FrameChanged(this, &nsIntRect::GetMaxSizedIntRect());
    observer->OnStopFrame(nsnull, 0);
    observer->OnStopDecode(nsnull, NS_OK, nsnull);
  }
  EvaluateAnimation();

  return rv;
}
Example #10
0
void
ImageResource::IncrementAnimationConsumers()
{
  mAnimationConsumers++;
  EvaluateAnimation();
}
void USkeletalMeshComponent::RefreshBoneTransforms()
{
	SCOPE_CYCLE_COUNTER(STAT_RefreshBoneTransforms);

	// Can't do anything without a SkeletalMesh
	// Do nothing more if no bones in skeleton.
	if( !SkeletalMesh || SpaceBases.Num() == 0 )
	{
		return;
	}
	
	AActor * Owner = GetOwner();
	const FAnimUpdateRateParameters  & UpdateRateParams = Owner ? Owner->AnimUpdateRateParams : FAnimUpdateRateParameters();

	{
		FScopeLockPhysXWriter LockPhysXForWriting;

		// Recalculate the RequiredBones array, if necessary
		if( !bRequiredBonesUpToDate )
		{
			RecalcRequiredBones(PredictedLODLevel);
		}

		// Update rate turned off, evaluate every frame.
		if( !bEnableUpdateRateOptimizations || (UpdateRateParams.GetEvaluationRate() <= 1) )
		{
			// evaluate pure animations, and fill up LocalAtoms
			EvaluateAnimation();
			// We need the mesh space bone transforms now for renderer to get delta from ref pose:
			FillSpaceBases();
			// Invalidate cached bones.
			CachedLocalAtoms.Empty();
			CachedSpaceBases.Empty();
		}
		else
		{
			// figure out if our cache is invalid.
			const bool bInvalidCachedBones = (LocalAtoms.Num() != SkeletalMesh->RefSkeleton.GetNum()) 
				|| (LocalAtoms.Num() != CachedLocalAtoms.Num())
				|| (SpaceBases.Num() != CachedSpaceBases.Num());

			// If cache is invalid, we need to rebuild it. And we can't interpolate.
			// (same path if we're not interpolating and not skipping a frame).
			if( bInvalidCachedBones || (!UpdateRateParams.ShouldInterpolateSkippedFrames() && !UpdateRateParams.ShouldSkipEvaluation()) )
			{
				// evaluate pure animations, and fill up LocalAtoms
				EvaluateAnimation();
				// Fill SpaceBases from LocalAtoms
				FillSpaceBases();

				// Cache bones
				CachedLocalAtoms = LocalAtoms;
				CachedSpaceBases = SpaceBases;
			}
			else
			{
				// No interpolation, just copy
				// @todo: if we don't blend any physics, we could even skip the copy.
				if( !UpdateRateParams.ShouldInterpolateSkippedFrames() )
				{
					LocalAtoms = CachedLocalAtoms;
					SpaceBases = CachedSpaceBases;
				}
				else
				{
					// If we are not skipping evaluation this frame, refresh cache.
					if( !UpdateRateParams.ShouldSkipEvaluation() )
					{
						// Preserve LocalAtoms and SpaceBases, so we can keep interpolation.
						Exchange(LocalAtoms, CachedLocalAtoms);
						Exchange(SpaceBases, CachedSpaceBases);

						// evaluate pure animations, and fill up LocalAtoms
						EvaluateAnimation();
						// Fill SpaceBases from LocalAtoms
						FillSpaceBases();

						Exchange(LocalAtoms, CachedLocalAtoms);
						Exchange(SpaceBases, CachedSpaceBases);
					}

					// Interpolate
					{
						SCOPE_CYCLE_COUNTER(STAT_InterpolateSkippedFrames);
						const float Alpha = 0.25f + (1.f / float(FMath::Max(UpdateRateParams.GetEvaluationRate(), 2) * 2));
						FAnimationRuntime::LerpBoneTransforms(LocalAtoms, CachedLocalAtoms, Alpha, RequiredBones);
						FAnimationRuntime::LerpBoneTransforms(SpaceBases, CachedSpaceBases, Alpha, RequiredBones);
					}
				}
			}
		}

		// Transforms updated, cached local bounds are now out of date.
		InvalidateCachedBounds();

		// update physics data from animated data
		UpdateKinematicBonesToPhysics(false);
		UpdateRBJointMotors();
	}

	// @todo anim : hack TTP 224385	ANIM: Skeletalmesh double buffer
	// this is problem because intermediate buffer changes physics position as well
	// this causes issue where a half of frame, physics position is fixed with anim pose, and the other half is real simulated position
	// if you enable physics in tick, since that's before physics update, you'll get animation pose dominating physics pose, which isn't what you want. (Or what you'll see)
	// so do not update transform if physics is on. This problem will be solved by double buffer, when we keep one buffer for intermediate, and the other buffer for result query
	{
		FScopeLockPhysXReader LockPhysXForReading;

		if( !IsSimulatingPhysics() )
		{
			SCOPE_CYCLE_COUNTER(STAT_UpdateLocalToWorldAndOverlaps);
			
			// New bone positions need to be sent to render thread
			UpdateComponentToWorld();	

			// animation often change overlap. 
			UpdateOverlaps();
		}
	}

	MarkRenderDynamicDataDirty();
}