コード例 #1
0
ファイル: RasterImage.cpp プロジェクト: alphan102/gecko-dev
RasterImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(aManager);
  MOZ_ASSERT((aFlags & ~(FLAG_SYNC_DECODE |
                         FLAG_SYNC_DECODE_IF_FAST |
                         FLAG_ASYNC_NOTIFY))
               == FLAG_NONE,
             "Unsupported flag passed to GetImageContainer");

  int32_t maxTextureSize = aManager->GetMaxTextureSize();
  if (!mHasSize ||
      mSize.width > maxTextureSize ||
      mSize.height > maxTextureSize) {
    return nullptr;
  }

  if (IsUnlocked()) {
    SendOnUnlockedDraw(aFlags);
  }

  RefPtr<layers::ImageContainer> container = mImageContainer.get();

  bool mustRedecode =
    (aFlags & (FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST)) &&
    mLastImageContainerDrawResult != DrawResult::SUCCESS &&
    mLastImageContainerDrawResult != DrawResult::BAD_IMAGE;

  if (container && !mustRedecode) {
    return container.forget();
  }

  // We need a new ImageContainer, so create one.
  container = LayerManager::CreateImageContainer();

  DrawResult drawResult;
  RefPtr<layers::Image> image;
  Tie(drawResult, image) = GetCurrentImage(container, aFlags);
  if (!image) {
    return nullptr;
  }

  // |image| holds a reference to a SourceSurface which in turn holds a lock on
  // the current frame's VolatileBuffer, ensuring that it doesn't get freed as
  // long as the layer system keeps this ImageContainer alive.
  AutoTArray<ImageContainer::NonOwningImage, 1> imageList;
  imageList.AppendElement(ImageContainer::NonOwningImage(image, TimeStamp(),
                                                         mLastFrameID++,
                                                         mImageProducerID));
  container->SetCurrentImagesInTransaction(imageList);

  mLastImageContainerDrawResult = drawResult;
  mImageContainer = container;

  return container.forget();
}
コード例 #2
0
VectorImage::Draw(gfxContext* aContext,
                  const nsIntSize& aSize,
                  const ImageRegion& aRegion,
                  uint32_t aWhichFrame,
                  SamplingFilter aSamplingFilter,
                  const Maybe<SVGImageContext>& aSVGContext,
                  uint32_t aFlags,
                  float aOpacity)
{
  if (aWhichFrame > FRAME_MAX_VALUE) {
    return DrawResult::BAD_ARGS;
  }

  if (!aContext) {
    return DrawResult::BAD_ARGS;
  }

  if (mError) {
    return DrawResult::BAD_IMAGE;
  }

  if (!mIsFullyLoaded) {
    return DrawResult::NOT_READY;
  }

  if (mAnimationConsumers == 0) {
    SendOnUnlockedDraw(aFlags);
  }

  MOZ_ASSERT(!(aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) ||
             (aSVGContext && aSVGContext->GetViewportSize()),
             "Viewport size is required when using "
             "FLAG_FORCE_PRESERVEASPECTRATIO_NONE");

  bool overridePAR = (aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext;

  bool haveContextPaint = aSVGContext && aSVGContext->GetContextPaint();
  bool blockContextPaint = false;
  if (haveContextPaint) {
    nsCOMPtr<nsIURI> imageURI = mURI->ToIURI();
    blockContextPaint = !SVGContextPaint::IsAllowedForImageFromURI(imageURI);
  }

  Maybe<SVGImageContext> newSVGContext;
  if (overridePAR || blockContextPaint) {
    // The key that we create for the image surface cache must match the way
    // that the image will be painted, so we need to initialize a new matching
    // SVGImageContext here in order to generate the correct key.

    newSVGContext = aSVGContext; // copy

    if (overridePAR) {
      // The SVGImageContext must take account of the preserveAspectRatio
      // overide:
      MOZ_ASSERT(!aSVGContext->GetPreserveAspectRatio(),
                 "FLAG_FORCE_PRESERVEASPECTRATIO_NONE is not expected if a "
                 "preserveAspectRatio override is supplied");
      Maybe<SVGPreserveAspectRatio> aspectRatio =
        Some(SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE,
                                    SVG_MEETORSLICE_UNKNOWN));
      newSVGContext->SetPreserveAspectRatio(aspectRatio);
    }

    if (blockContextPaint) {
      // The SVGImageContext must not include context paint if the image is
      // not allowed to use it:
      newSVGContext->ClearContextPaint();
    }
  }

  float animTime = (aWhichFrame == FRAME_FIRST)
                     ? 0.0f : mSVGDocumentWrapper->GetCurrentTime();

  SVGDrawingParameters params(aContext, aSize, aRegion, aSamplingFilter,
                              newSVGContext ? newSVGContext : aSVGContext,
                              animTime, aFlags, aOpacity);

  // If we have an prerasterized version of this image that matches the
  // drawing parameters, use that.
  RefPtr<gfxDrawable> svgDrawable = LookupCachedSurface(params);
  if (svgDrawable) {
    Show(svgDrawable, params);
    return DrawResult::SUCCESS;
  }

  // else, we need to paint the image:

  if (mIsDrawing) {
    NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw");
    return DrawResult::TEMPORARY_ERROR;
  }
  AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing);
  mIsDrawing = true;

  // Apply any 'preserveAspectRatio' override (if specified) to the root
  // element:
  AutoPreserveAspectRatioOverride autoPAR(newSVGContext ? newSVGContext : aSVGContext,
                                          mSVGDocumentWrapper->GetRootSVGElem());

  // Set the animation time:
  AutoSVGTimeSetRestore autoSVGTime(mSVGDocumentWrapper->GetRootSVGElem(),
                                    animTime);

  // Set context paint (if specified) on the document:
  Maybe<AutoSetRestoreSVGContextPaint> autoContextPaint;
  if (haveContextPaint && !blockContextPaint) {
    autoContextPaint.emplace(aSVGContext->GetContextPaint(),
                             mSVGDocumentWrapper->GetDocument());
  }

  // We didn't get a hit in the surface cache, so we'll need to rerasterize.
  CreateSurfaceAndShow(params, aContext->GetDrawTarget()->GetBackendType());
  return DrawResult::SUCCESS;
}
コード例 #3
0
ファイル: RasterImage.cpp プロジェクト: alphan102/gecko-dev
RasterImage::Draw(gfxContext* aContext,
                  const IntSize& aSize,
                  const ImageRegion& aRegion,
                  uint32_t aWhichFrame,
                  SamplingFilter aSamplingFilter,
                  const Maybe<SVGImageContext>& /*aSVGContext - ignored*/,
                  uint32_t aFlags,
                  float aOpacity)
{
  if (aWhichFrame > FRAME_MAX_VALUE) {
    return DrawResult::BAD_ARGS;
  }

  if (mError) {
    return DrawResult::BAD_IMAGE;
  }

  // Illegal -- you can't draw with non-default decode flags.
  // (Disabling colorspace conversion might make sense to allow, but
  // we don't currently.)
  if (ToSurfaceFlags(aFlags) != DefaultSurfaceFlags()) {
    return DrawResult::BAD_ARGS;
  }

  if (!aContext) {
    return DrawResult::BAD_ARGS;
  }

  if (IsUnlocked()) {
    SendOnUnlockedDraw(aFlags);
  }


  // If we're not using SamplingFilter::GOOD, we shouldn't high-quality scale or
  // downscale during decode.
  uint32_t flags = aSamplingFilter == SamplingFilter::GOOD
                 ? aFlags
                 : aFlags & ~FLAG_HIGH_QUALITY_SCALING;

  DrawableSurface surface =
    LookupFrame(aSize, flags, ToPlaybackType(aWhichFrame));
  if (!surface) {
    // Getting the frame (above) touches the image and kicks off decoding.
    if (mDrawStartTime.IsNull()) {
      mDrawStartTime = TimeStamp::Now();
    }
    return DrawResult::NOT_READY;
  }

  bool shouldRecordTelemetry = !mDrawStartTime.IsNull() &&
                               surface->IsFinished();

  auto result = DrawInternal(Move(surface), aContext, aSize,
                             aRegion, aSamplingFilter, flags, aOpacity);

  if (shouldRecordTelemetry) {
      TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
      Telemetry::Accumulate(Telemetry::IMAGE_DECODE_ON_DRAW_LATENCY,
                            int32_t(drawLatency.ToMicroseconds()));
      mDrawStartTime = TimeStamp();
  }

  return result;
}