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); }
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()); }
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()); }