Bug 772679. RestrictToLayerPixels needs to accurately convert between appunits scroll offsets and ThebesLayer pixel coordinates. r=tnikkel
Change GetThebesLayerResolutionForFrame to GetThebesLayerScaleForFrame, which just returns a scale. Ensure that the scale is as accurate as possible even if dedicated layers for scrolled content (or any layers at all) have not been created yet, by taking into account transforms that have not yet generated layers. This makes the decisions made by nsGfxScrollFrameInner::ScrollToImpl independent of whether there is currently an active layer for the scrolled content (or much more nearly so). In nsGfxScrollFrameInner::ScrollToImpl, do not use the current internal fractional offset of the ThebesLayer, which is in a mostly unrelated coordinate space to our scroll positions. Instead, just try to make sure that the previous and next scroll position differ by a whole number of layer pixels.
This commit is contained in:
@@ -2505,44 +2505,50 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
FrameLayerBuilder::GetThebesLayerResolutionForFrame(nsIFrame* aFrame,
|
||||
double* aXres, double* aYres,
|
||||
gfxPoint* aPoint)
|
||||
static gfxSize
|
||||
PredictScaleForContent(nsIFrame* aFrame, nsIFrame* aAncestorWithScale,
|
||||
const gfxSize& aScale)
|
||||
{
|
||||
nsTArray<DisplayItemData> *array = GetDisplayItemDataArrayForFrame(aFrame);
|
||||
if (array) {
|
||||
for (PRUint32 i = 0; i < array->Length(); ++i) {
|
||||
Layer* layer = array->ElementAt(i).mLayer;
|
||||
if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
|
||||
ThebesDisplayItemLayerUserData* data =
|
||||
static_cast<ThebesDisplayItemLayerUserData*>
|
||||
(layer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
*aXres = data->mXScale;
|
||||
*aYres = data->mYScale;
|
||||
*aPoint = data->mActiveScrolledRootPosition;
|
||||
return true;
|
||||
gfx3DMatrix transform =
|
||||
gfx3DMatrix::ScalingMatrix(aScale.width, aScale.height, 1.0);
|
||||
// aTransform is applied first, then the scale is applied to the result
|
||||
transform = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestorWithScale)*transform;
|
||||
gfxMatrix transform2d;
|
||||
if (transform.CanDraw2D(&transform2d)) {
|
||||
return transform2d.ScaleFactors(true);
|
||||
}
|
||||
return gfxSize(1.0, 1.0);
|
||||
}
|
||||
|
||||
gfxSize
|
||||
FrameLayerBuilder::GetThebesLayerScaleForFrame(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* last;
|
||||
for (nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
||||
last = f;
|
||||
if (f->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER) {
|
||||
nsTArray<DisplayItemData>* array = GetDisplayItemDataArrayForFrame(f);
|
||||
NS_ASSERTION(array, "Must have display item data for container");
|
||||
for (PRUint32 i = 0; i < array->Length(); ++i) {
|
||||
Layer* layer = array->ElementAt(i).mLayer;
|
||||
ContainerLayer* container = layer->AsContainerLayer();
|
||||
if (!container) {
|
||||
continue;
|
||||
}
|
||||
for (Layer* l = container->GetFirstChild(); l; l = l->GetNextSibling()) {
|
||||
ThebesDisplayItemLayerUserData* data =
|
||||
static_cast<ThebesDisplayItemLayerUserData*>
|
||||
(l->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
if (data) {
|
||||
return PredictScaleForContent(aFrame, f, gfxSize(data->mXScale, data->mYScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame::ChildListIterator lists(aFrame);
|
||||
for (; !lists.IsDone(); lists.Next()) {
|
||||
if (lists.CurrentID() == nsIFrame::kPopupList ||
|
||||
lists.CurrentID() == nsIFrame::kSelectPopupList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||
if (GetThebesLayerResolutionForFrame(childFrames.get(),
|
||||
aXres, aYres, aPoint)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return PredictScaleForContent(aFrame, last,
|
||||
last->PresContext()->PresShell()->GetResolution());
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
|
||||
Reference in New Issue
Block a user