mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1013385 - Add the layer bounds to the layers API and use it for checkerboarding. r=mattwoodrow,BenWa
This commit is contained in:
parent
999a08b6c5
commit
6b0862f4b0
@ -1467,6 +1467,9 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
if (!mTransform.IsIdentity()) {
|
||||
AppendToString(aStream, mTransform, " [transform=", "]");
|
||||
}
|
||||
if (!mLayerBounds.IsEmpty()) {
|
||||
AppendToString(aStream, mLayerBounds, " [bounds=", "]");
|
||||
}
|
||||
if (!mVisibleRegion.IsEmpty()) {
|
||||
AppendToString(aStream, mVisibleRegion, " [visible=", "]");
|
||||
} else {
|
||||
|
@ -805,6 +805,24 @@ public:
|
||||
Mutated();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* The union of the bounds of all the display item that got flattened
|
||||
* into this layer. This is intended to be an approximation to the
|
||||
* size of the layer if the nearest scrollable ancestor had an infinitely
|
||||
* large displayport. Computing this more exactly is too expensive,
|
||||
* but this approximation is sufficient for what we need to use it for.
|
||||
*/
|
||||
virtual void SetLayerBounds(const nsIntRect& aLayerBounds)
|
||||
{
|
||||
if (!mLayerBounds.IsEqualEdges(aLayerBounds)) {
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) LayerBounds", this));
|
||||
mLayerBounds = aLayerBounds;
|
||||
Mutated();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* Tell this layer which region will be visible. The visible region
|
||||
@ -1178,6 +1196,7 @@ public:
|
||||
gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; }
|
||||
const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; }
|
||||
uint32_t GetContentFlags() { return mContentFlags; }
|
||||
const nsIntRect& GetLayerBounds() const { return mLayerBounds; }
|
||||
const nsIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
|
||||
const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
|
||||
uint32_t GetFrameMetricsCount() const { return mFrameMetrics.Length(); }
|
||||
@ -1589,6 +1608,7 @@ protected:
|
||||
void* mImplData;
|
||||
nsRefPtr<Layer> mMaskLayer;
|
||||
gfx::UserData mUserData;
|
||||
nsIntRect mLayerBounds;
|
||||
nsIntRegion mVisibleRegion;
|
||||
nsTArray<FrameMetrics> mFrameMetrics;
|
||||
EventRegions mEventRegions;
|
||||
|
@ -2620,6 +2620,19 @@ Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
|
||||
Matrix4x4().Scale(zoomChange, zoomChange, 1);
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::IsCurrentlyCheckerboarding() const {
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
if (!gfxPrefs::APZAllowCheckerboarding()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset;
|
||||
CSSRect painted = mLastContentPaintMetrics.mDisplayPort + mLastContentPaintMetrics.GetScrollOffset();
|
||||
CSSRect visible = CSSRect(currentScrollOffset, mFrameMetrics.CalculateCompositedSizeInCssPixels());
|
||||
return !painted.Contains(visible);
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
|
||||
AssertOnCompositorThread();
|
||||
|
||||
|
@ -240,6 +240,14 @@ public:
|
||||
*/
|
||||
Matrix4x4 GetTransformToLastDispatchedPaint() const;
|
||||
|
||||
/**
|
||||
* Returns whether or not the APZC is currently in a state of checkerboarding.
|
||||
* This is a simple computation based on the last-painted content and whether
|
||||
* the async transform has pushed it so far that it doesn't fully contain the
|
||||
* composition bounds.
|
||||
*/
|
||||
bool IsCurrentlyCheckerboarding() const;
|
||||
|
||||
/**
|
||||
* Recalculates the displayport. Ideally, this should paint an area bigger
|
||||
* than the composite-to dimensions so that when you scroll down, you don't
|
||||
|
@ -48,6 +48,24 @@ namespace layers {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
static bool
|
||||
LayerHasCheckerboardingAPZC(Layer* aLayer, gfxRGBA* aOutColor)
|
||||
{
|
||||
for (LayerMetricsWrapper i(aLayer, LayerMetricsWrapper::StartAt::BOTTOM); i; i = i.GetParent()) {
|
||||
if (!i.Metrics().IsScrollable()) {
|
||||
continue;
|
||||
}
|
||||
if (i.GetApzc() && i.GetApzc()->IsCurrentlyCheckerboarding()) {
|
||||
if (aOutColor) {
|
||||
*aOutColor = i.Metrics().GetBackgroundColor();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a rectangle of content painted opaquely by aLayer. Very consertative;
|
||||
* bails by returning an empty rect in any tricky situations.
|
||||
@ -180,12 +198,14 @@ ContainerPrepare(ContainerT* aContainer,
|
||||
|
||||
if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() &&
|
||||
!layerToRender->GetLayer()->AsContainerLayer()) {
|
||||
CULLING_LOG("Sublayer %p has no effective visible region\n", layerToRender->GetLayer());
|
||||
continue;
|
||||
}
|
||||
|
||||
RenderTargetIntRect clipRect = layerToRender->GetLayer()->
|
||||
CalculateScissorRect(aClipRect);
|
||||
if (clipRect.IsEmpty()) {
|
||||
CULLING_LOG("Sublayer %p has an empty world clip rect\n", layerToRender->GetLayer());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -195,7 +215,9 @@ ContainerPrepare(ContainerT* aContainer,
|
||||
|
||||
Compositor* compositor = aManager->GetCompositor();
|
||||
if (!layerToRender->GetLayer()->AsContainerLayer() &&
|
||||
!quad.Intersects(compositor->ClipRectInLayersCoordinates(layerToRender->GetLayer(), clipRect))) {
|
||||
!quad.Intersects(compositor->ClipRectInLayersCoordinates(layerToRender->GetLayer(), clipRect)) &&
|
||||
!LayerHasCheckerboardingAPZC(layerToRender->GetLayer(), nullptr)) {
|
||||
CULLING_LOG("Sublayer %p is clipped entirely\n", layerToRender->GetLayer());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -269,6 +291,24 @@ RenderLayers(ContainerT* aContainer,
|
||||
PreparedLayer& preparedData = aContainer->mPrepared->mLayers[i];
|
||||
LayerComposite* layerToRender = preparedData.mLayer;
|
||||
const RenderTargetIntRect& clipRect = preparedData.mClipRect;
|
||||
Layer* layer = layerToRender->GetLayer();
|
||||
|
||||
gfxRGBA color;
|
||||
if (LayerHasCheckerboardingAPZC(layer, &color)) {
|
||||
// Ideally we would want to intersect the checkerboard region from the APZ with the layer bounds
|
||||
// and only fill in that area. However the layer bounds takes into account the base translation
|
||||
// for the thebes layer whereas the checkerboard region does not. One does not simply
|
||||
// intersect areas in different coordinate spaces. So we do this a little more permissively
|
||||
// and only fill in the background when we know there is checkerboard, which in theory
|
||||
// should only occur transiently.
|
||||
nsIntRect layerBounds = layer->GetLayerBounds();
|
||||
EffectChain effectChain(layer);
|
||||
effectChain.mPrimaryEffect = new EffectSolidColor(ToColor(color));
|
||||
aManager->GetCompositor()->DrawQuad(gfx::Rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height),
|
||||
gfx::Rect(clipRect.ToUnknownRect()),
|
||||
effectChain, layer->GetEffectiveOpacity(),
|
||||
layer->GetEffectiveTransform());
|
||||
}
|
||||
|
||||
if (layerToRender->HasLayerBeenComposited()) {
|
||||
// Composer2D will compose this layer so skip GPU composition
|
||||
@ -290,7 +330,6 @@ RenderLayers(ContainerT* aContainer,
|
||||
layerToRender->SetShadowVisibleRegion(preparedData.mSavedVisibleRegion);
|
||||
}
|
||||
|
||||
Layer* layer = layerToRender->GetLayer();
|
||||
if (gfxPrefs::UniformityInfo()) {
|
||||
PrintUniformityInfo(layer);
|
||||
}
|
||||
|
@ -294,6 +294,7 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
const LayerAttributes& attrs = osla.attrs();
|
||||
|
||||
const CommonLayerAttributes& common = attrs.common();
|
||||
layer->SetLayerBounds(common.layerBounds());
|
||||
layer->SetVisibleRegion(common.visibleRegion());
|
||||
layer->SetEventRegions(common.eventRegions());
|
||||
layer->SetContentFlags(common.contentFlags());
|
||||
|
@ -190,6 +190,7 @@ struct Animation {
|
||||
|
||||
// Change a layer's attributes
|
||||
struct CommonLayerAttributes {
|
||||
nsIntRect layerBounds;
|
||||
nsIntRegion visibleRegion;
|
||||
EventRegions eventRegions;
|
||||
TransformMatrix transform;
|
||||
|
@ -574,6 +574,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||
|
||||
LayerAttributes attrs;
|
||||
CommonLayerAttributes& common = attrs.common();
|
||||
common.layerBounds() = mutant->GetLayerBounds();
|
||||
common.visibleRegion() = mutant->GetVisibleRegion();
|
||||
common.eventRegions() = mutant->GetEventRegions();
|
||||
common.postXScale() = mutant->GetPostXScale();
|
||||
|
@ -500,6 +500,10 @@ public:
|
||||
* in mItemClip).
|
||||
*/
|
||||
void UpdateCommonClipCount(const DisplayItemClip& aCurrentClip);
|
||||
/**
|
||||
* The union of all the bounds of the display items in this layer.
|
||||
*/
|
||||
nsIntRegion mBounds;
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -2165,6 +2169,10 @@ ContainerState::PopThebesLayerData()
|
||||
SetOuterVisibleRegionForLayer(layer, data->mVisibleRegion);
|
||||
}
|
||||
|
||||
nsIntRect layerBounds = data->mBounds.GetBounds();
|
||||
layerBounds.MoveBy(-GetTranslationForThebesLayer(data->mLayer));
|
||||
layer->SetLayerBounds(layerBounds);
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
layer->AddExtraDumpInfo(nsCString(data->mLog));
|
||||
#endif
|
||||
@ -2325,6 +2333,10 @@ ThebesLayerData::Accumulate(ContainerState* aState,
|
||||
{
|
||||
FLB_LOG_THEBES_DECISION(this, "Accumulating dp=%s(%p), f=%p against tld=%p\n", aItem->Name(), aItem, aItem->Frame(), this);
|
||||
|
||||
bool snap;
|
||||
nsRect itemBounds = aItem->GetBounds(aState->mBuilder, &snap);
|
||||
mBounds.OrWith(aState->ScaleToOutsidePixels(itemBounds, snap));
|
||||
|
||||
if (aState->mBuilder->NeedToForceTransparentSurfaceForItem(aItem)) {
|
||||
mForceTransparentSurface = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user