void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
    switch (node->op()) {
    case SetLocal: {
        VariableAccessData* variable = node->variableAccessData();
        m_availability.operand(variable->local()) =
            Availability(node->child1().node(), variable->flushedAt());
        break;
    }

    case GetArgument: {
        VariableAccessData* variable = node->variableAccessData();
        m_availability.operand(variable->local()) =
            Availability(node, variable->flushedAt());
        break;
    }

    case MovHint: {
        m_availability.operand(node->unlinkedLocal()) =
            Availability(node->child1().node());
        break;
    }

    case ZombieHint: {
        m_availability.operand(node->unlinkedLocal()) =
            Availability::unavailable();
        break;
    }

    default:
        break;
    }
}
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
    switch (node->op()) {
    case PutLocal: {
        VariableAccessData* variable = node->variableAccessData();
        m_availability.m_locals.operand(variable->local()).setFlush(variable->flushedAt());
        break;
    }
        
    case KillLocal: {
        m_availability.m_locals.operand(node->unlinkedLocal()).setFlush(FlushedAt(ConflictingFlush));
        break;
    }

    case GetLocal: {
        VariableAccessData* variable = node->variableAccessData();
        m_availability.m_locals.operand(variable->local()) =
            Availability(node, variable->flushedAt());
        break;
    }

    case MovHint: {
        m_availability.m_locals.operand(node->unlinkedLocal()).setNode(node->child1().node());
        break;
    }

    case ZombieHint: {
        m_availability.m_locals.operand(node->unlinkedLocal()).setNodeUnavailable();
        break;
    }
        
    case LoadVarargs: {
        LoadVarargsData* data = node->loadVarargsData();
        m_availability.m_locals.operand(data->count) =
            Availability(FlushedAt(FlushedInt32, data->machineCount));
        for (unsigned i = data->limit; i--;) {
            m_availability.m_locals.operand(VirtualRegister(data->start.offset() + i)) =
                Availability(FlushedAt(FlushedJSValue, VirtualRegister(data->machineStart.offset() + i)));
        }
        break;
    }
        
    default:
        break;
    }
    
    promoteHeapAccess(
        node,
        [&] (PromotedHeapLocation location, Edge value) {
            m_availability.m_heap.set(location, Availability(value.node()));
        },
        [&] (PromotedHeapLocation) { });
}
void AvailabilityMap::merge(const AvailabilityMap& other)
{
    for (unsigned i = other.m_locals.size(); i--;)
        m_locals[i] = other.m_locals[i].merge(m_locals[i]);
    
    for (auto pair : other.m_heap) {
        auto result = m_heap.add(pair.key, Availability());
        result.iterator->value = pair.value.merge(result.iterator->value);
    }
}
    bool run()
    {
        ASSERT(m_graph.m_form == SSA);
        
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            block->ssa->availabilityAtHead.clear();
            block->ssa->availabilityAtTail.clear();
        }
        
        BasicBlock* root = m_graph.block(0);
        root->ssa->availabilityAtHead.m_locals.fill(Availability::unavailable());
        for (unsigned argument = m_graph.m_argumentFormats.size(); argument--;) {
            FlushedAt flushedAt = FlushedAt(
                m_graph.m_argumentFormats[argument],
                virtualRegisterForArgument(argument));
            root->ssa->availabilityAtHead.m_locals.argument(argument) = Availability(flushedAt);
        }

        // This could be made more efficient by processing blocks in reverse postorder.
        
        LocalOSRAvailabilityCalculator calculator;
        bool changed;
        do {
            changed = false;
            
            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
                BasicBlock* block = m_graph.block(blockIndex);
                if (!block)
                    continue;
                
                calculator.beginBlock(block);
                
                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
                    calculator.executeNode(block->at(nodeIndex));
                
                if (calculator.m_availability == block->ssa->availabilityAtTail)
                    continue;
                
                block->ssa->availabilityAtTail = calculator.m_availability;
                changed = true;
                
                for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
                    BasicBlock* successor = block->successor(successorIndex);
                    successor->ssa->availabilityAtHead.merge(calculator.m_availability);
                    successor->ssa->availabilityAtHead.pruneByLiveness(
                        m_graph, successor->firstOrigin().forExit);
                }
            }
        } while (changed);
        
        return true;
    }
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
    switch (node->op()) {
    case SetLocal: {
        VariableAccessData* variable = node->variableAccessData();
        m_availability.m_locals.operand(variable->local()) =
            Availability(node->child1().node(), variable->flushedAt());
        break;
    }

    case GetArgument: {
        VariableAccessData* variable = node->variableAccessData();
        m_availability.m_locals.operand(variable->local()) =
            Availability(node, variable->flushedAt());
        break;
    }

    case MovHint: {
        m_availability.m_locals.operand(node->unlinkedLocal()) =
            Availability(node->child1().node());
        break;
    }

    case ZombieHint: {
        m_availability.m_locals.operand(node->unlinkedLocal()) =
            Availability::unavailable();
        break;
    }
        
    default:
        break;
    }
    
    promoteHeapAccess(
        node,
        [&] (PromotedHeapLocation location, Edge value) {
            m_availability.m_heap.set(location, Availability(value.node()));
        },
        [&] (PromotedHeapLocation) { });
}
示例#6
0
/* static */ already_AddRefed<IDecodingTask>
DecoderFactory::CreateDecoder(DecoderType aType,
                              NotNull<RasterImage*> aImage,
                              NotNull<SourceBuffer*> aSourceBuffer,
                              const IntSize& aIntrinsicSize,
                              const IntSize& aOutputSize,
                              DecoderFlags aDecoderFlags,
                              SurfaceFlags aSurfaceFlags)
{
  if (aType == DecoderType::UNKNOWN) {
    return nullptr;
  }

  // Create an anonymous decoder. Interaction with the SurfaceCache and the
  // owning RasterImage will be mediated by DecodedSurfaceProvider.
  RefPtr<Decoder> decoder =
    GetDecoder(aType, nullptr, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
  MOZ_ASSERT(decoder, "Should have a decoder now");

  // Initialize the decoder.
  decoder->SetMetadataDecode(false);
  decoder->SetIterator(aSourceBuffer->Iterator());
  decoder->SetOutputSize(aOutputSize);
  decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
  decoder->SetSurfaceFlags(aSurfaceFlags);

  if (NS_FAILED(decoder->Init())) {
    return nullptr;
  }

  // Create a DecodedSurfaceProvider which will manage the decoding process and
  // make this decoder's output available in the surface cache.
  SurfaceKey surfaceKey =
    RasterSurfaceKey(aOutputSize, aSurfaceFlags, PlaybackType::eStatic);
  auto provider = MakeNotNull<RefPtr<DecodedSurfaceProvider>>(
    aImage, surfaceKey, WrapNotNull(decoder));
  if (aDecoderFlags & DecoderFlags::CANNOT_SUBSTITUTE) {
    provider->Availability().SetCannotSubstitute();
  }

  // Attempt to insert the surface provider into the surface cache right away so
  // we won't trigger any more decoders with the same parameters.
  if (SurfaceCache::Insert(provider) != InsertOutcome::SUCCESS) {
    return nullptr;
  }

  // Return the surface provider in its IDecodingTask guise.
  RefPtr<IDecodingTask> task = provider.get();
  return task.forget();
}
bool
DecodedSurfaceProvider::IsFinished() const
{
  // See DrawableRef() for commentary on these assertions.
  if (Availability().IsPlaceholder()) {
    MOZ_ASSERT_UNREACHABLE("Calling IsFinished() on a placeholder");
    return false;
  }

  if (!mSurface) {
    MOZ_ASSERT_UNREACHABLE("Calling IsFinished() when we have no surface");
    return false;
  }

  return mSurface->IsFinished();
}
bool
AnimationSurfaceProvider::IsFinished() const
{
  MutexAutoLock lock(mFramesMutex);

  if (Availability().IsPlaceholder()) {
    MOZ_ASSERT_UNREACHABLE("Calling IsFinished() on a placeholder");
    return false;
  }

  if (mFrames.IsEmpty()) {
    MOZ_ASSERT_UNREACHABLE("Calling IsFinished() when we have no frames");
    return false;
  }

  // As long as we have at least one finished frame, we're finished.
  return mFrames[0]->IsFinished();
}
void
DecodedSurfaceProvider::SetLocked(bool aLocked)
{
  // See DrawableRef() for commentary on these assertions.
  if (Availability().IsPlaceholder()) {
    MOZ_ASSERT_UNREACHABLE("Calling SetLocked() on a placeholder");
    return;
  }

  if (!mSurface) {
    MOZ_ASSERT_UNREACHABLE("Calling SetLocked() when we have no surface");
    return;
  }

  if (aLocked == IsLocked()) {
    return;  // Nothing to do.
  }

  // If we're locked, hold a DrawableFrameRef to |mSurface|, which will keep any
  // volatile buffer it owns in memory.
  mLockRef = aLocked ? mSurface->DrawableRef()
                     : DrawableFrameRef();
}
DrawableFrameRef
DecodedSurfaceProvider::DrawableRef(size_t aFrame)
{
  MOZ_ASSERT(aFrame == 0,
             "Requesting an animation frame from a DecodedSurfaceProvider?");

  // We depend on SurfaceCache::SurfaceAvailable() to provide synchronization
  // for methods that touch |mSurface|; after SurfaceAvailable() is called,
  // |mSurface| should be non-null and shouldn't be mutated further until we get
  // destroyed. That means that the assertions below are very important; we'll
  // end up with data races if these assumptions are violated.
  if (Availability().IsPlaceholder()) {
    MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() on a placeholder");
    return DrawableFrameRef();
  }

  if (!mSurface) {
    MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() when we have no surface");
    return DrawableFrameRef();
  }

  return mSurface->DrawableRef();
}
DrawableFrameRef
AnimationSurfaceProvider::DrawableRef(size_t aFrame)
{
  MutexAutoLock lock(mFramesMutex);

  if (Availability().IsPlaceholder()) {
    MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() on a placeholder");
    return DrawableFrameRef();
  }

  if (mFrames.IsEmpty()) {
    MOZ_ASSERT_UNREACHABLE("Calling DrawableRef() when we have no frames");
    return DrawableFrameRef();
  }

  // If we don't have that frame, return an empty frame ref.
  if (aFrame >= mFrames.Length()) {
    return DrawableFrameRef();
  }

  // We've got the requested frame. Return it.
  MOZ_ASSERT(mFrames[aFrame]);
  return mFrames[aFrame]->DrawableRef();
}
    bool run()
    {
        ASSERT(m_graph.m_form == SSA);

        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            block->ssa->availabilityAtHead.clear();
            block->ssa->availabilityAtTail.clear();
        }

        BasicBlock* root = m_graph.block(0);
        root->ssa->availabilityAtHead.m_locals.fill(Availability::unavailable());
        for (unsigned argument = m_graph.m_argumentFormats.size(); argument--;) {
            FlushedAt flushedAt = FlushedAt(
                m_graph.m_argumentFormats[argument],
                virtualRegisterForArgument(argument));
            root->ssa->availabilityAtHead.m_locals.argument(argument) = Availability(flushedAt);
        }

        // This could be made more efficient by processing blocks in reverse postorder.

        LocalOSRAvailabilityCalculator calculator(m_graph);
        bool changed;
        do {
            changed = false;

            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
                BasicBlock* block = m_graph.block(blockIndex);
                if (!block)
                    continue;

                calculator.beginBlock(block);

                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
                    calculator.executeNode(block->at(nodeIndex));

                if (calculator.m_availability == block->ssa->availabilityAtTail)
                    continue;

                block->ssa->availabilityAtTail = calculator.m_availability;
                changed = true;

                for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
                    BasicBlock* successor = block->successor(successorIndex);
                    successor->ssa->availabilityAtHead.merge(calculator.m_availability);
                    successor->ssa->availabilityAtHead.pruneByLiveness(
                        m_graph, successor->at(0)->origin.forExit);
                }
            }
        } while (changed);

        if (validationEnabled()) {

            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
                BasicBlock* block = m_graph.block(blockIndex);
                if (!block)
                    continue;

                calculator.beginBlock(block);

                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                    if (block->at(nodeIndex)->origin.exitOK) {
                        // If we're allowed to exit here, the heap must be in a state
                        // where exiting wouldn't crash. These particular fields are
                        // required for correctness because we use them during OSR exit
                        // to do meaningful things. It would be wrong for any of them
                        // to be dead.

                        AvailabilityMap availabilityMap = calculator.m_availability;
                        availabilityMap.pruneByLiveness(m_graph, block->at(nodeIndex)->origin.forExit);

                        for (auto heapPair : availabilityMap.m_heap) {
                            switch (heapPair.key.kind()) {
                            case ActivationScopePLoc:
                            case ActivationSymbolTablePLoc:
                            case FunctionActivationPLoc:
                            case FunctionExecutablePLoc:
                            case StructurePLoc:
                                if (heapPair.value.isDead()) {
                                    dataLogLn("PromotedHeapLocation is dead, but should not be: ", heapPair.key);
                                    availabilityMap.dump(WTF::dataFile());
                                    CRASH();
                                }
                                break;

                            default:
                                break;
                            }
                        }
                    }

                    calculator.executeNode(block->at(nodeIndex));
                }
            }
        }

        return true;
    }
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
    switch (node->op()) {
    case PutStack: {
        StackAccessData* data = node->stackAccessData();
        m_availability.m_locals.operand(data->local).setFlush(data->flushedAt());
        break;
    }

    case KillStack: {
        m_availability.m_locals.operand(node->unlinkedLocal()).setFlush(FlushedAt(ConflictingFlush));
        break;
    }

    case GetStack: {
        StackAccessData* data = node->stackAccessData();
        m_availability.m_locals.operand(data->local) = Availability(node, data->flushedAt());
        break;
    }

    case MovHint: {
        m_availability.m_locals.operand(node->unlinkedLocal()).setNode(node->child1().node());
        break;
    }

    case ZombieHint: {
        m_availability.m_locals.operand(node->unlinkedLocal()).setNodeUnavailable();
        break;
    }

    case LoadVarargs:
    case ForwardVarargs: {
        LoadVarargsData* data = node->loadVarargsData();
        m_availability.m_locals.operand(data->count) =
            Availability(FlushedAt(FlushedInt32, data->machineCount));
        for (unsigned i = data->limit; i--;) {
            m_availability.m_locals.operand(VirtualRegister(data->start.offset() + i)) =
                Availability(FlushedAt(FlushedJSValue, VirtualRegister(data->machineStart.offset() + i)));
        }
        break;
    }

    case PhantomCreateRest:
    case PhantomDirectArguments:
    case PhantomClonedArguments: {
        InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
        if (!inlineCallFrame) {
            // We don't need to record anything about how the arguments are to be recovered. It's just a
            // given that we can read them from the stack.
            break;
        }

        unsigned numberOfArgumentsToSkip = 0;
        if (node->op() == PhantomCreateRest)
            numberOfArgumentsToSkip = node->numberOfArgumentsToSkip();

        if (inlineCallFrame->isVarargs()) {
            // Record how to read each argument and the argument count.
            Availability argumentCount =
                m_availability.m_locals.operand(inlineCallFrame->stackOffset + CallFrameSlot::argumentCount);

            m_availability.m_heap.set(PromotedHeapLocation(ArgumentCountPLoc, node), argumentCount);
        }

        if (inlineCallFrame->isClosureCall) {
            Availability callee = m_availability.m_locals.operand(
                inlineCallFrame->stackOffset + CallFrameSlot::callee);
            m_availability.m_heap.set(PromotedHeapLocation(ArgumentsCalleePLoc, node), callee);
        }

        for (unsigned i = numberOfArgumentsToSkip; i < inlineCallFrame->arguments.size() - 1; ++i) {
            Availability argument = m_availability.m_locals.operand(
                inlineCallFrame->stackOffset + CallFrame::argumentOffset(i));

            m_availability.m_heap.set(PromotedHeapLocation(ArgumentPLoc, node, i), argument);
        }
        break;
    }

    case PutHint: {
        m_availability.m_heap.set(
            PromotedHeapLocation(node->child1().node(), node->promotedLocationDescriptor()),
            Availability(node->child2().node()));
        break;
    }

    case PhantomSpread:
        m_availability.m_heap.set(PromotedHeapLocation(SpreadPLoc, node), Availability(node->child1().node()));
        break;

    case PhantomNewArrayWithSpread:
        for (unsigned i = 0; i < node->numChildren(); i++) {
            Node* child = m_graph.varArgChild(node, i).node();
            m_availability.m_heap.set(PromotedHeapLocation(NewArrayWithSpreadArgumentPLoc, node, i), Availability(child));
        }
        break;

    default:
        break;
    }
}
/*!
    \qmlproperty enumeration QtMultimedia::Audio::availability

    Returns the availability state of the media player.

    This is one of:
    \table
    \header \li Value \li Description
    \row \li Available
        \li The media player is available to use.
    \row \li Busy
        \li The media player is usually available, but some other
           process is utilizing the hardware necessary to play media.
    \row \li Unavailable
        \li There are no supported media playback facilities.
    \row \li ResourceMissing
        \li There is one or more resources missing, so the media player cannot
           be used.  It may be possible to try again at a later time.
    \endtable
 */
QDeclarativeAudio::Availability QDeclarativeAudio::availability() const
{
    if (!m_player)
        return Unavailable;
    return Availability(m_player->availability());
}
 bool run()
 {
     ASSERT(m_graph.m_form == SSA);
     
     for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
         BasicBlock* block = m_graph.block(blockIndex);
         if (!block)
             continue;
         block->ssa->availabilityAtHead.fill(Availability());
         block->ssa->availabilityAtTail.fill(Availability());
     }
     
     BasicBlock* root = m_graph.block(0);
     for (unsigned argument = root->ssa->availabilityAtHead.numberOfArguments(); argument--;) {
         root->ssa->availabilityAtHead.argument(argument) =
             Availability::unavailable().withFlush(
                 FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
     }
     for (unsigned local = root->ssa->availabilityAtHead.numberOfLocals(); local--;)
         root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
     
     if (m_graph.m_plan.mode == FTLForOSREntryMode) {
         for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;) {
             root->ssa->availabilityAtHead.local(local) =
                 Availability::unavailable().withFlush(
                     FlushedAt(FlushedJSValue, virtualRegisterForLocal(local)));
         }
     }
     
     // This could be made more efficient by processing blocks in reverse postorder.
     Operands<Availability> availability;
     bool changed;
     do {
         changed = false;
         
         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
             BasicBlock* block = m_graph.block(blockIndex);
             if (!block)
                 continue;
             
             availability = block->ssa->availabilityAtHead;
             
             for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                 Node* node = block->at(nodeIndex);
                 
                 switch (node->op()) {
                 case SetLocal: {
                     VariableAccessData* variable = node->variableAccessData();
                     availability.operand(variable->local()) =
                         Availability(node->child1().node(), variable->flushedAt());
                     break;
                 }
                     
                 case GetArgument: {
                     VariableAccessData* variable = node->variableAccessData();
                     availability.operand(variable->local()) =
                         Availability(node, variable->flushedAt());
                     break;
                 }
                     
                 case MovHint:
                 case MovHintAndCheck: {
                     VariableAccessData* variable = node->variableAccessData();
                     availability.operand(variable->local()) =
                         Availability(node->child1().node());
                     break;
                 }
                     
                 case ZombieHint: {
                     VariableAccessData* variable = node->variableAccessData();
                     availability.operand(variable->local()) = Availability::unavailable();
                     break;
                 }
                     
                 default:
                     break;
                 }
             }
             
             if (availability == block->ssa->availabilityAtTail)
                 continue;
             
             block->ssa->availabilityAtTail = availability;
             changed = true;
             
             for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
                 BasicBlock* successor = block->successor(successorIndex);
                 for (unsigned i = availability.size(); i--;) {
                     successor->ssa->availabilityAtHead[i] = availability[i].merge(
                         successor->ssa->availabilityAtHead[i]);
                 }
             }
         }
     } while (changed);
     
     return true;
 }
void QDeclarativeCamera::_q_availabilityChanged(QMultimedia::AvailabilityStatus availability)
{
    emit availabilityChanged(Availability(availability));
}
    bool run()
    {
        ASSERT(m_graph.m_form == SSA);
        
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
            block->ssa->availabilityAtHead.fill(Availability());
            block->ssa->availabilityAtTail.fill(Availability());
        }
        
        BasicBlock* root = m_graph.block(0);
        for (unsigned argument = root->ssa->availabilityAtHead.numberOfArguments(); argument--;) {
            root->ssa->availabilityAtHead.argument(argument) =
                Availability::unavailable().withFlush(
                    FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
        }

        if (m_graph.m_plan.mode == FTLForOSREntryMode) {
            for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;)
                root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
        } else {
            for (unsigned local = root->ssa->availabilityAtHead.numberOfLocals(); local--;)
                root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
        }
        
        // This could be made more efficient by processing blocks in reverse postorder.
        
        LocalOSRAvailabilityCalculator calculator;
        bool changed;
        do {
            changed = false;
            
            for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
                BasicBlock* block = m_graph.block(blockIndex);
                if (!block)
                    continue;
                
                calculator.beginBlock(block);
                
                for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex)
                    calculator.executeNode(block->at(nodeIndex));
                
                if (calculator.m_availability == block->ssa->availabilityAtTail)
                    continue;
                
                block->ssa->availabilityAtTail = calculator.m_availability;
                changed = true;
                
                for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
                    BasicBlock* successor = block->successor(successorIndex);
                    for (unsigned i = calculator.m_availability.size(); i--;) {
                        successor->ssa->availabilityAtHead[i] =
                            calculator.m_availability[i].merge(
                                successor->ssa->availabilityAtHead[i]);
                    }
                }
            }
        } while (changed);
        
        return true;
    }
void AvailabilityMap::clear()
{
    m_locals.fill(Availability());
    m_heap.clear();
}
/*!
    \qmlproperty enumeration QtMultimedia::RadioData::availability

    Returns the availability state of the radio data interface.

    This is one of:

    \table
    \header \li Value \li Description
    \row \li Available
        \li The radio data interface is available to use
    \row \li Busy
        \li The radio data interface is usually available to use, but is currently busy.
    \row \li Unavailable
        \li The radio data interface is not available to use (there may be no radio
           hardware)
    \row \li ResourceMissing
        \li There is one or more resources missing, so the radio cannot
           be used.  It may be possible to try again at a later time.
    \endtable
 */
QDeclarativeRadioData::Availability QDeclarativeRadioData::availability() const
{
    return Availability(m_radioData->availability());
}
/*!
    \qmlproperty enumeration QtMultimedia::Camera::availability

    This property holds the availability state of the camera.

    The availability states can be one of the following:

    \table
    \header \li Value \li Description
    \row \li Available
        \li The camera is available to use
    \row \li Busy
        \li The camera is busy at the moment as it is being used by another process.
    \row \li Unavailable
        \li The camera is not available to use (there may be no camera
           hardware)
    \row \li ResourceMissing
        \li The camera cannot be used because of missing resources.
         It may be possible to try again at a later time.
    \endtable
 */
QDeclarativeCamera::Availability QDeclarativeCamera::availability() const
{
    return Availability(m_camera->availability());
}