void
WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder,
                                                  const StackingContextHelper& aSc)
{
  ScrollingLayersHelper scroller(this, aBuilder, aSc);
  StackingContextHelper sc(aSc, aBuilder, this);

  LayerRect rect = Bounds();
  DumpLayerInfo("PaintedLayer", rect);

  LayerRect clipRect = ClipRect().valueOr(rect);
  Maybe<WrImageMask> mask = BuildWrMaskLayer(&sc);
  WrClipRegionToken clip = aBuilder.PushClipRegion(
      sc.ToRelativeWrRect(clipRect),
      mask.ptrOr(nullptr));

  WrImageKey key = GetImageKey();
  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
  WrManager()->AddImageKeyForDiscard(key);

  aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, wr::ImageRendering::Auto, key);
}
Esempio n. 2
0
void
WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
                                 const StackingContextHelper& aSc)
{
  if (!mContainer) {
     return;
  }

  CompositableType type = GetImageClientType();
  if (type == CompositableType::UNKNOWN) {
    return;
  }

  MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN);

  if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) {
    mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
                                                  WrBridge(),
                                                  TextureFlags::DEFAULT);
    if (!mImageClient) {
      return;
    }
    mImageClient->Connect();
  }

  if (GetImageClientType() == CompositableType::IMAGE_BRIDGE && mPipelineId.isNothing()) {
    MOZ_ASSERT(!mImageClient);
    // Alloc async image pipeline id.
    mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
    WrBridge()->AddPipelineIdForAsyncCompositable(mPipelineId.ref(),
                                                  mContainer->GetAsyncContainerHandle());
  } else if (GetImageClientType() == CompositableType::IMAGE && mExternalImageId.isNothing())  {
    MOZ_ASSERT(mImageClient);
    mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
    MOZ_ASSERT(mExternalImageId.isSome());
  }

  if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
    MOZ_ASSERT(!mImageClient);
    MOZ_ASSERT(mExternalImageId.isNothing());

    // Push IFrame for async image pipeline.
    // XXX Remove this once partial display list update is supported.

    ScrollingLayersHelper scroller(this, aBuilder, aSc);

    ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds());

    // We don't push a stacking context for this async image pipeline here.
    // Instead, we do it inside the iframe that hosts the image. As a result,
    // a bunch of the calculations normally done as part of that stacking
    // context need to be done manually and pushed over to the parent side,
    // where it will be done when we build the display list for the iframe.
    // That happens in AsyncImagePipelineManager.

    LayerRect rect = ViewAs<LayerPixel>(bounds,
        PixelCastJustification::MovingDownToChildren);
    DumpLayerInfo("Image Layer async", rect);

    wr::LayoutRect r = aSc.ToRelativeLayoutRect(rect);
    aBuilder.PushIFrame(r, mPipelineId.ref());

    gfx::Matrix4x4 scTransform = GetTransform();
    // Translate is applied as part of PushIFrame()
    scTransform.PostTranslate(-rect.x, -rect.y, 0);
    // Adjust transform as to apply origin
    LayerPoint scOrigin = Bounds().TopLeft();
    scTransform.PreTranslate(-scOrigin.x, -scOrigin.y, 0);

    MaybeIntSize scaleToSize;
    if (mScaleMode != ScaleMode::SCALE_NONE) {
      NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
                   "No other scalemodes than stretch and none supported yet.");
      scaleToSize = Some(mScaleToSize);
    }
    LayerRect scBounds = BoundsForStackingContext();
    wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
    wr::MixBlendMode mixBlendMode = wr::ToMixBlendMode(GetMixBlendMode());

    WrBridge()->AddWebRenderParentCommand(OpUpdateAsyncImagePipeline(mPipelineId.value(),
                                                                     scBounds,
                                                                     scTransform,
                                                                     scaleToSize,
                                                                     filter,
                                                                     mixBlendMode));
    return;
  }

  MOZ_ASSERT(GetImageClientType() == CompositableType::IMAGE);
  MOZ_ASSERT(mImageClient->AsImageClientSingle());

  AutoLockImage autoLock(mContainer);
  Image* image = autoLock.GetImage();
  if (!image) {
    return;
  }
  gfx::IntSize size = image->GetSize();
  mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
                        mContainer,
                        mKey,
                        mExternalImageId.ref());
  if (mKey.isNothing()) {
    return;
  }

  ScrollingLayersHelper scroller(this, aBuilder, aSc);
  StackingContextHelper sc(aSc, aBuilder, this);

  LayerRect rect(0, 0, size.width, size.height);
  if (mScaleMode != ScaleMode::SCALE_NONE) {
    NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
                 "No other scalemodes than stretch and none supported yet.");
    rect = LayerRect(0, 0, mScaleToSize.width, mScaleToSize.height);
  }

  wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);

  DumpLayerInfo("Image Layer", rect);
  if (gfxPrefs::LayersDump()) {
    printf_stderr("ImageLayer %p texture-filter=%s \n",
                  GetLayer(),
                  Stringify(filter).c_str());
  }
  wr::LayoutRect r = sc.ToRelativeLayoutRect(rect);
  aBuilder.PushImage(r, r, filter, mKey.value());
}
Esempio n. 3
0
void
WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
  // XXX We won't keep using ContentClient for WebRenderPaintedLayer in the future and
  // there is a crash problem for ContentClient on MacOS. So replace ContentClient with
  // ImageClient. See bug 1341001.
  //RenderLayerWithReadback(nullptr);

  if (!mImageContainer) {
    mImageContainer = LayerManager::CreateImageContainer();
  }

  if (!mImageClient) {
    mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
                                                  WrBridge(),
                                                  TextureFlags::DEFAULT);
    if (!mImageClient) {
      return;
    }
    mImageClient->Connect();
  }

  if (!mExternalImageId) {
    mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
    MOZ_ASSERT(mExternalImageId);
  }

  LayerIntRegion visibleRegion = GetVisibleRegion();
  LayerIntRect bounds = visibleRegion.GetBounds();
  LayerIntSize size = bounds.Size();
  if (size.IsEmpty()) {
      if (gfxPrefs::LayersDump()) {
        printf_stderr("PaintedLayer %p skipping\n", this->GetLayer());
      }
      return;
  }

  IntSize imageSize(size.width, size.height);
  RefPtr<TextureClient> texture = mImageClient->GetTextureClientRecycler()->CreateOrRecycle(SurfaceFormat::B8G8R8A8,
                                                                                            imageSize,
                                                                                            BackendSelector::Content,
                                                                                            TextureFlags::DEFAULT);
  if (!texture) {
    return;
  }

  {
    TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
    if (!autoLock.Succeeded()) {
      return;
    }
    RefPtr<DrawTarget> target = texture->BorrowDrawTarget();
    if (!target) {
      return;
    }
    target->ClearRect(Rect(0, 0, imageSize.width, imageSize.height));
    target->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
    RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target);
    MOZ_ASSERT(ctx); // already checked the target above

    Manager()->GetPaintedLayerCallback()(this,
                                         ctx,
                                         visibleRegion.ToUnknownRegion(), visibleRegion.ToUnknownRegion(),
                                         DrawRegionClip::DRAW, nsIntRegion(), Manager()->GetPaintedLayerCallbackData());
  }
  RefPtr<TextureWrapperImage> image = new TextureWrapperImage(texture, IntRect(IntPoint(0, 0), imageSize));
  mImageContainer->SetCurrentImageInTransaction(image);
  if (!mImageClient->UpdateImage(mImageContainer, /* unused */0)) {
    return;
  }

  gfx::Matrix4x4 transform = GetTransform();
  gfx::Rect relBounds = GetWrRelBounds();
  gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);

  gfx::Rect rect(0, 0, size.width, size.height);
  gfx::Rect clipRect = GetWrClipRect(rect);

  Maybe<WrImageMask> mask = BuildWrMaskLayer();
  WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect));

  wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());

  DumpLayerInfo("PaintedLayer", rect);

  WrImageKey key;
  key.mNamespace = WrBridge()->GetNamespace();
  key.mHandle = WrBridge()->GetNextResourceId();
  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));

  aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                              wr::ToWrRect(overflow),
                              mask.ptrOr(nullptr),
                              1.0f,
                              //GetAnimations(),
                              transform,
                              mixBlendMode);
  aBuilder.PushImage(wr::ToWrRect(rect), clip, wr::ImageRendering::Auto, key);
  aBuilder.PopStackingContext();
}
void
WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
                                       const StackingContextHelper& aSc)
{
  LayerIntRegion visibleRegion = GetVisibleRegion();
  LayerIntRect bounds = visibleRegion.GetBounds();
  LayerIntSize size = bounds.Size();

  if (visibleRegion.IsEmpty()) {
    if (gfxPrefs::LayersDump()) {
      printf_stderr("PaintedLayer %p skipping\n", this->GetLayer());
    }
    return;
  }

  nsIntRegion regionToPaint;
  regionToPaint.Sub(mVisibleRegion.ToUnknownRegion(), mValidRegion);

  // We have something to paint but can't. This usually happens only in
  // empty transactions
  if (!regionToPaint.IsEmpty() && !WrManager()->GetPaintedLayerCallback()) {
    WrManager()->SetTransactionIncomplete();
    return;
  }

  IntSize imageSize(size.ToUnknownSize());
  if (!regionToPaint.IsEmpty() && WrManager()->GetPaintedLayerCallback()) {
    RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
    RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, imageSize, gfx::SurfaceFormat::B8G8R8X8);
    RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt);

    dt->ClearRect(Rect(0, 0, imageSize.width, imageSize.height));
    dt->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
    RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(dt);
    MOZ_ASSERT(ctx); // already checked the target above

    WrManager()->GetPaintedLayerCallback()(this,
                                           ctx,
                                           visibleRegion.ToUnknownRegion(), visibleRegion.ToUnknownRegion(),
                                           DrawRegionClip::DRAW, nsIntRegion(), WrManager()->GetPaintedLayerCallbackData());

    if (gfxPrefs::WebRenderHighlightPaintedLayers()) {
      dt->SetTransform(Matrix());
      dt->FillRect(Rect(0, 0, imageSize.width, imageSize.height), ColorPattern(Color(1.0, 0.0, 0.0, 0.5)));
    }

    wr::ByteBuffer bytes;
    bytes.Allocate(recorder->RecordingSize());
    DebugOnly<bool> ok = recorder->CopyRecording((char*)bytes.AsSlice().begin().get(), bytes.AsSlice().length());
    MOZ_ASSERT(ok);

    //XXX: We should switch to updating the blob image instead of adding a new one
    //     That will get rid of this discard bit
    if (mImageKey.isSome()) {
      WrManager()->AddImageKeyForDiscard(mImageKey.value());
    }
    mImageKey = Some(GetImageKey());
    WrBridge()->SendAddBlobImage(mImageKey.value(), imageSize, size.width * 4, dt->GetFormat(), bytes);
  } else {
    MOZ_ASSERT(GetInvalidRegion().IsEmpty());
  }

  ScrollingLayersHelper scroller(this, aBuilder, aSc);
  StackingContextHelper sc(aSc, aBuilder, this);
  LayerRect rect = Bounds();
  DumpLayerInfo("PaintedLayer", rect);

  LayerRect clipRect = ClipRect().valueOr(rect);
  Maybe<WrImageMask> mask = BuildWrMaskLayer(&sc);
  WrClipRegionToken clip = aBuilder.PushClipRegion(
      sc.ToRelativeWrRect(clipRect),
      mask.ptrOr(nullptr));

  aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, wr::ImageRendering::Auto, mImageKey.value());
}