mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Do image scaling on the GPU (bug 650988, r=roc,cjones).
This commit is contained in:
parent
b5690cc915
commit
6ced71cf11
@ -1602,7 +1602,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||
mBounds.UnionRect(mBounds, itemContent);
|
||||
itemVisibleRect.IntersectRect(itemVisibleRect, itemDrawRect);
|
||||
|
||||
LayerState layerState = item->GetLayerState(mBuilder, mManager);
|
||||
LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
|
||||
|
||||
nsIFrame* activeScrolledRoot =
|
||||
nsLayoutUtils::GetActiveScrolledRootFor(item, mBuilder);
|
||||
@ -2070,7 +2070,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
if (aContainerItem &&
|
||||
aContainerItem->GetLayerState(aBuilder, aManager) == LAYER_ACTIVE_EMPTY) {
|
||||
aContainerItem->GetLayerState(aBuilder, aManager, aParameters) == LAYER_ACTIVE_EMPTY) {
|
||||
// Empty layers only have metadata and should never have display items. We
|
||||
// early exit because later, invalidation will walk up the frame tree to
|
||||
// determine which thebes layer gets invalidated. Since an empty layer
|
||||
|
@ -1654,9 +1654,10 @@ void nsDisplayWrapList::Paint(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
bool nsDisplayWrapList::ChildrenCanBeInactive(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aActiveScrolledRoot) {
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aActiveScrolledRoot) {
|
||||
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
|
||||
nsIFrame* f = i->GetUnderlyingFrame();
|
||||
if (f) {
|
||||
@ -1666,12 +1667,12 @@ bool nsDisplayWrapList::ChildrenCanBeInactive(nsDisplayListBuilder* aBuilder,
|
||||
return false;
|
||||
}
|
||||
|
||||
LayerState state = i->GetLayerState(aBuilder, aManager);
|
||||
LayerState state = i->GetLayerState(aBuilder, aManager, aParameters);
|
||||
if (state == LAYER_ACTIVE)
|
||||
return false;
|
||||
if (state == LAYER_NONE) {
|
||||
nsDisplayList* list = i->GetList();
|
||||
if (list && !ChildrenCanBeInactive(aBuilder, aManager, *list, aActiveScrolledRoot))
|
||||
if (list && !ChildrenCanBeInactive(aBuilder, aManager, aParameters, *list, aActiveScrolledRoot))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1810,13 +1811,14 @@ IsItemTooSmallForActiveLayer(nsDisplayItem* aItem)
|
||||
|
||||
nsDisplayItem::LayerState
|
||||
nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager) {
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters) {
|
||||
if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateOpacityLayer) &&
|
||||
!IsItemTooSmallForActiveLayer(this))
|
||||
return LAYER_ACTIVE;
|
||||
nsIFrame* activeScrolledRoot =
|
||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
||||
return !ChildrenCanBeInactive(aBuilder, aManager, mList, activeScrolledRoot)
|
||||
return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot)
|
||||
? LAYER_ACTIVE : LAYER_INACTIVE;
|
||||
}
|
||||
|
||||
@ -1992,7 +1994,8 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
LayerState
|
||||
nsDisplayScrollLayer::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
// Force this as a layer so we can scroll asynchronously.
|
||||
// This causes incorrect rendering for rounded clips!
|
||||
@ -2083,7 +2086,8 @@ nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer()
|
||||
|
||||
LayerState
|
||||
nsDisplayScrollInfoLayer::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
return LAYER_ACTIVE_EMPTY;
|
||||
}
|
||||
@ -2677,7 +2681,8 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
||||
|
||||
nsDisplayItem::LayerState
|
||||
nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager) {
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters) {
|
||||
// Here we check if the *post-transform* bounds of this item are big enough
|
||||
// to justify an active layer.
|
||||
if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateTransformLayer) &&
|
||||
@ -2688,9 +2693,10 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* activeScrolledRoot =
|
||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
||||
return !mStoredList.ChildrenCanBeInactive(aBuilder,
|
||||
aManager,
|
||||
*mStoredList.GetList(),
|
||||
activeScrolledRoot)
|
||||
aManager,
|
||||
aParameters,
|
||||
*mStoredList.GetList(),
|
||||
activeScrolledRoot)
|
||||
? LAYER_ACTIVE : LAYER_INACTIVE;
|
||||
}
|
||||
|
||||
|
@ -596,6 +596,7 @@ protected:
|
||||
*/
|
||||
class nsDisplayItem : public nsDisplayItemLink {
|
||||
public:
|
||||
typedef mozilla::FrameLayerBuilder::ContainerParameters ContainerParameters;
|
||||
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
@ -765,7 +766,8 @@ public:
|
||||
* every time we paint.
|
||||
*/
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{ return mozilla::LAYER_NONE; }
|
||||
/**
|
||||
* Actually paint this item to some rendering context.
|
||||
@ -800,7 +802,6 @@ public:
|
||||
* FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
|
||||
* constructed.
|
||||
*/
|
||||
typedef mozilla::FrameLayerBuilder::ContainerParameters ContainerParameters;
|
||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aContainerParameters)
|
||||
@ -1805,9 +1806,10 @@ public:
|
||||
* and they all have the given aActiveScrolledRoot.
|
||||
*/
|
||||
static bool ChildrenCanBeInactive(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aActiveScrolledRoot);
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aActiveScrolledRoot);
|
||||
|
||||
protected:
|
||||
nsDisplayWrapList() {}
|
||||
@ -1875,7 +1877,8 @@ public:
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aContainerParameters);
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager);
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters);
|
||||
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aAllowVisibleRegionExpansion);
|
||||
@ -1899,7 +1902,8 @@ public:
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aContainerParameters);
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
return mozilla::LAYER_ACTIVE;
|
||||
}
|
||||
@ -1966,7 +1970,8 @@ public:
|
||||
const nsRect& aAllowVisibleRegionExpansion);
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager);
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters);
|
||||
|
||||
virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem);
|
||||
@ -2007,7 +2012,8 @@ public:
|
||||
#endif
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager);
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters);
|
||||
|
||||
virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem);
|
||||
@ -2230,7 +2236,8 @@ public:
|
||||
bool* aSnap);
|
||||
virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor);
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager);
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters);
|
||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aContainerParameters);
|
||||
|
@ -182,6 +182,20 @@ nsLayoutUtils::UseBackgroundNearestFiltering()
|
||||
return sUseBackgroundNearestFilteringEnabled;
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::GPUImageScalingEnabled()
|
||||
{
|
||||
static bool sGPUImageScalingEnabled;
|
||||
static bool sGPUImageScalingPrefInitialised = false;
|
||||
|
||||
if (!sGPUImageScalingPrefInitialised) {
|
||||
sGPUImageScalingPrefInitialised = true;
|
||||
sGPUImageScalingEnabled = mozilla::Preferences::GetBool("layout.gpu-image-scaling.enabled", false);
|
||||
}
|
||||
|
||||
return sGPUImageScalingEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutUtils::UnionChildOverflow(nsIFrame* aFrame,
|
||||
nsOverflowAreas& aOverflowAreas)
|
||||
|
@ -1502,6 +1502,12 @@ public:
|
||||
*/
|
||||
static bool UseBackgroundNearestFiltering();
|
||||
|
||||
/**
|
||||
* Checks whether we want to use the GPU to scale images when
|
||||
* possible.
|
||||
*/
|
||||
static bool GPUImageScalingEnabled();
|
||||
|
||||
/**
|
||||
* Unions the overflow areas of all non-popup children of aFrame with
|
||||
* aOverflowAreas.
|
||||
|
@ -109,7 +109,8 @@ public:
|
||||
BuildLayer(aBuilder, aManager, this);
|
||||
}
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const FrameLayerBuilder::ContainerParameters& aParameters)
|
||||
{
|
||||
if (CanvasElementFromContent(mFrame->GetContent())->ShouldForceInactiveLayer(aManager))
|
||||
return LAYER_INACTIVE;
|
||||
|
@ -1234,11 +1234,9 @@ nsDisplayImage::GetContainer()
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayImage::ConfigureLayer(ImageLayer* aLayer)
|
||||
gfxRect
|
||||
nsDisplayImage::GetDestRect()
|
||||
{
|
||||
aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
|
||||
|
||||
PRInt32 factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
nsImageFrame* imageFrame = static_cast<nsImageFrame*>(mFrame);
|
||||
|
||||
@ -1246,11 +1244,77 @@ nsDisplayImage::ConfigureLayer(ImageLayer* aLayer)
|
||||
gfxRect destRect(dest.x, dest.y, dest.width, dest.height);
|
||||
destRect.ScaleInverse(factor);
|
||||
|
||||
return destRect;
|
||||
}
|
||||
|
||||
LayerState
|
||||
nsDisplayImage::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const FrameLayerBuilder::ContainerParameters& aParameters)
|
||||
{
|
||||
if (mImage->GetType() != imgIContainer::TYPE_RASTER ||
|
||||
!aManager->IsCompositingCheap() ||
|
||||
!nsLayoutUtils::GPUImageScalingEnabled()) {
|
||||
return LAYER_NONE;
|
||||
}
|
||||
|
||||
PRInt32 imageWidth;
|
||||
PRInt32 imageHeight;
|
||||
mImage->GetWidth(&imageWidth);
|
||||
mImage->GetHeight(&imageHeight);
|
||||
|
||||
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
|
||||
|
||||
gfxRect destRect = GetDestRect();
|
||||
|
||||
destRect.width *= aParameters.mXScale;
|
||||
destRect.height *= aParameters.mYScale;
|
||||
|
||||
// Calculate the scaling factor for the frame.
|
||||
gfxSize scale = gfxSize(destRect.width / imageWidth, destRect.height / imageHeight);
|
||||
|
||||
// If we are not scaling at all, no point in separating this into a layer.
|
||||
if (scale.width == 1.0f && scale.height == 1.0f) {
|
||||
return LAYER_INACTIVE;
|
||||
}
|
||||
|
||||
// If the target size is pretty small, no point in using a layer.
|
||||
if (destRect.width * destRect.height < 64 * 64) {
|
||||
return LAYER_INACTIVE;
|
||||
}
|
||||
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
already_AddRefed<Layer>
|
||||
nsDisplayImage::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
nsRefPtr<ImageContainer> container;
|
||||
nsresult rv = mImage->GetImageContainer(getter_AddRefs(container));
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
nsRefPtr<ImageLayer> layer = aManager->CreateImageLayer();
|
||||
layer->SetContainer(container);
|
||||
ConfigureLayer(layer);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayImage::ConfigureLayer(ImageLayer *aLayer)
|
||||
{
|
||||
aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
|
||||
|
||||
PRInt32 imageWidth;
|
||||
PRInt32 imageHeight;
|
||||
mImage->GetWidth(&imageWidth);
|
||||
mImage->GetHeight(&imageHeight);
|
||||
|
||||
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
|
||||
|
||||
const gfxRect destRect = GetDestRect();
|
||||
|
||||
gfxMatrix transform;
|
||||
transform.Translate(destRect.TopLeft());
|
||||
transform.Scale(destRect.Width()/imageWidth,
|
||||
|
@ -410,13 +410,23 @@ public:
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx);
|
||||
|
||||
|
||||
/**
|
||||
* Returns an ImageContainer for this image if the image type
|
||||
* supports it (TYPE_RASTER only).
|
||||
*/
|
||||
already_AddRefed<ImageContainer> GetContainer();
|
||||
|
||||
|
||||
gfxRect GetDestRect();
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters);
|
||||
|
||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aContainerParameters);
|
||||
|
||||
/**
|
||||
* Configure an ImageLayer for this display item.
|
||||
* Set the required filter and scaling transform.
|
||||
|
@ -932,7 +932,8 @@ public:
|
||||
}
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
|
@ -168,8 +168,8 @@ public:
|
||||
LayerManager* aManager,
|
||||
nsDisplayItem* aItem);
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager);
|
||||
LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager);
|
||||
|
||||
already_AddRefed<ImageContainer> GetImageContainer();
|
||||
/**
|
||||
@ -330,7 +330,8 @@ public:
|
||||
}
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{
|
||||
return static_cast<nsObjectFrame*>(mFrame)->GetLayerState(aBuilder,
|
||||
aManager);
|
||||
|
@ -360,7 +360,8 @@ public:
|
||||
}
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const FrameLayerBuilder::ContainerParameters& aParameters)
|
||||
{
|
||||
if (aManager->GetBackendType() != LayerManager::LAYERS_BASIC) {
|
||||
// For non-basic layer managers we can assume that compositing
|
||||
|
@ -161,7 +161,8 @@ public:
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
LayerManager* aManager,
|
||||
const ContainerParameters& aParameters)
|
||||
{ return mozilla::LAYER_ACTIVE; }
|
||||
|
||||
NS_OVERRIDE
|
||||
|
Loading…
Reference in New Issue
Block a user