зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1377571 - Add fallback path for layers-free. r=jrmuizel
MozReview-Commit-ID: KOM7JXYljX2 --HG-- extra : rebase_source : 94a8c314ac311a05256a27bd61648815b0e42734
This commit is contained in:
Родитель
ae76578b49
Коммит
a11b08a3ac
|
@ -13,6 +13,7 @@
|
||||||
#include "mozilla/layers/StackingContextHelper.h"
|
#include "mozilla/layers/StackingContextHelper.h"
|
||||||
#include "mozilla/layers/TextureClient.h"
|
#include "mozilla/layers/TextureClient.h"
|
||||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||||
|
#include "mozilla/layers/UpdateImageHelper.h"
|
||||||
#include "WebRenderCanvasLayer.h"
|
#include "WebRenderCanvasLayer.h"
|
||||||
#include "WebRenderColorLayer.h"
|
#include "WebRenderColorLayer.h"
|
||||||
#include "WebRenderContainerLayer.h"
|
#include "WebRenderContainerLayer.h"
|
||||||
|
@ -223,7 +224,7 @@ WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDi
|
||||||
|
|
||||||
if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this,
|
if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this,
|
||||||
aDisplayListBuilder)) {
|
aDisplayListBuilder)) {
|
||||||
// TODO: fallback
|
PushItemAsImage(item, aBuilder, aSc, aDisplayListBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aDisplayList->AppendToTop(&savedItems);
|
aDisplayList->AppendToTop(&savedItems);
|
||||||
|
@ -304,49 +305,132 @@ WebRenderLayerManager::PushImage(nsDisplayItem* aItem,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
|
DrawTarget* aDT,
|
||||||
|
const LayerRect& aImageRect,
|
||||||
|
const LayerPoint& aOffset,
|
||||||
|
nsDisplayListBuilder* aDisplayListBuilder)
|
||||||
|
{
|
||||||
|
aDT->ClearRect(aImageRect.ToUnknownRect());
|
||||||
|
RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT, aOffset.ToUnknownPoint());
|
||||||
|
MOZ_ASSERT(context);
|
||||||
|
aItem->Paint(aDisplayListBuilder, context);
|
||||||
|
|
||||||
|
if (gfxPrefs::WebRenderHighlightPaintedLayers()) {
|
||||||
|
aDT->SetTransform(Matrix());
|
||||||
|
aDT->FillRect(Rect(0, 0, aImageRect.width, aImageRect.height), ColorPattern(Color(1.0, 0.0, 0.0, 0.5)));
|
||||||
|
}
|
||||||
|
if (aItem->Frame()->PresContext()->GetPaintFlashing()) {
|
||||||
|
aDT->SetTransform(Matrix());
|
||||||
|
float r = float(rand()) / RAND_MAX;
|
||||||
|
float g = float(rand()) / RAND_MAX;
|
||||||
|
float b = float(rand()) / RAND_MAX;
|
||||||
|
aDT->FillRect(Rect(0, 0, aImageRect.width, aImageRect.height), ColorPattern(Color(r, g, b, 0.5)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WebRenderLayerManager::PushItemAsBlobImage(nsDisplayItem* aItem,
|
WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
|
||||||
wr::DisplayListBuilder& aBuilder,
|
wr::DisplayListBuilder& aBuilder,
|
||||||
const StackingContextHelper& aSc,
|
const StackingContextHelper& aSc,
|
||||||
nsDisplayListBuilder* aDisplayListBuilder)
|
nsDisplayListBuilder* aDisplayListBuilder)
|
||||||
{
|
{
|
||||||
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
|
RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
|
||||||
|
|
||||||
bool snap;
|
bool snap;
|
||||||
|
nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
|
||||||
|
nsRect clippedBounds = itemBounds;
|
||||||
|
|
||||||
|
const DisplayItemClip& clip = aItem->GetClip();
|
||||||
|
if (clip.HasClip()) {
|
||||||
|
clippedBounds = itemBounds.Intersect(clip.GetClipRect());
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
|
||||||
LayerRect bounds = ViewAs<LayerPixel>(
|
LayerRect bounds = ViewAs<LayerPixel>(
|
||||||
LayoutDeviceRect::FromAppUnits(aItem->GetBounds(aDisplayListBuilder, &snap), appUnitsPerDevPixel),
|
LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel),
|
||||||
PixelCastJustification::WebRenderHasUnitResolution);
|
PixelCastJustification::WebRenderHasUnitResolution);
|
||||||
|
|
||||||
LayerIntSize imageSize = RoundedToInt(bounds.Size());
|
LayerIntSize imageSize = RoundedToInt(bounds.Size());
|
||||||
LayerRect imageRect;
|
LayerRect imageRect;
|
||||||
imageRect.SizeTo(LayerSize(imageSize));
|
imageRect.SizeTo(LayerSize(imageSize));
|
||||||
|
if (imageSize.width == 0 || imageSize.height == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPoint shift = clippedBounds.TopLeft() - itemBounds.TopLeft();
|
||||||
|
LayerPoint offset = ViewAs<LayerPixel>(
|
||||||
|
LayoutDevicePoint::FromAppUnits(aItem->ToReferenceFrame() + shift, appUnitsPerDevPixel),
|
||||||
|
PixelCastJustification::WebRenderHasUnitResolution);
|
||||||
|
|
||||||
|
nsRegion invalidRegion;
|
||||||
|
nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
|
||||||
|
|
||||||
|
if (geometry) {
|
||||||
|
nsPoint shift = itemBounds.TopLeft() - geometry->mBounds.TopLeft();
|
||||||
|
geometry->MoveBy(shift);
|
||||||
|
aItem->ComputeInvalidationRegion(aDisplayListBuilder, geometry, &invalidRegion);
|
||||||
|
nsRect lastBounds = fallbackData->GetBounds();
|
||||||
|
lastBounds.MoveBy(shift);
|
||||||
|
|
||||||
|
if (!lastBounds.IsEqualInterior(clippedBounds)) {
|
||||||
|
invalidRegion.OrWith(lastBounds);
|
||||||
|
invalidRegion.OrWith(clippedBounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!geometry || !invalidRegion.IsEmpty()) {
|
||||||
|
if (gfxPrefs::WebRenderBlobImages()) {
|
||||||
RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
|
RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
|
||||||
RefPtr<gfx::DrawTarget> dummyDt =
|
RefPtr<gfx::DrawTarget> dummyDt =
|
||||||
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8X8);
|
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8X8);
|
||||||
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
|
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
|
||||||
LayerPoint offset = ViewAs<LayerPixel>(
|
PaintItemByDrawTarget(aItem, dt, imageRect, offset, aDisplayListBuilder);
|
||||||
LayoutDevicePoint::FromAppUnits(aItem->ToReferenceFrame(), appUnitsPerDevPixel),
|
recorder->Finish();
|
||||||
PixelCastJustification::WebRenderHasUnitResolution);
|
|
||||||
|
|
||||||
{
|
|
||||||
dt->ClearRect(imageRect.ToUnknownRect());
|
|
||||||
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt, offset.ToUnknownPoint());
|
|
||||||
MOZ_ASSERT(context);
|
|
||||||
|
|
||||||
aItem->Paint(aDisplayListBuilder, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
|
wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
|
||||||
|
wr::ImageKey key = WrBridge()->GetNextImageKey();
|
||||||
|
WrBridge()->SendAddBlobImage(key, imageSize.ToUnknownSize(), imageSize.width * 4, dt->GetFormat(), bytes);
|
||||||
|
fallbackData->SetKey(key);
|
||||||
|
} else {
|
||||||
|
fallbackData->CreateImageClientIfNeeded();
|
||||||
|
RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
|
||||||
|
RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
|
||||||
|
|
||||||
|
{
|
||||||
|
UpdateImageHelper helper(imageContainer, imageClient, imageSize.ToUnknownSize());
|
||||||
|
{
|
||||||
|
RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
|
||||||
|
PaintItemByDrawTarget(aItem, dt, imageRect, offset, aDisplayListBuilder);
|
||||||
|
}
|
||||||
|
if (!helper.UpdateImage()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force update the key in fallback data since we repaint the image in this path.
|
||||||
|
// If not force update, fallbackData may reuse the original key because it
|
||||||
|
// doesn't know UpdateImageHelper already updated the image container.
|
||||||
|
if (!fallbackData->UpdateImageKey(imageContainer, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry = aItem->AllocateGeometry(aDisplayListBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update current bounds to fallback data
|
||||||
|
fallbackData->SetGeometry(Move(geometry));
|
||||||
|
fallbackData->SetBounds(clippedBounds);
|
||||||
|
|
||||||
|
MOZ_ASSERT(fallbackData->GetKey());
|
||||||
|
|
||||||
WrRect dest = aSc.ToRelativeWrRect(imageRect + offset);
|
WrRect dest = aSc.ToRelativeWrRect(imageRect + offset);
|
||||||
WrImageKey key = WrBridge()->GetNextImageKey();
|
|
||||||
WrBridge()->SendAddBlobImage(key, imageSize.ToUnknownSize(), imageSize.width * 4, dt->GetFormat(), bytes);
|
|
||||||
AddImageKeyForDiscard(key);
|
|
||||||
|
|
||||||
aBuilder.PushImage(dest,
|
aBuilder.PushImage(dest,
|
||||||
dest,
|
dest,
|
||||||
wr::ImageRendering::Auto,
|
wr::ImageRendering::Auto,
|
||||||
key);
|
fallbackData->GetKey().value());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||||
const StackingContextHelper& aSc,
|
const StackingContextHelper& aSc,
|
||||||
const LayerRect& aRect);
|
const LayerRect& aRect);
|
||||||
bool PushItemAsBlobImage(nsDisplayItem* aItem,
|
bool PushItemAsImage(nsDisplayItem* aItem,
|
||||||
wr::DisplayListBuilder& aBuilder,
|
wr::DisplayListBuilder& aBuilder,
|
||||||
const StackingContextHelper& aSc,
|
const StackingContextHelper& aSc,
|
||||||
nsDisplayListBuilder* aDisplayListBuilder);
|
nsDisplayListBuilder* aDisplayListBuilder);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "WebRenderUserData.h"
|
#include "WebRenderUserData.h"
|
||||||
|
#include "nsDisplayListInvalidation.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
@ -35,7 +36,7 @@ WebRenderImageData::~WebRenderImageData()
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<wr::ImageKey>
|
Maybe<wr::ImageKey>
|
||||||
WebRenderImageData::UpdateImageKey(ImageContainer* aContainer)
|
WebRenderImageData::UpdateImageKey(ImageContainer* aContainer, bool aForceUpdate)
|
||||||
{
|
{
|
||||||
CreateImageClientIfNeeded();
|
CreateImageClientIfNeeded();
|
||||||
CreateExternalImageIfNeeded();
|
CreateExternalImageIfNeeded();
|
||||||
|
@ -61,7 +62,7 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reuse old key if generation is not updated.
|
// Reuse old key if generation is not updated.
|
||||||
if (oldCounter == imageClient->GetLastUpdateGenerationCounter() && mKey) {
|
if (!aForceUpdate && oldCounter == imageClient->GetLastUpdateGenerationCounter() && mKey) {
|
||||||
return mKey;
|
return mKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +78,13 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer)
|
||||||
return mKey;
|
return mKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<ImageClient>
|
||||||
|
WebRenderImageData::GetImageClient()
|
||||||
|
{
|
||||||
|
RefPtr<ImageClient> imageClient = mImageClient;
|
||||||
|
return imageClient.forget();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||||
ImageContainer* aContainer,
|
ImageContainer* aContainer,
|
||||||
|
@ -140,5 +148,26 @@ WebRenderImageData::CreateExternalImageIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebRenderFallbackData::~WebRenderFallbackData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager)
|
||||||
|
: WebRenderImageData(aWRManager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoPtr<nsDisplayItemGeometry>
|
||||||
|
WebRenderFallbackData::GetGeometry()
|
||||||
|
{
|
||||||
|
return mGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebRenderFallbackData::SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
|
||||||
|
{
|
||||||
|
mGeometry = aGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "mozilla/layers/StackingContextHelper.h"
|
#include "mozilla/layers/StackingContextHelper.h"
|
||||||
#include "mozilla/webrender/WebRenderAPI.h"
|
#include "mozilla/webrender/WebRenderAPI.h"
|
||||||
|
|
||||||
|
class nsDisplayItemGeometry;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
class ImageClient;
|
class ImageClient;
|
||||||
|
@ -30,6 +32,7 @@ public:
|
||||||
|
|
||||||
enum class UserDataType {
|
enum class UserDataType {
|
||||||
eImage,
|
eImage,
|
||||||
|
eFallback,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual UserDataType GetType() = 0;
|
virtual UserDataType GetType() = 0;
|
||||||
|
@ -51,8 +54,11 @@ public:
|
||||||
virtual WebRenderImageData* AsImageData() override { return this; }
|
virtual WebRenderImageData* AsImageData() override { return this; }
|
||||||
virtual UserDataType GetType() override { return UserDataType::eImage; }
|
virtual UserDataType GetType() override { return UserDataType::eImage; }
|
||||||
static UserDataType Type() { return UserDataType::eImage; }
|
static UserDataType Type() { return UserDataType::eImage; }
|
||||||
|
Maybe<wr::ImageKey> GetKey() { return mKey; }
|
||||||
|
void SetKey(const wr::ImageKey& aKey) { mKey = Some(aKey); }
|
||||||
|
already_AddRefed<ImageClient> GetImageClient();
|
||||||
|
|
||||||
Maybe<wr::ImageKey> UpdateImageKey(ImageContainer* aContainer);
|
Maybe<wr::ImageKey> UpdateImageKey(ImageContainer* aContainer, bool aForceUpdate = false);
|
||||||
|
|
||||||
void CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
void CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||||
ImageContainer* aContainer,
|
ImageContainer* aContainer,
|
||||||
|
@ -64,8 +70,9 @@ public:
|
||||||
const WrImageRendering& aFilter,
|
const WrImageRendering& aFilter,
|
||||||
const WrMixBlendMode& aMixBlendMode);
|
const WrMixBlendMode& aMixBlendMode);
|
||||||
|
|
||||||
protected:
|
|
||||||
void CreateImageClientIfNeeded();
|
void CreateImageClientIfNeeded();
|
||||||
|
|
||||||
|
protected:
|
||||||
void CreateExternalImageIfNeeded();
|
void CreateExternalImageIfNeeded();
|
||||||
|
|
||||||
wr::MaybeExternalImageId mExternalImageId;
|
wr::MaybeExternalImageId mExternalImageId;
|
||||||
|
@ -75,6 +82,24 @@ protected:
|
||||||
RefPtr<ImageContainer> mContainer;
|
RefPtr<ImageContainer> mContainer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WebRenderFallbackData : public WebRenderImageData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit WebRenderFallbackData(WebRenderLayerManager* aWRManager);
|
||||||
|
virtual ~WebRenderFallbackData();
|
||||||
|
|
||||||
|
virtual UserDataType GetType() override { return UserDataType::eFallback; }
|
||||||
|
static UserDataType Type() { return UserDataType::eFallback; }
|
||||||
|
nsAutoPtr<nsDisplayItemGeometry> GetGeometry();
|
||||||
|
void SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry);
|
||||||
|
nsRect GetBounds() { return mBounds; }
|
||||||
|
void SetBounds(const nsRect& aRect) { mBounds = aRect; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
||||||
|
nsRect mBounds;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -490,7 +490,7 @@ BulletRenderer::CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsPathType());
|
MOZ_ASSERT(IsPathType());
|
||||||
|
|
||||||
if (!aManager->PushItemAsBlobImage(aItem, aBuilder, aSc, aDisplayListBuilder)) {
|
if (!aManager->PushItemAsImage(aItem, aBuilder, aSc, aDisplayListBuilder)) {
|
||||||
NS_WARNING("Fail to create WebRender commands for Bullet path.");
|
NS_WARNING("Fail to create WebRender commands for Bullet path.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче