예제 #1
0
bool
WMFVideoMFTManager::InitInternal(bool aForceD3D9)
{
  mUseHwAccel = false; // default value; changed if D3D setup succeeds.
  bool useDxva = InitializeDXVA(aForceD3D9);

  RefPtr<MFTDecoder> decoder(new MFTDecoder());

  HRESULT hr = decoder->Create(GetMFTGUID());
  NS_ENSURE_TRUE(SUCCEEDED(hr), false);

  RefPtr<IMFAttributes> attr(decoder->GetAttributes());
  UINT32 aware = 0;
  if (attr) {
    attr->GetUINT32(MF_SA_D3D_AWARE, &aware);
    attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads,
      WMFDecoderModule::GetNumDecoderThreads());
    hr = attr->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);
    if (SUCCEEDED(hr)) {
      LOG("Enabling Low Latency Mode");
    }
    else {
      LOG("Couldn't enable Low Latency Mode");
    }
  }

  if (useDxva) {
    if (aware) {
      // TODO: Test if I need this anywhere... Maybe on Vista?
      //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE);
      //NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
      MOZ_ASSERT(mDXVA2Manager);
      ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
      hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager);
      if (SUCCEEDED(hr)) {
        mUseHwAccel = true;
      } else {
        mDXVA2Manager = nullptr;
        mDXVAFailureReason = nsPrintfCString("MFT_MESSAGE_SET_D3D_MANAGER failed with code %X", hr);
      }
    }
    else {
      mDXVAFailureReason.AssignLiteral("Decoder returned false for MF_SA_D3D_AWARE");
    }
  }

  mDecoder = decoder;
  hr = SetDecoderMediaTypes();
  NS_ENSURE_TRUE(SUCCEEDED(hr), false);

  LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));

  // Just in case ConfigureVideoFrameGeometry() does not set these
  mVideoInfo = VideoInfo();
  mVideoStride = 0;
  mVideoWidth = 0;
  mVideoHeight = 0;
  mPictureRegion.SetEmpty();

  return true;
}
예제 #2
0
bool
WMFVideoMFTManager::InitInternal(bool aForceD3D9)
{
  mUseHwAccel = false; // default value; changed if D3D setup succeeds.
  bool useDxva = InitializeDXVA(aForceD3D9 ||
                                mStreamType == VP8 || mStreamType == VP9);

  RefPtr<MFTDecoder> decoder(new MFTDecoder());

  HRESULT hr = decoder->Create(GetMFTGUID());
  NS_ENSURE_TRUE(SUCCEEDED(hr), false);

  RefPtr<IMFAttributes> attr(decoder->GetAttributes());
  UINT32 aware = 0;
  if (attr) {
    attr->GetUINT32(MF_SA_D3D_AWARE, &aware);
    attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads,
      WMFDecoderModule::GetNumDecoderThreads());
    if (MediaPrefs::PDMWMFLowLatencyEnabled()) {
      hr = attr->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);
      if (SUCCEEDED(hr)) {
        LOG("Enabling Low Latency Mode");
      } else {
        LOG("Couldn't enable Low Latency Mode");
      }
    }
  }

  if (useDxva) {
    if (aware) {
      // TODO: Test if I need this anywhere... Maybe on Vista?
      //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE);
      //NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
      MOZ_ASSERT(mDXVA2Manager);
      ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager());
      hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager);
      if (SUCCEEDED(hr)) {
        mUseHwAccel = true;
      } else {
        mDXVA2Manager = nullptr;
        mDXVAFailureReason = nsPrintfCString("MFT_MESSAGE_SET_D3D_MANAGER failed with code %X", hr);
      }
    }
    else {
      mDXVAFailureReason.AssignLiteral("Decoder returned false for MF_SA_D3D_AWARE");
    }
  }

  if (!mUseHwAccel) {
    Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
                          uint32_t(media::MediaDecoderBackend::WMFSoftware));
  }

  mDecoder = decoder;
  hr = SetDecoderMediaTypes();
  NS_ENSURE_TRUE(SUCCEEDED(hr), false);

  LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));

  return true;
}
예제 #3
0
/* static */ RefPtr<AllocationWrapper::AllocateDecoderPromise>
AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams)
{
  // aParams.mConfig is guaranteed to stay alive during the lifetime of the
  // MediaDataDecoder, so keeping a pointer to the object is safe.
  const TrackInfo* config = &aParams.mConfig;
  RefPtr<TaskQueue> taskQueue = aParams.mTaskQueue;
  DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics;
  RefPtr<layers::ImageContainer> imageContainer = aParams.mImageContainer;
  RefPtr<layers::KnowsCompositor> knowsCompositor = aParams.mKnowsCompositor;
  RefPtr<GMPCrashHelper> crashHelper = aParams.mCrashHelper;
  CreateDecoderParams::UseNullDecoder useNullDecoder = aParams.mUseNullDecoder;
  CreateDecoderParams::NoWrapper noWrapper = aParams.mNoWrapper;
  TrackInfo::TrackType type = aParams.mType;
  MediaEventProducer<TrackInfo::TrackType>* onWaitingForKeyEvent =
    aParams.mOnWaitingForKeyEvent;
  CreateDecoderParams::OptionSet options = aParams.mOptions;
  CreateDecoderParams::VideoFrameRate rate = aParams.mRate;

  RefPtr<AllocateDecoderPromise> p =
    GlobalAllocPolicy::Instance(aParams.mType)
      .Alloc()
      ->Then(
        AbstractThread::GetCurrent(),
        __func__,
        [=](RefPtr<Token> aToken) {
          // result may not always be updated by PDMFactory::CreateDecoder
          // either when the creation succeeded or failed, as such it must be
          // initialized to a fatal error by default.
          MediaResult result = MediaResult(
            NS_ERROR_DOM_MEDIA_FATAL_ERR,
            nsPrintfCString("error creating %s decoder", TrackTypeToStr(type)));
          RefPtr<PDMFactory> pdm = new PDMFactory();
          CreateDecoderParams params{ *config,
                                      taskQueue,
                                      diagnostics,
                                      imageContainer,
                                      &result,
                                      knowsCompositor,
                                      crashHelper,
                                      useNullDecoder,
                                      noWrapper,
                                      type,
                                      onWaitingForKeyEvent,
                                      options,
                                      rate };
          RefPtr<MediaDataDecoder> decoder = pdm->CreateDecoder(params);
          if (decoder) {
            RefPtr<AllocationWrapper> wrapper =
              new AllocationWrapper(decoder.forget(), aToken.forget());
            return AllocateDecoderPromise::CreateAndResolve(wrapper, __func__);
          }
          return AllocateDecoderPromise::CreateAndReject(result, __func__);
        },
        []() {
          return AllocateDecoderPromise::CreateAndReject(
            MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                        "Allocation policy expired"),
            __func__);
        });
  return p;
}
예제 #4
0
bool
WebGLFramebuffer::ValidateAndInitAttachments(const char* funcName)
{
    MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
               mContext->mBoundReadFramebuffer == this);

    nsCString fbStatusInfo;
    const auto fbStatus = CheckFramebufferStatus(&fbStatusInfo);
    if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
        nsCString errorText = nsPrintfCString("Incomplete framebuffer: Status 0x%04x",
                                              fbStatus.get());
        if (fbStatusInfo.Length()) {
            errorText += ": ";
            errorText += fbStatusInfo;
        }

        mContext->ErrorInvalidFramebufferOperation("%s: %s.", funcName,
                                                   errorText.BeginReading());
        return false;
    }

    // Cool! We've checked out ok. Just need to initialize.

    // Check if we need to initialize anything
    {
        bool hasUninitializedAttachments = false;

        if (mColorAttachment0.HasImage() && IsDrawBuffer(0))
            hasUninitializedAttachments |= mColorAttachment0.HasUninitializedImageData();

        size_t i = 1;
        for (const auto& cur : mMoreColorAttachments) {
            if (cur.HasImage() && IsDrawBuffer(i))
                hasUninitializedAttachments |= cur.HasUninitializedImageData();

            ++i;
        }

        if (mDepthAttachment.HasImage())
            hasUninitializedAttachments |= mDepthAttachment.HasUninitializedImageData();
        if (mStencilAttachment.HasImage())
            hasUninitializedAttachments |= mStencilAttachment.HasUninitializedImageData();
        if (mDepthStencilAttachment.HasImage())
            hasUninitializedAttachments |= mDepthStencilAttachment.HasUninitializedImageData();

        if (!hasUninitializedAttachments)
            return true;
    }

    // Get buffer-bit-mask and color-attachment-mask-list
    uint32_t clearBits = 0;
    std::vector<GLenum> tempDrawBuffers(1 + mMoreColorAttachments.Size(), LOCAL_GL_NONE);

    if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
        clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
        tempDrawBuffers[0] = LOCAL_GL_COLOR_ATTACHMENT0;
    }

    size_t i = 1;
    for (const auto& cur : mMoreColorAttachments) {
        if (cur.HasUninitializedImageData() && IsDrawBuffer(i)) {
            clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
            tempDrawBuffers[i] = LOCAL_GL_COLOR_ATTACHMENT0 + i;
        }

        ++i;
    }

    if (mDepthAttachment.HasUninitializedImageData() ||
        mDepthStencilAttachment.HasUninitializedImageData())
    {
        clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
    }

    if (mStencilAttachment.HasUninitializedImageData() ||
        mDepthStencilAttachment.HasUninitializedImageData())
    {
        clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
    }

    mContext->MakeContextCurrent();

    const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) {
        const GLenum* ptr = nullptr;
        if (list.size()) {
            ptr = &(list[0]);
        }
        this->mContext->gl->fDrawBuffers(list.size(), ptr);
    };

    const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers;
    const bool hasDrawBuffers = (mContext->IsWebGL2() ||
                                 mContext->IsExtensionEnabled(drawBufferExt));

    if (hasDrawBuffers) {
        fnDrawBuffers(tempDrawBuffers);
    }

    // Clear!
    mContext->ForceClearFramebufferWithDefaultValues(clearBits, false);

    if (hasDrawBuffers) {
        fnDrawBuffers(mDrawBuffers);
    }

    // Mark all the uninitialized images as initialized.
    if (mDepthAttachment.HasUninitializedImageData())
        mDepthAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
    if (mStencilAttachment.HasUninitializedImageData())
        mStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
    if (mDepthStencilAttachment.HasUninitializedImageData())
        mDepthStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);

    if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) {
        mColorAttachment0.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);
    }

    i = 1;
    for (auto& cur : mMoreColorAttachments) {
        if (cur.HasUninitializedImageData() && IsDrawBuffer(i))
            cur.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData);

        ++i;
    }

    return true;
}
nsCString
DecoderDoctorDiagnostics::GetDescription() const
{
  nsCString s;
  switch (mDiagnosticsType) {
    case eUnsaved:
      s = "Unsaved diagnostics, cannot get accurate description";
      break;
    case eFormatSupportCheck:
      s = "format='";
      s += NS_ConvertUTF16toUTF8(mFormat).get();
      s += mCanPlay ? "', can play" : "', cannot play";
      if (mVideoNotSupported) {
        s+= ", but video format not supported";
      }
      if (mAudioNotSupported) {
        s+= ", but audio format not supported";
      }
      if (mWMFFailedToLoad) {
        s += ", Windows platform decoder failed to load";
      }
      if (mFFmpegFailedToLoad) {
        s += ", Linux platform decoder failed to load";
      }
      if (mGMPPDMFailedToStartup) {
        s += ", GMP PDM failed to startup";
      } else if (!mGMP.IsEmpty()) {
        s += ", Using GMP '";
        s += mGMP;
        s += "'";
      }
      break;
    case eMediaKeySystemAccessRequest:
      s = "key system='";
      s += NS_ConvertUTF16toUTF8(mKeySystem).get();
      s += mIsKeySystemSupported ? "', supported" : "', not supported";
      switch (mKeySystemIssue) {
        case eUnset:
          break;
        case eWidevineWithNoWMF:
          s += ", Widevine with no WMF";
          break;
      }
      break;
    case eEvent:
      s = nsPrintfCString("event domain %s result=%" PRIu32,
                          EventDomainString(mEvent.mDomain), static_cast<uint32_t>(mEvent.mResult));
      break;
    case eDecodeError:
      s = "decode error: ";
      s += mDecodeIssue.Description();
      s += ", src='";
      s += mDecodeIssueMediaSrc.IsEmpty() ? "<none>" : "<provided>";
      s += "'";
      break;
    case eDecodeWarning:
      s = "decode warning: ";
      s += mDecodeIssue.Description();
      s += ", src='";
      s += mDecodeIssueMediaSrc.IsEmpty() ? "<none>" : "<provided>";
      s += "'";
      break;
    default:
      MOZ_ASSERT_UNREACHABLE("Unexpected DiagnosticsType");
      s = "?";
      break;
  }
  return s;
}
예제 #6
0
NS_IMETHODIMP
nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes)
{
  nsresult rv;
  bool longName;

#ifdef XP_WIN
  nsAutoString pathName, leafName, rootName, suffix;
  rv = GetPath(pathName);
#else
  nsAutoCString pathName, leafName, rootName, suffix;
  rv = GetNativePath(pathName);
#endif
  if (NS_FAILED(rv)) {
    return rv;
  }

  longName = (pathName.Length() + kMaxSequenceNumberLength >
              kMaxFilenameLength);
  if (!longName) {
    rv = Create(aType, aAttributes);
    if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
      return rv;
    }
  }

#ifdef XP_WIN
  rv = GetLeafName(leafName);
  if (NS_FAILED(rv)) {
    return rv;
  }

  const int32_t lastDot = leafName.RFindChar(char16_t('.'));
#else
  rv = GetNativeLeafName(leafName);
  if (NS_FAILED(rv)) {
    return rv;
  }

  const int32_t lastDot = leafName.RFindChar('.');
#endif

  if (lastDot == kNotFound) {
    rootName = leafName;
  } else {
    suffix = Substring(leafName, lastDot);      // include '.'
    rootName = Substring(leafName, 0, lastDot); // strip suffix and dot
  }

  if (longName) {
    int32_t maxRootLength = (kMaxFilenameLength -
                             (pathName.Length() - leafName.Length()) -
                             suffix.Length() - kMaxSequenceNumberLength);

    // We cannot create an item inside a directory whose name is too long.
    // Also, ensure that at least one character remains after we truncate
    // the root name, as we don't want to end up with an empty leaf name.
    if (maxRootLength < 2) {
      return NS_ERROR_FILE_UNRECOGNIZED_PATH;
    }

#ifdef XP_WIN
    // ensure that we don't cut the name in mid-UTF16-character
    rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ?
                       maxRootLength - 1 : maxRootLength);
    SetLeafName(rootName + suffix);
#else
    if (NS_IsNativeUTF8()) {
      // ensure that we don't cut the name in mid-UTF8-character
      // (assume the name is valid UTF8 to begin with)
      while (UTF8traits::isInSeq(rootName[maxRootLength])) {
        --maxRootLength;
      }

      // Another check to avoid ending up with an empty leaf name.
      if (maxRootLength == 0 && suffix.IsEmpty()) {
        return NS_ERROR_FILE_UNRECOGNIZED_PATH;
      }
    }

    rootName.SetLength(maxRootLength);
    SetNativeLeafName(rootName + suffix);
#endif
    nsresult rv = Create(aType, aAttributes);
    if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
      return rv;
    }
  }

  for (int indx = 1; indx < 10000; ++indx) {
    // start with "Picture-1.jpg" after "Picture.jpg" exists
#ifdef XP_WIN
    SetLeafName(rootName +
                NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) +
                suffix);
#else
    SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
#endif
    rv = Create(aType, aAttributes);
    if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) {
      return rv;
    }
  }

  // The disk is full, sort of
  return NS_ERROR_FILE_TOO_BIG;
}
예제 #7
0
nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, PRBool set_default)
{
    if (!gHashTable.ops)
        return NS_ERROR_OUT_OF_MEMORY;

    PrefHashEntry* pref = static_cast<PrefHashEntry*>(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD));

    if (!pref)
        return NS_ERROR_OUT_OF_MEMORY;

    // new entry, better intialize
    if (!pref->key) {

        // initialize the pref entry
        pref->flags = type;
        pref->key = ArenaStrDup(key, &gPrefNameArena);
        memset(&pref->defaultPref, 0, sizeof(pref->defaultPref));
        memset(&pref->userPref, 0, sizeof(pref->userPref));
    }
    else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) !=
                 (type & PREF_VALUETYPE_MASK))
    {
        NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get());
        return NS_ERROR_UNEXPECTED;
    }

    PRBool valueChanged = PR_FALSE;
    if (set_default)
    {
        if (!PREF_IS_LOCKED(pref))
        {       /* ?? change of semantics? */
            if (pref_ValueChanged(pref->defaultPref, value, type) ||
                !(pref->flags & PREF_HAS_DEFAULT))
            {
                pref_SetValue(&pref->defaultPref, value, type);
                pref->flags |= PREF_HAS_DEFAULT;
                if (!PREF_HAS_USER_VALUE(pref))
                    valueChanged = PR_TRUE;
            }
        }
    }
    else
    {
        /* If new value is same as the default value, then un-set the user value.
           Otherwise, set the user value only if it has changed */
        if (!pref_ValueChanged(pref->defaultPref, value, type) &&
            pref->flags & PREF_HAS_DEFAULT)
        {
            if (PREF_HAS_USER_VALUE(pref))
            {
                pref->flags &= ~PREF_USERSET;
                if (!PREF_IS_LOCKED(pref))
                    valueChanged = PR_TRUE;
            }
        }
        else if ( !PREF_HAS_USER_VALUE(pref) ||
                   pref_ValueChanged(pref->userPref, value, type) )
        {
            pref_SetValue(&pref->userPref, value, type);
            pref->flags |= PREF_USERSET;
            if (!PREF_IS_LOCKED(pref))
                valueChanged = PR_TRUE;
        }
    }

    nsresult rv = NS_OK;
    if (valueChanged) {
        gDirty = PR_TRUE;

        nsresult rv2 = pref_DoCallback(key);
        if (NS_FAILED(rv2))
            rv = rv2;
    }
    return rv;
}
예제 #8
0
void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName )
{
  SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName);
}
예제 #9
0
void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName )
{
  SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName);
}
예제 #10
0
void nsPrinterFeatures::SetCharValue(  const char *tagname, const char *value )
{
  mPrefs->SetCharPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
}
예제 #11
0
void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName )
{
  SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName);
}
예제 #12
0
UniquePtr<AudioStream::Chunk>
DecodedAudioDataSink::PopFrames(uint32_t aFrames)
{
  class Chunk : public AudioStream::Chunk {
  public:
    Chunk(AudioData* aBuffer, uint32_t aFrames, AudioDataValue* aData)
      : mBuffer(aBuffer), mFrames(aFrames), mData(aData) {}
    Chunk() : mFrames(0), mData(nullptr) {}
    const AudioDataValue* Data() const { return mData; }
    uint32_t Frames() const { return mFrames; }
    uint32_t Channels() const { return mBuffer ? mBuffer->mChannels: 0; }
    uint32_t Rate() const { return mBuffer ? mBuffer->mRate : 0; }
    AudioDataValue* GetWritable() const { return mData; }
  private:
    const RefPtr<AudioData> mBuffer;
    const uint32_t mFrames;
    AudioDataValue* const mData;
  };

  class SilentChunk : public AudioStream::Chunk {
  public:
    SilentChunk(uint32_t aFrames, uint32_t aChannels, uint32_t aRate)
      : mFrames(aFrames)
      , mChannels(aChannels)
      , mRate(aRate)
      , mData(MakeUnique<AudioDataValue[]>(aChannels * aFrames)) {
      memset(mData.get(), 0, aChannels * aFrames * sizeof(AudioDataValue));
    }
    const AudioDataValue* Data() const { return mData.get(); }
    uint32_t Frames() const { return mFrames; }
    uint32_t Channels() const { return mChannels; }
    uint32_t Rate() const { return mRate; }
    AudioDataValue* GetWritable() const { return mData.get(); }
  private:
    const uint32_t mFrames;
    const uint32_t mChannels;
    const uint32_t mRate;
    UniquePtr<AudioDataValue[]> mData;
  };

  while (!mCurrentData) {
    // No data in the queue. Return an empty chunk.
    if (AudioQueue().GetSize() == 0) {
      return MakeUnique<Chunk>();
    }

    AudioData* a = AudioQueue().PeekFront()->As<AudioData>();

    // Ignore the element with 0 frames and try next.
    if (a->mFrames == 0) {
      RefPtr<MediaData> releaseMe = AudioQueue().PopFront();
      continue;
    }

    // Ignore invalid samples.
    if (a->mRate != mInfo.mRate || a->mChannels != mInfo.mChannels) {
      NS_WARNING(nsPrintfCString(
        "mismatched sample format, data=%p rate=%u channels=%u frames=%u",
        a->mAudioData.get(), a->mRate, a->mChannels, a->mFrames).get());
      RefPtr<MediaData> releaseMe = AudioQueue().PopFront();
      continue;
    }

    // See if there's a gap in the audio. If there is, push silence into the
    // audio hardware, so we can play across the gap.
    // Calculate the timestamp of the next chunk of audio in numbers of
    // samples.
    CheckedInt64 sampleTime = UsecsToFrames(AudioQueue().PeekFront()->mTime, mInfo.mRate);
    // Calculate the number of frames that have been pushed onto the audio hardware.
    CheckedInt64 playedFrames = UsecsToFrames(mStartTime, mInfo.mRate) +
                                static_cast<int64_t>(mWritten);
    CheckedInt64 missingFrames = sampleTime - playedFrames;

    if (!missingFrames.isValid() || !sampleTime.isValid()) {
      NS_WARNING("Int overflow in DecodedAudioDataSink");
      mErrored = true;
      return MakeUnique<Chunk>();
    }

    if (missingFrames.value() > AUDIO_FUZZ_FRAMES) {
      // The next audio chunk begins some time after the end of the last chunk
      // we pushed to the audio hardware. We must push silence into the audio
      // hardware so that the next audio chunk begins playback at the correct
      // time.
      missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value());
      auto framesToPop = std::min<uint32_t>(missingFrames.value(), aFrames);
      mWritten += framesToPop;
      return MakeUnique<SilentChunk>(framesToPop, mInfo.mChannels, mInfo.mRate);
    }

    mCurrentData = dont_AddRef(AudioQueue().PopFront().take()->As<AudioData>());
    mCursor = MakeUnique<AudioBufferCursor>(mCurrentData->mAudioData.get(),
                                            mCurrentData->mChannels,
                                            mCurrentData->mFrames);
    MOZ_ASSERT(mCurrentData->mFrames > 0);
  }

  auto framesToPop = std::min(aFrames, mCursor->Available());

  SINK_LOG_V("playing audio at time=%lld offset=%u length=%u",
             mCurrentData->mTime, mCurrentData->mFrames - mCursor->Available(), framesToPop);

  UniquePtr<AudioStream::Chunk> chunk =
    MakeUnique<Chunk>(mCurrentData, framesToPop, mCursor->Ptr());

  mWritten += framesToPop;
  mCursor->Advance(framesToPop);

  // All frames are popped. Reset mCurrentData so we can pop new elements from
  // the audio queue in next calls to PopFrames().
  if (mCursor->Available() == 0) {
    mCurrentData = nullptr;
  }

  return chunk;
}
예제 #13
0
void
ChromiumCDMProxy::Init(PromiseId aPromiseId,
                       const nsAString& aOrigin,
                       const nsAString& aTopLevelOrigin,
                       const nsAString& aGMPName)
{
  MOZ_ASSERT(NS_IsMainThread());
  NS_ENSURE_TRUE_VOID(!mKeys.IsNull());

  EME_LOG(
    "ChromiumCDMProxy::Init (pid=%u, origin=%s, topLevelOrigin=%s, gmp=%s)",
    aPromiseId,
    NS_ConvertUTF16toUTF8(aOrigin).get(),
    NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(),
    NS_ConvertUTF16toUTF8(aGMPName).get());

  if (!mGMPThread) {
    RejectPromise(
      aPromiseId,
      NS_ERROR_DOM_INVALID_STATE_ERR,
      NS_LITERAL_CSTRING("Couldn't get GMP thread ChromiumCDMProxy::Init"));
    return;
  }

  if (aGMPName.IsEmpty()) {
    RejectPromise(aPromiseId,
                  NS_ERROR_DOM_INVALID_STATE_ERR,
                  nsPrintfCString("Unknown GMP for keysystem '%s'",
                                  NS_ConvertUTF16toUTF8(mKeySystem).get()));
    return;
  }

  gmp::NodeId nodeId(aOrigin, aTopLevelOrigin, aGMPName);
  RefPtr<AbstractThread> thread = mGMPThread;
  RefPtr<GMPCrashHelper> helper(mCrashHelper);
  RefPtr<ChromiumCDMProxy> self(this);
  nsCString keySystem = NS_ConvertUTF16toUTF8(mKeySystem);
  RefPtr<Runnable> task(NS_NewRunnableFunction(
    [self, nodeId, helper, aPromiseId, thread, keySystem]() -> void {
      MOZ_ASSERT(self->IsOnOwnerThread());

      RefPtr<gmp::GeckoMediaPluginService> service =
        gmp::GeckoMediaPluginService::GetGeckoMediaPluginService();
      if (!service) {
        self->RejectPromise(
          aPromiseId,
          NS_ERROR_DOM_INVALID_STATE_ERR,
          NS_LITERAL_CSTRING(
            "Couldn't get GeckoMediaPluginService in ChromiumCDMProxy::Init"));
        return;
      }
      RefPtr<gmp::GetCDMParentPromise> promise =
        service->GetCDM(nodeId, { keySystem }, helper);
      promise->Then(
        thread,
        __func__,
        [self, aPromiseId](RefPtr<gmp::ChromiumCDMParent> cdm) {
          if (!cdm->Init(self,
                         self->mDistinctiveIdentifierRequired,
                         self->mPersistentStateRequired)) {
            self->RejectPromise(aPromiseId,
                                NS_ERROR_FAILURE,
                                NS_LITERAL_CSTRING("GetCDM failed."));
            return;
          }
          {
            MutexAutoLock lock(self->mCDMMutex);
            self->mCDM = cdm;
          }
          self->OnCDMCreated(aPromiseId);
        },
        [self, aPromiseId](nsresult rv) {
          self->RejectPromise(
            aPromiseId, NS_ERROR_FAILURE, NS_LITERAL_CSTRING("GetCDM failed."));
        });
    }));

  mGMPThread->Dispatch(task.forget());
}
예제 #14
0
void
nsHttpConnectionInfo::SetTlsFlags(uint32_t aTlsFlags) {
    mTlsFlags = aTlsFlags;

    mHashKey.Replace(18, 8, nsPrintfCString("%08x", mTlsFlags));
}
예제 #15
0
nsACString&
LayerManager::PrintInfo(nsACString& aTo, const char* aPrefix)
{
  aTo += aPrefix;
  return aTo += nsPrintfCString(64, "%sLayerManager (0x%p)", Name(), this);
}
예제 #16
0
void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace )
{
  SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace);
}
예제 #17
0
파일: prefapi.cpp 프로젝트: ahadzi/celtx
nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, PRBool set_default)
{
    if (!gHashTable.ops)
        return NS_ERROR_OUT_OF_MEMORY;

    PrefHashEntry* pref = static_cast<PrefHashEntry*>(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD));

    if (!pref)
        return NS_ERROR_OUT_OF_MEMORY;

    // new entry, better intialize
    if (!pref->key) {

        // initialize the pref entry
        pref->flags = type;
        pref->key = ArenaStrDup(key, &gPrefNameArena);
        memset(&pref->defaultPref, 0, sizeof(pref->defaultPref));
        memset(&pref->userPref, 0, sizeof(pref->userPref));

        /* ugly hack -- define it to a default that no pref will ever
           default to this should really get fixed right by some out
           of band data
        */
        if (pref->flags & PREF_BOOL)
            pref->defaultPref.boolVal = (PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE;
        if (pref->flags & PREF_INT)
            pref->defaultPref.intVal = (PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE;
    }
    else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) !=
                 (type & PREF_VALUETYPE_MASK))
    {
        NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get());
        return NS_ERROR_UNEXPECTED;
    }

    PRBool valueChanged = PR_FALSE;
    if (set_default)
    {
        if (!PREF_IS_LOCKED(pref))
        {       /* ?? change of semantics? */
            if (pref_ValueChanged(pref->defaultPref, value, type))
            {
                pref_SetValue(&pref->defaultPref, value, type);
                if (!PREF_HAS_USER_VALUE(pref))
                    valueChanged = PR_TRUE;
            }
        }
    }
    else
    {
        /* If new value is same as the default value, then un-set the user value.
           Otherwise, set the user value only if it has changed */
        if ( !pref_ValueChanged(pref->defaultPref, value, type) )
        {
            if (PREF_HAS_USER_VALUE(pref))
            {
                pref->flags &= ~PREF_USERSET;
                if (!PREF_IS_LOCKED(pref))
                    valueChanged = PR_TRUE;
            }
        }
        else if ( !PREF_HAS_USER_VALUE(pref) ||
                   pref_ValueChanged(pref->userPref, value, type) )
        {
            pref_SetValue(&pref->userPref, value, type);
            pref->flags |= PREF_USERSET;
            if (!PREF_IS_LOCKED(pref))
                valueChanged = PR_TRUE;
        }
    }

    nsresult rv = NS_OK;
    if (valueChanged) {
        gDirty = PR_TRUE;

        if (gCallbacksEnabled) {
            nsresult rv2 = pref_DoCallback(key);
            if (NS_FAILED(rv2))
                rv = rv2;
        }
#ifdef MOZ_PROFILESHARING
        if (gSharedPrefHandler)
            gSharedPrefHandler->OnPrefChanged(set_default, pref, value);
#endif
    }
    return rv;
}
예제 #18
0
/* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings)
{
  DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()"));
  nsresult rv;

  NS_ENSURE_ARG_POINTER(aPrinterName);
  NS_ENSURE_ARG_POINTER(aPrintSettings);
  
  NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE);
  NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE);

  nsCOMPtr<nsIPrefBranch> pPrefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
  if (NS_FAILED(rv))
    return rv;

  nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ 
                 printerName;     /* "Stripped" name of printer */
  fullPrinterName.Assign(NS_ConvertUTF16toUTF8(aPrinterName));
  printerName.Assign(NS_ConvertUTF16toUTF8(aPrinterName));
  DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get()));
  
  PrintMethod type = pmInvalid;
  rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type);
  if (NS_FAILED(rv))
    return rv;

#ifdef USE_POSTSCRIPT
  /* "Demangle" postscript printer name */
  if (type == pmPostScript) {
    /* Strip the printing method name from the printer,
     * e.g. turn "PostScript/foobar" to "foobar" */
    PRInt32 slash = printerName.FindChar('/');
    if (kNotFound != slash)
      printerName.Cut(0, slash + 1);
  }
#endif /* USE_POSTSCRIPT */

#ifdef SET_PRINTER_FEATURES_VIA_PREFS
  /* Defaults to FALSE */
  pPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.has_special_printerfeatures", fullPrinterName.get()).get(), PR_FALSE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

  
  /* Set filename */
  nsXPIDLCString filename;
  if (NS_FAILED(CopyPrinterCharPref(pPrefs, nsnull, printerName, "filename", filename))) {
    const char *path;
  
    if (!(path = PR_GetEnv("PWD")))
      path = PR_GetEnv("HOME");
  
    if (path)
      filename = nsPrintfCString(PATH_MAX, "%s/mozilla.ps", path);
    else
      filename.AssignLiteral("mozilla.ps");
  }  
  DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get()));
  aPrintSettings->SetToFileName(NS_ConvertUTF8toUTF16(filename).get());

  aPrintSettings->SetIsInitializedFromPrinter(PR_TRUE);

#ifdef USE_POSTSCRIPT
  if (type == pmPostScript) {
    DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n"));

#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    nsPrinterFeatures printerFeatures(fullPrinterName);

    printerFeatures.SetSupportsPaperSizeChange(PR_TRUE);
    printerFeatures.SetSupportsOrientationChange(PR_TRUE);
    printerFeatures.SetSupportsPlexChange(PR_FALSE);
    printerFeatures.SetSupportsResolutionNameChange(PR_FALSE);
    printerFeatures.SetSupportsColorspaceChange(PR_FALSE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ 
      
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetCanChangeOrientation(PR_TRUE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

    nsXPIDLCString orientation;
    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "orientation", orientation))) {
      if (orientation.LowerCaseEqualsLiteral("portrait")) {
        DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
        aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
      }
      else if (orientation.LowerCaseEqualsLiteral("landscape")) {
        DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
        aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);  
      }
      else {
        DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get()));
      }
    }

#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetOrientationRecord(0, "portrait");
    printerFeatures.SetOrientationRecord(1, "landscape");
    printerFeatures.SetNumOrientationRecords(2);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

    /* PostScript module does not support changing the plex mode... */
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetCanChangePlex(PR_FALSE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
    DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default"));
    aPrintSettings->SetPlexName(NS_LITERAL_STRING("default").get());
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetPlexRecord(0, "default");
    printerFeatures.SetNumPlexRecords(1);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

    /* PostScript module does not support changing the resolution mode... */
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetCanChangeResolutionName(PR_FALSE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
    DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default"));
    aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get());
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetResolutionNameRecord(0, "default");
    printerFeatures.SetNumResolutionNameRecords(1);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

    /* PostScript module does not support changing the colorspace... */
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetCanChangeColorspace(PR_FALSE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
    DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default"));
    aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get());
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetColorspaceRecord(0, "default");
    printerFeatures.SetNumColorspaceRecords(1);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */   

#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetCanChangePaperSize(PR_TRUE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
    nsXPIDLCString papername;
    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", papername))) {
      nsPaperSizePS paper;

      if (paper.Find(papername)) {
        DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
              paper.Name(), paper.Width_mm(), paper.Height_mm()));
	aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
        aPrintSettings->SetPaperWidth(paper.Width_mm());
        aPrintSettings->SetPaperHeight(paper.Height_mm());
        aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper.Name()).get());
      }
      else {
        DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
      }
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
      paper.First();
      int count = 0;
      while (!paper.AtEnd())
      {
        printerFeatures.SetPaperRecord(count++, paper.Name(),
            (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
        paper.Next();
      }
      printerFeatures.SetNumPaperSizeRecords(count);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
    }

    PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
        nsPSPrinterList::GetPrinterType(fullPrinterName));
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd);
    printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd);

    /* Postscript module does not pass the job title to lpr */
    printerFeatures.SetSupportsJobTitleChange(PR_FALSE);
    printerFeatures.SetCanChangeJobTitle(PR_FALSE);
    /* Postscript module has no control over builtin fonts yet */
    printerFeatures.SetSupportsDownloadFontsChange(PR_FALSE);
    printerFeatures.SetCanChangeDownloadFonts(PR_FALSE);
    /* Postscript module does not support multiple colorspaces
     * so it has to use the old way */
    printerFeatures.SetSupportsPrintInColorChange(PR_TRUE);
    printerFeatures.SetCanChangePrintInColor(PR_TRUE);
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

    if (hasSpoolerCmd) {
      nsXPIDLCString command;
      if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript",
            printerName, "print_command", command))) {
        DO_PR_DEBUG_LOG(("setting default print command to '%s'\n",
            command.get()));
        aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUTF16(command).get());
      }
    }
    
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
    printerFeatures.SetCanChangeNumCopies(PR_TRUE);   
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */

    return NS_OK;    
  }
#endif /* USE_POSTSCRIPT */

  return NS_ERROR_UNEXPECTED;
}
예제 #19
0
void
TextureSource::PrintInfo(nsACString& aTo, const char* aPrefix)
{
  aTo += aPrefix;
  aTo += nsPrintfCString("UnknownTextureSource (0x%p)", this);
}
예제 #20
0
void
WebGLProgram::LinkProgram()
{
    mContext->InvalidateBufferFetching(); // we do it early in this function
    // as some of the validation below changes program state

    mLinkLog.Truncate();
    mMostRecentLinkInfo = nullptr;

    if (!mVertShader || !mVertShader->IsCompiled()) {
        mLinkLog.AssignLiteral("Must have a compiled vertex shader attached.");
        mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
        return;
    }

    if (!mFragShader || !mFragShader->IsCompiled()) {
        mLinkLog.AssignLiteral("Must have an compiled fragment shader attached.");
        mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
        return;
    }

    if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) {
        mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
        return;
    }

    gl::GLContext* gl = mContext->gl;
    gl->MakeCurrent();

    if (gl->WorkAroundDriverBugs() &&
        mContext->mIsMesa)
    {
        // Bug 777028: Mesa can't handle more than 16 samplers per program,
        // counting each array entry.
        size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() +
                                               mFragShader->CalcNumSamplerUniforms();
        if (numSamplerUniforms_upperBound > 16) {
            mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on"
                                   " Mesa drivers to avoid crashing.");
            mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
            return;
        }

        // Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count.
        if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) {
            mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count.");
            mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
            return;
        }
    }

    // Bind the attrib locations.
    // This can't be done trivially, because we have to deal with mapped attrib names.
    for (auto itr = mBoundAttribLocs.begin(); itr != mBoundAttribLocs.end(); ++itr) {
        const nsCString& name = itr->first;
        GLuint index = itr->second;

        mVertShader->BindAttribLocation(mGLName, name, index);
    }

    if (!mTransformFeedbackVaryings.empty()) {
        // Bind the transform feedback varyings.
        // This can't be done trivially, because we have to deal with mapped names too.
        mVertShader->ApplyTransformFeedbackVaryings(mGLName,
                                                    mTransformFeedbackVaryings,
                                                    mTransformFeedbackBufferMode,
                                                    &mTempMappedVaryings);
    }

    LinkAndUpdate();
    if (IsLinked()) {
        // Check if the attrib name conflicting to uniform name
        for (const auto& uniform : mMostRecentLinkInfo->uniformMap) {
            if (mMostRecentLinkInfo->attribMap.find(uniform.first) != mMostRecentLinkInfo->attribMap.end()) {
                mLinkLog = nsPrintfCString("The uniform name (%s) conflicts with attribute name.",
                                           uniform.first.get());
                mMostRecentLinkInfo = nullptr;
                break;
            }
        }
    }

    if (mMostRecentLinkInfo)
        return;

    // Failed link.
    if (mContext->ShouldGenerateWarnings()) {
        // report shader/program infoLogs as warnings.
        // note that shader compilation errors can be deferred to linkProgram,
        // which is why we can't do anything in compileShader. In practice we could
        // report in compileShader the translation errors generated by ANGLE,
        // but it seems saner to keep a single way of obtaining shader infologs.
        if (!mLinkLog.IsEmpty()) {
            mContext->GenerateWarning("linkProgram: Failed to link, leaving the following"
                                      " log:\n%s\n",
                                      mLinkLog.BeginReading());
        }
    }
}
예제 #21
0
bool
WebGLFBAttachPoint::IsComplete(WebGLContext* webgl, nsCString* const out_info) const
{
    MOZ_ASSERT(IsDefined());

    if (!HasImage()) {
        AttachmentName(out_info);
        out_info->AppendLiteral("'s image is not defined");
        return false;
    }

    uint32_t width;
    uint32_t height;
    Size(&width, &height);
    if (!width || !height) {
        AttachmentName(out_info);
        out_info->AppendLiteral(" has no width or height");
        return false;
    }

    const auto formatUsage = Format();
    if (!formatUsage->isRenderable) {
        nsAutoCString attachName;
        AttachmentName(&attachName);

        *out_info = nsPrintfCString("%s has an effective format of %s, which is not"
                                    " renderable",
                                    attachName.BeginReading(), formatUsage->format->name);
        return false;
    }

    const auto format = formatUsage->format;

    bool hasRequiredBits;

    switch (mAttachmentPoint) {
    case LOCAL_GL_DEPTH_ATTACHMENT:
        hasRequiredBits = format->hasDepth;
        break;

    case LOCAL_GL_STENCIL_ATTACHMENT:
        hasRequiredBits = format->hasStencil;
        break;

    case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
        MOZ_ASSERT(!webgl->IsWebGL2());
        hasRequiredBits = (format->hasDepth && format->hasStencil);
        break;

    default:
        MOZ_ASSERT(mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0);
        hasRequiredBits = format->isColorFormat;
        break;
    }

    if (!hasRequiredBits) {
        AttachmentName(out_info);
        out_info->AppendLiteral("'s format is missing required color/depth/stencil bits");
        return false;
    }

    if (!webgl->IsWebGL2()) {
        bool hasSurplusPlanes = false;

        switch (mAttachmentPoint) {
        case LOCAL_GL_DEPTH_ATTACHMENT:
            hasSurplusPlanes = format->hasStencil;
            break;

        case LOCAL_GL_STENCIL_ATTACHMENT:
            hasSurplusPlanes = format->hasDepth;
            break;
        }

        if (hasSurplusPlanes) {
            AttachmentName(out_info);
            out_info->AppendLiteral("'s format has depth or stencil bits when it"
                                    " shouldn't");
            return false;
        }
    }

    return true;
}
예제 #22
0
nsresult nsSceneTracker::UpdateSceneNumberLiterals (
                                  nsIDOMHTMLParagraphElement* aScene) {
  NS_ENSURE_ARG(aScene);

  nsAutoString className;
  nsresult rv = aScene->GetClassName(className);
  NS_ENSURE_SUCCESS(rv, rv);

  if (! className.Equals(NS_LITERAL_STRING("sceneheading")))
    return NS_ERROR_INVALID_ARG;

  nsAutoString sceneNumberStr;
  rv = aScene->GetAttribute(NS_LITERAL_STRING("scenenumber"), sceneNumberStr);
  NS_ENSURE_SUCCESS(rv, rv);

  // Durrrr... maybe this should be an error?
  if (sceneNumberStr.IsEmpty())
    return NS_OK;

  PRUint32 sceneNumber[DEFAULT_MAX_SCENE_DEPTH];
  PRUint32 sceneNumberLength = DEFAULT_MAX_SCENE_DEPTH;
  rv = ParseSceneNumber(sceneNumberStr, &sceneNumberLength, sceneNumber);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoString displayStr;
  rv = mScheme.SceneNumberToString(sceneNumberLength, sceneNumber,
    displayStr);
  NS_ENSURE_SUCCESS(rv, rv);

  aScene->SetAttribute(NS_LITERAL_STRING("scenestr"), displayStr);

  nsAutoString sceneID;
  rv = aScene->GetAttribute(NS_LITERAL_STRING("id"), sceneID);
  NS_ENSURE_SUCCESS(rv, rv);

  if (sceneID.IsEmpty())
    return NS_ERROR_UNEXPECTED;

  nsCOMPtr<nsIRDFResource> sceneres;
  rv = SceneForSceneID(sceneID, getter_AddRefs(sceneres));
  NS_ENSURE_SUCCESS(rv, rv);

  if (! sceneres)
    return NS_ERROR_UNEXPECTED;

  nsCOMPtr<nsIRDFResource> ordarc;
  nsCOMPtr<nsIRDFResource> sortordarc;
  mRDFSvc->GetResource(NS_LITERAL_CSTRING("http://celtx.com/NS/v1/ordinal"),
    getter_AddRefs(ordarc));
  mRDFSvc->GetResource(NS_LITERAL_CSTRING("http://celtx.com/NS/v1/sortord"),
    getter_AddRefs(sortordarc));
  // TODO: Distinguish canonical string from display string
  SetRDFString(mDS, sceneres, ordarc, displayStr);

  // This is for sorting only. Each scene number component is
  // zero-padded to 4 digits, allowing alphabetical sorting.
  nsCAutoString sortStr;
  sortStr.Assign(nsPrintfCString("%04d", sceneNumber[0]));

  for (PRUint32 i = 1; i < sceneNumberLength; ++i)
    sortStr.Append(nsPrintfCString("%04d", sceneNumber[i]));

  SetRDFString(mDS, sceneres, sortordarc,
    NS_ConvertASCIItoUTF16(sortStr));

  return NS_OK;
}
예제 #23
0
  NS_DECL_THREADSAFE_ISUPPORTS

  NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
                            nsISupports *aClosure, bool aAnonymize)
  {
    typedef DOMFileImplMemory::DataOwner DataOwner;

    StaticMutexAutoLock lock(DataOwner::sDataOwnerMutex);

    if (!DataOwner::sDataOwners) {
      return NS_OK;
    }

    const size_t LARGE_OBJECT_MIN_SIZE = 8 * 1024;
    size_t smallObjectsTotal = 0;

    for (DataOwner *owner = DataOwner::sDataOwners->getFirst();
         owner; owner = owner->getNext()) {

      size_t size = DOMMemoryFileDataOwnerMallocSizeOf(owner->mData);

      if (size < LARGE_OBJECT_MIN_SIZE) {
        smallObjectsTotal += size;
      } else {
        SHA1Sum sha1;
        sha1.update(owner->mData, owner->mLength);
        uint8_t digest[SHA1Sum::kHashSize]; // SHA1 digests are 20 bytes long.
        sha1.finish(digest);

        nsAutoCString digestString;
        for (size_t i = 0; i < sizeof(digest); i++) {
          digestString.AppendPrintf("%02x", digest[i]);
        }

        nsresult rv = aCallback->Callback(
          /* process */ NS_LITERAL_CSTRING(""),
          nsPrintfCString(
            "explicit/dom/memory-file-data/large/file(length=%llu, sha1=%s)",
            owner->mLength, aAnonymize ? "<anonymized>" : digestString.get()),
          KIND_HEAP, UNITS_BYTES, size,
          nsPrintfCString(
            "Memory used to back a memory file of length %llu bytes.  The file "
            "has a sha1 of %s.\n\n"
            "Note that the allocator may round up a memory file's length -- "
            "that is, an N-byte memory file may take up more than N bytes of "
            "memory.",
            owner->mLength, digestString.get()),
          aClosure);
        NS_ENSURE_SUCCESS(rv, rv);
      }
    }

    if (smallObjectsTotal > 0) {
      nsresult rv = aCallback->Callback(
        /* process */ NS_LITERAL_CSTRING(""),
        NS_LITERAL_CSTRING("explicit/dom/memory-file-data/small"),
        KIND_HEAP, UNITS_BYTES, smallObjectsTotal,
        nsPrintfCString(
          "Memory used to back small memory files (less than %d bytes each).\n\n"
          "Note that the allocator may round up a memory file's length -- "
          "that is, an N-byte memory file may take up more than N bytes of "
          "memory."),
        aClosure);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    return NS_OK;
  }
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
                                                         nsIURI* aURL)
{
  nsresult rv = NS_OK;

  // If we don't yet have a stream listener, we need to get
  // one from the plugin.
  // NOTE: this should only happen when a stream was NOT created
  // with GetURL or PostURL (i.e. it's the initial stream we
  // send to the plugin as determined by the SRC or DATA attribute)
  if (!mPStreamListener) {
    if (!mPluginInstance) {
      return NS_ERROR_FAILURE;
    }

    RefPtr<nsNPAPIPluginStreamListener> streamListener;
    rv = mPluginInstance->NewStreamListener(nullptr, nullptr,
                                            getter_AddRefs(streamListener));
    if (NS_FAILED(rv) || !streamListener) {
      return NS_ERROR_FAILURE;
    }

    mPStreamListener = static_cast<nsNPAPIPluginStreamListener*>(streamListener.get());
  }

  mPStreamListener->SetStreamListenerPeer(this);

  // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);

  /*
   * Assumption
   * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
   * called, all the headers have been read.
   */
  if (httpChannel) {
    // Reassemble the HTTP response status line and provide it to our
    // listener.  Would be nice if we could get the raw status line,
    // but nsIHttpChannel doesn't currently provide that.
    // Status code: required; the status line isn't useful without it.
    uint32_t statusNum;
    if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) &&
        statusNum < 1000) {
      // HTTP version: provide if available.  Defaults to empty string.
      nsCString ver;
      nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
      do_QueryInterface(channel);
      if (httpChannelInternal) {
        uint32_t major, minor;
        if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major,
                                                                 &minor))) {
          ver = nsPrintfCString("/%" PRIu32 ".%" PRIu32, major, minor);
        }
      }

      // Status text: provide if available.  Defaults to "OK".
      nsCString statusText;
      if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) {
        statusText = "OK";
      }

      // Assemble everything and pass to listener.
      nsPrintfCString status("HTTP%s %" PRIu32 " %s", ver.get(), statusNum,
                             statusText.get());
      static_cast<nsIHTTPHeaderListener*>(mPStreamListener)->StatusLine(status.get());
    }

    // Also provide all HTTP response headers to our listener.
    rv = httpChannel->VisitResponseHeaders(this);
    MOZ_ASSERT(NS_SUCCEEDED(rv));

    // we require a content len
    // get Last-Modified header for plugin info
    nsAutoCString lastModified;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) &&
        !lastModified.IsEmpty()) {
      PRTime time64;
      PR_ParseTimeString(lastModified.get(), true, &time64);  //convert string time to integer time

      // Convert PRTime to unix-style time_t, i.e. seconds since the epoch
      double fpTime = double(time64);
      mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
    }
  }

  MOZ_ASSERT(!mRequest);
  mRequest = request;

  rv = mPStreamListener->OnStartBinding(this);

  mStartBinding = true;

  if (NS_FAILED(rv))
    return rv;

  return NS_OK;
}
예제 #25
0
// If a blacklisted DLL is found, return its information, otherwise "".
static const nsACString&
FindDXVABlacklistedDLL(StaticAutoPtr<D3DDLLBlacklistingCache>& aDLLBlacklistingCache,
                       const char* aDLLBlacklistPrefName)
{
  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");

  if (!aDLLBlacklistingCache) {
    // First time here, create persistent data that will be reused in all
    // D3D11-blacklisting checks.
    aDLLBlacklistingCache = new D3DDLLBlacklistingCache();
    ClearOnShutdown(&aDLLBlacklistingCache);
  }

  nsAdoptingCString blacklist = Preferences::GetCString(aDLLBlacklistPrefName);
  if (blacklist.IsEmpty()) {
    // Empty blacklist -> No blacklisting.
    aDLLBlacklistingCache->mBlacklistPref.SetLength(0);
    aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
    return aDLLBlacklistingCache->mBlacklistedDLL;
  }

  // Detect changes in pref.
  if (aDLLBlacklistingCache->mBlacklistPref.Equals(blacklist)) {
    // Same blacklist -> Return same result (i.e., don't check DLLs again).
    return aDLLBlacklistingCache->mBlacklistedDLL;
  }
  // Adopt new pref now, so we don't work on it again.
  aDLLBlacklistingCache->mBlacklistPref = blacklist;

  // media.wmf.disable-d3d*-for-dlls format: (whitespace is trimmed)
  // "dll1.dll: 1.2.3.4[, more versions...][; more dlls...]"
  nsTArray<nsCString> dlls;
  SplitAt(";", blacklist, dlls);
  for (const auto& dll : dlls) {
    nsTArray<nsCString> nameAndVersions;
    SplitAt(":", dll, nameAndVersions);
    if (nameAndVersions.Length() != 2) {
      NS_WARNING(nsPrintfCString("Skipping incorrect '%s' dll:versions format",
                                 aDLLBlacklistPrefName).get());
      continue;
    }

    nameAndVersions[0].CompressWhitespace();
    NS_ConvertUTF8toUTF16 name(nameAndVersions[0]);
    WCHAR systemPath[MAX_PATH + 1];
    if (!ConstructSystem32Path(name.get(), systemPath, MAX_PATH + 1)) {
      // Cannot build path -> Assume it's not the blacklisted DLL.
      continue;
    }

    DWORD zero;
    DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
    if (infoSize == 0) {
      // Can't get file info -> Assume we don't have the blacklisted DLL.
      continue;
    }
    // vInfo is a pointer into infoData, that's why we keep it outside of the loop.
    auto infoData = MakeUnique<unsigned char[]>(infoSize);
    VS_FIXEDFILEINFO *vInfo;
    UINT vInfoLen;
    if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get())
        || !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen)
        || !vInfo) {
      // Can't find version -> Assume it's not blacklisted.
      continue;
    }

    nsTArray<nsCString> versions;
    SplitAt(",", nameAndVersions[1], versions);
    for (const auto& version : versions) {
      nsTArray<nsCString> numberStrings;
      SplitAt(".", version, numberStrings);
      if (numberStrings.Length() != 4) {
        NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format",
                                   aDLLBlacklistPrefName).get());
        continue;
      }
      DWORD numbers[4];
      nsresult errorCode = NS_OK;
      for (int i = 0; i < 4; ++i) {
        numberStrings[i].CompressWhitespace();
        numbers[i] = DWORD(numberStrings[i].ToInteger(&errorCode));
        if (NS_FAILED(errorCode)) {
          break;
        }
        if (numbers[i] > UINT16_MAX) {
          errorCode = NS_ERROR_FAILURE;
          break;
        }
      }

      if (NS_FAILED(errorCode)) {
        NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format",
                                   aDLLBlacklistPrefName).get());
        continue;
      }

      if (vInfo->dwFileVersionMS == ((numbers[0] << 16) | numbers[1])
          && vInfo->dwFileVersionLS == ((numbers[2] << 16) | numbers[3])) {
        // Blacklisted! Record bad DLL.
        aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
        aDLLBlacklistingCache->mBlacklistedDLL.AppendPrintf(
          "%s (%lu.%lu.%lu.%lu)",
          nameAndVersions[0].get(), numbers[0], numbers[1], numbers[2], numbers[3]);
        return aDLLBlacklistingCache->mBlacklistedDLL;
      }
    }
  }

  // No blacklisted DLL.
  aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0);
  return aDLLBlacklistingCache->mBlacklistedDLL;
}
예제 #26
0
bool
WebGLProgram::ValidateAfterTentativeLink(nsCString* const out_linkLog) const
{
    const auto& linkInfo = mMostRecentLinkInfo;
    const auto& gl = mContext->gl;

    // Check if the attrib name conflicting to uniform name
    for (const auto& attrib : linkInfo->attribs) {
        const auto& attribName = attrib.mActiveInfo->mBaseUserName;

        for (const auto& uniform : linkInfo->uniforms) {
            const auto& uniformName = uniform->mActiveInfo->mBaseUserName;
            if (attribName == uniformName) {
                *out_linkLog = nsPrintfCString("Attrib name conflicts with uniform name:"
                                               " %s",
                                               attribName.BeginReading());
                return false;
            }
        }
    }

    std::map<uint32_t, const webgl::AttribInfo*> attribsByLoc;
    for (const auto& attrib : linkInfo->attribs) {
        const auto& elemType = attrib.mActiveInfo->mElemType;
        const auto numUsedLocs = NumUsedLocationsByElemType(elemType);
        for (uint32_t i = 0; i < numUsedLocs; i++) {
            const uint32_t usedLoc = attrib.mLoc + i;

            const auto res = attribsByLoc.insert({usedLoc, &attrib});
            const bool& didInsert = res.second;
            if (!didInsert) {
                const auto& aliasingName = attrib.mActiveInfo->mBaseUserName;
                const auto& itrExisting = res.first;
                const auto& existingInfo = itrExisting->second;
                const auto& existingName = existingInfo->mActiveInfo->mBaseUserName;
                *out_linkLog = nsPrintfCString("Attrib \"%s\" aliases locations used by"
                                               " attrib \"%s\".",
                                               aliasingName.BeginReading(),
                                               existingName.BeginReading());
                return false;
            }
        }
    }

    // Forbid:
    // * Unrecognized varying name
    // * Duplicate varying name
    // * Too many components for specified buffer mode
    if (mNextLink_TransformFeedbackVaryings.size()) {
        GLuint maxComponentsPerIndex = 0;
        switch (mNextLink_TransformFeedbackBufferMode) {
        case LOCAL_GL_INTERLEAVED_ATTRIBS:
            gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
                             &maxComponentsPerIndex);
            break;

        case LOCAL_GL_SEPARATE_ATTRIBS:
            gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
                             &maxComponentsPerIndex);
            break;

        default:
            MOZ_CRASH("`bufferMode`");
        }

        std::vector<size_t> componentsPerVert;
        std::set<const WebGLActiveInfo*> alreadyUsed;
        for (const auto& wideUserName : mNextLink_TransformFeedbackVaryings) {
            if (!componentsPerVert.size() ||
                mNextLink_TransformFeedbackBufferMode == LOCAL_GL_SEPARATE_ATTRIBS)
            {
                componentsPerVert.push_back(0);
            }

            ////

            const WebGLActiveInfo* curInfo = nullptr;
            for (const auto& info : linkInfo->transformFeedbackVaryings) {
                const NS_ConvertASCIItoUTF16 info_wideUserName(info->mBaseUserName);
                if (info_wideUserName == wideUserName) {
                    curInfo = info.get();
                    break;
                }
            }

            if (!curInfo) {
                const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
                *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\" not"
                                               " found.",
                                               asciiUserName.BeginReading());
                return false;
            }

            const auto insertResPair = alreadyUsed.insert(curInfo);
            const auto& didInsert = insertResPair.second;
            if (!didInsert) {
                const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
                *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\""
                                               " specified twice.",
                                               asciiUserName.BeginReading());
                return false;
            }

            ////

            size_t varyingComponents = NumComponents(curInfo->mElemType);
            varyingComponents *= curInfo->mElemCount;

            auto& totalComponentsForIndex = *(componentsPerVert.rbegin());
            totalComponentsForIndex += varyingComponents;

            if (totalComponentsForIndex > maxComponentsPerIndex) {
                const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
                *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\""
                                               " pushed `componentsForIndex` over the"
                                               " limit of %u.",
                                               asciiUserName.BeginReading(),
                                               maxComponentsPerIndex);
                return false;
            }
        }

        linkInfo->componentsPerTFVert.swap(componentsPerVert);
    }

    return true;
}
예제 #27
0
void
nsPicoService::Init()
{
  MOZ_ASSERT(!NS_IsMainThread());
  MOZ_ASSERT(!mInitialized);

  if (!sPicoApi.Init()) {
    NS_WARNING("Failed to initialize pico library");
    return;
  }

  // Use environment variable, or default android/b2g path
  nsAutoCString langPath(PR_GetEnv("PICO_LANG_PATH"));

  if (langPath.IsEmpty()) {
    langPath.AssignLiteral(GONK_PICO_LANG_PATH);
  }

  nsCOMPtr<nsIFile> voicesDir;
  NS_NewNativeLocalFile(langPath, true, getter_AddRefs(voicesDir));

  nsCOMPtr<nsISimpleEnumerator> dirIterator;
  nsresult rv = voicesDir->GetDirectoryEntries(getter_AddRefs(dirIterator));

  if (NS_FAILED(rv)) {
    NS_WARNING(nsPrintfCString("Failed to get contents of directory: %s", langPath.get()).get());
    return;
  }

  bool hasMoreElements = false;
  rv = dirIterator->HasMoreElements(&hasMoreElements);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  MonitorAutoLock autoLock(mVoicesMonitor);

  while (hasMoreElements && NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsISupports> supports;
    rv = dirIterator->GetNext(getter_AddRefs(supports));
    MOZ_ASSERT(NS_SUCCEEDED(rv));

    nsCOMPtr<nsIFile> voiceFile = do_QueryInterface(supports);
    MOZ_ASSERT(voiceFile);

    nsAutoCString leafName;
    voiceFile->GetNativeLeafName(leafName);

    nsAutoString lang;

    if (GetVoiceFileLanguage(leafName, lang)) {
      nsAutoString uri;
      uri.AssignLiteral("urn:moz-tts:pico:");
      uri.Append(lang);

      bool found = false;
      PicoVoice* voice = mVoices.GetWeak(uri, &found);

      if (!found) {
        voice = new PicoVoice(lang);
        mVoices.Put(uri, voice);
      }

      // Each voice consists of two lingware files: A language resource file,
      // suffixed by _ta.bin, and a speaker resource file, suffixed by _sb.bin.
      // We currently assume that there is a pair of files for each language.
      if (StringEndsWith(leafName, NS_LITERAL_CSTRING("_ta.bin"))) {
        rv = voiceFile->GetPersistentDescriptor(voice->mTaFile);
        MOZ_ASSERT(NS_SUCCEEDED(rv));
      } else if (StringEndsWith(leafName, NS_LITERAL_CSTRING("_sg.bin"))) {
        rv = voiceFile->GetPersistentDescriptor(voice->mSgFile);
        MOZ_ASSERT(NS_SUCCEEDED(rv));
      }
    }

    rv = dirIterator->HasMoreElements(&hasMoreElements);
  }

  NS_DispatchToMainThread(NS_NewRunnableMethod(this, &nsPicoService::RegisterVoices));
}
예제 #28
0
nsACString&
Layer::PrintInfo(nsACString& aTo, const char* aPrefix)
{
  aTo += aPrefix;
  aTo += nsPrintfCString("%s%s (0x%p)", mManager->Name(), Name(), this);

  layers::PrintInfo(aTo, AsLayerComposite());

  if (mUseClipRect) {
    AppendToString(aTo, mClipRect, " [clip=", "]");
  }
  if (1.0 != mPostXScale || 1.0 != mPostYScale) {
    aTo.AppendPrintf(" [postScale=%g, %g]", mPostXScale, mPostYScale);
  }
  if (!mTransform.IsIdentity()) {
    AppendToString(aTo, mTransform, " [transform=", "]");
  }
  if (!mVisibleRegion.IsEmpty()) {
    AppendToString(aTo, mVisibleRegion, " [visible=", "]");
  } else {
    aTo += " [not visible]";
  }
  if (!mEventRegions.mHitRegion.IsEmpty()) {
    AppendToString(aTo, mEventRegions.mHitRegion, " [hitregion=", "]");
  }
  if (!mEventRegions.mDispatchToContentHitRegion.IsEmpty()) {
    AppendToString(aTo, mEventRegions.mDispatchToContentHitRegion, " [dispatchtocontentregion=", "]");
  }
  if (1.0 != mOpacity) {
    aTo.AppendPrintf(" [opacity=%g]", mOpacity);
  }
  if (GetContentFlags() & CONTENT_OPAQUE) {
    aTo += " [opaqueContent]";
  }
  if (GetContentFlags() & CONTENT_COMPONENT_ALPHA) {
    aTo += " [componentAlpha]";
  }
  if (GetScrollbarDirection() == VERTICAL) {
    aTo.AppendPrintf(" [vscrollbar=%lld]", GetScrollbarTargetContainerId());
  }
  if (GetScrollbarDirection() == HORIZONTAL) {
    aTo.AppendPrintf(" [hscrollbar=%lld]", GetScrollbarTargetContainerId());
  }
  if (GetIsFixedPosition()) {
    aTo.AppendPrintf(" [isFixedPosition anchor=%f,%f margin=%f,%f,%f,%f]", mAnchor.x, mAnchor.y,
                     mMargins.top, mMargins.right, mMargins.bottom, mMargins.left);
  }
  if (GetIsStickyPosition()) {
    aTo.AppendPrintf(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f "
                     "inner=%f,%f %fx%f]", mStickyPositionData->mScrollId,
                     mStickyPositionData->mOuter.x, mStickyPositionData->mOuter.y,
                     mStickyPositionData->mOuter.width, mStickyPositionData->mOuter.height,
                     mStickyPositionData->mInner.x, mStickyPositionData->mInner.y,
                     mStickyPositionData->mInner.width, mStickyPositionData->mInner.height);
  }
  if (mMaskLayer) {
    aTo.AppendPrintf(" [mMaskLayer=%p]", mMaskLayer.get());
  }

  return aTo;
}
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
                                                         nsIURI* aURL)
{
  nsresult rv = NS_OK;
  
  // If we don't yet have a stream listener, we need to get
  // one from the plugin.
  // NOTE: this should only happen when a stream was NOT created
  // with GetURL or PostURL (i.e. it's the initial stream we
  // send to the plugin as determined by the SRC or DATA attribute)
  if (!mPStreamListener) {
    if (!mPluginInstance) {
      return NS_ERROR_FAILURE;
    }

    nsRefPtr<nsNPAPIPluginStreamListener> streamListener;
    rv = mPluginInstance->NewStreamListener(nullptr, nullptr,
                                            getter_AddRefs(streamListener));
    if (NS_FAILED(rv) || !streamListener) {
      return NS_ERROR_FAILURE;
    }

    mPStreamListener = static_cast<nsNPAPIPluginStreamListener*>(streamListener.get());
  }

  mPStreamListener->SetStreamListenerPeer(this);

  bool useLocalCache = false;
  
  // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
  
  /*
   * Assumption
   * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
   * called, all the headers have been read.
   */
  if (httpChannel) {
    // Reassemble the HTTP response status line and provide it to our
    // listener.  Would be nice if we could get the raw status line,
    // but nsIHttpChannel doesn't currently provide that.
    // Status code: required; the status line isn't useful without it.
    uint32_t statusNum;
    if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) &&
        statusNum < 1000) {
      // HTTP version: provide if available.  Defaults to empty string.
      nsCString ver;
      nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
      do_QueryInterface(channel);
      if (httpChannelInternal) {
        uint32_t major, minor;
        if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major,
                                                                 &minor))) {
          ver = nsPrintfCString("/%lu.%lu", major, minor);
        }
      }

      // Status text: provide if available.  Defaults to "OK".
      nsCString statusText;
      if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) {
        statusText = "OK";
      }

      // Assemble everything and pass to listener.
      nsPrintfCString status("HTTP%s %lu %s", ver.get(), statusNum,
                             statusText.get());
      static_cast<nsIHTTPHeaderListener*>(mPStreamListener)->StatusLine(status.get());
    }

    // Also provide all HTTP response headers to our listener.
    httpChannel->VisitResponseHeaders(this);
    
    mSeekable = false;
    // first we look for a content-encoding header. If we find one, we tell the
    // plugin that stream is not seekable, because the plugin always sees
    // uncompressed data, so it can't make meaningful range requests on a
    // compressed entity.  Also, we force the plugin to use
    // nsPluginStreamType_AsFile stream type and we have to save decompressed
    // file into local plugin cache, because necko cache contains original
    // compressed file.
    nsAutoCString contentEncoding;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
                                                    contentEncoding))) {
      useLocalCache = true;
    } else {
      // set seekability (seekable if the stream has a known length and if the
      // http server accepts byte ranges).
      uint32_t length;
      GetLength(&length);
      if (length) {
        nsAutoCString range;
        if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("accept-ranges"), range)) &&
            range.Equals(NS_LITERAL_CSTRING("bytes"), nsCaseInsensitiveCStringComparator())) {
          mSeekable = true;
        }
      }
    }
    
    // we require a content len
    // get Last-Modified header for plugin info
    nsAutoCString lastModified;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) &&
        !lastModified.IsEmpty()) {
      PRTime time64;
      PR_ParseTimeString(lastModified.get(), true, &time64);  //convert string time to integer time
      
      // Convert PRTime to unix-style time_t, i.e. seconds since the epoch
      double fpTime = double(time64);
      mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
    }
  }
  
  rv = mPStreamListener->OnStartBinding(this);
  
  mStartBinding = true;
  
  if (NS_FAILED(rv))
    return rv;
  
  mPStreamListener->GetStreamType(&mStreamType);
  
  if (!useLocalCache && mStreamType >= NP_ASFILE) {
    // check it out if this is not a file channel.
    nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
    if (!fileChannel) {
        useLocalCache = true;
    }
  }
  
  if (useLocalCache) {
    SetupPluginCacheFile(channel);
  }
  
  return NS_OK;
}
nsresult
nsDOMStorageDBWrapper::CreateScopeDBKey(nsIPrincipal* aPrincipal,
                                        nsACString& aKey)
{
  nsCOMPtr<nsIURI> uri;
  nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);

  nsAutoCString domainScope;
  rv = uri->GetAsciiHost(domainScope);
  NS_ENSURE_SUCCESS(rv, rv);

  if (domainScope.IsEmpty()) {
    // About pages have an empty host but a valid path.  Since they are handled
    // internally by our own redirector, we can trust them and use path as key.
    // if file:/// protocol, let's make the exact directory the domain
    bool isScheme = false;
    if ((NS_SUCCEEDED(uri->SchemeIs("about", &isScheme)) && isScheme) ||
        (NS_SUCCEEDED(uri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) {
      rv = uri->GetPath(domainScope);
      NS_ENSURE_SUCCESS(rv, rv);
      // While the host is always canonicalized to lowercase, the path is not,
      // thus need to force the casing.
      ToLowerCase(domainScope);
    }
    else if (NS_SUCCEEDED(uri->SchemeIs("file", &isScheme)) && isScheme) {
      nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
      NS_ENSURE_SUCCESS(rv, rv);
      rv = url->GetDirectory(domainScope);
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  nsAutoCString key;

  rv = CreateReversedDomain(domainScope, key);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString scheme;
  rv = uri->GetScheme(scheme);
  NS_ENSURE_SUCCESS(rv, rv);

  key.Append(NS_LITERAL_CSTRING(":") + scheme);

  int32_t port = NS_GetRealPort(uri);
  if (port != -1) {
    key.Append(nsPrintfCString(":%d", port));
  }

  uint32_t appId;
  rv = aPrincipal->GetAppId(&appId);
  NS_ENSURE_SUCCESS(rv, rv);

  bool isInBrowserElement;
  rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
  NS_ENSURE_SUCCESS(rv, rv);

  if (appId == nsIScriptSecurityManager::NO_APP_ID && !isInBrowserElement) {
    aKey.Assign(key);
    return NS_OK;
  }

  aKey.Truncate();
  aKey.AppendInt(appId);
  aKey.Append(NS_LITERAL_CSTRING(":") + (isInBrowserElement ?
              NS_LITERAL_CSTRING("t") : NS_LITERAL_CSTRING("f")) +
              NS_LITERAL_CSTRING(":") + key);

  return NS_OK;
}