bool WebRenderPaintedLayer::UpdateImageClient() { MOZ_ASSERT(WrManager()->GetPaintedLayerCallback()); LayerIntRegion visibleRegion = GetVisibleRegion(); LayerIntRect bounds = visibleRegion.GetBounds(); LayerIntSize size = bounds.Size(); IntSize imageSize(size.width, size.height); UpdateImageHelper helper(mImageContainer, mImageClient, imageSize); { RefPtr<DrawTarget> target = helper.GetDrawTarget(); if (!target) { return false; } 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 WrManager()->GetPaintedLayerCallback()(this, ctx, visibleRegion.ToUnknownRegion(), visibleRegion.ToUnknownRegion(), DrawRegionClip::DRAW, nsIntRegion(), WrManager()->GetPaintedLayerCallbackData()); if (gfxPrefs::WebRenderHighlightPaintedLayers()) { target->SetTransform(Matrix()); target->FillRect(Rect(0, 0, imageSize.width, imageSize.height), ColorPattern(Color(1.0, 0.0, 0.0, 0.5))); } } if (!helper.UpdateImage()) { return false; } return true; }
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()); }