void
AnimationSurfaceProvider::CheckForNewFrameAtTerminalState()
{
  mDecodingMutex.AssertCurrentThreadOwns();
  MOZ_ASSERT(mDecoder);

  bool justGotFirstFrame = false;

  {
    MutexAutoLock lock(mFramesMutex);

    RawAccessFrameRef frame = mDecoder->GetCurrentFrameRef();
    if (!frame) {
      return;
    }

    if (!mFrames.IsEmpty() && mFrames.LastElement().get() == frame.get()) {
      return;  // We already have this one.
    }

    // Append the new frame to the list.
    mFrames.AppendElement(Move(frame));

    if (mFrames.Length() == 1) {
      justGotFirstFrame = true;
    }
  }

  if (justGotFirstFrame) {
    AnnounceSurfaceAvailable();
  }
}
void
AnimationSurfaceProvider::CheckForNewFrameAtYield()
{
  mDecodingMutex.AssertCurrentThreadOwns();
  MOZ_ASSERT(mDecoder);

  bool justGotFirstFrame = false;

  {
    MutexAutoLock lock(mFramesMutex);

    // Try to get the new frame from the decoder.
    RawAccessFrameRef frame = mDecoder->GetCurrentFrameRef();
    if (!frame) {
      MOZ_ASSERT_UNREACHABLE("Decoder yielded but didn't produce a frame?");
      return;
    }

    // We should've gotten a different frame than last time.
    MOZ_ASSERT_IF(!mFrames.IsEmpty(),
                  mFrames.LastElement().get() != frame.get());

    // Append the new frame to the list.
    mFrames.AppendElement(Move(frame));

    if (mFrames.Length() == 1) {
      justGotFirstFrame = true;
    }
  }

  if (justGotFirstFrame) {
    AnnounceSurfaceAvailable();
  }
}