Skip to content
Permalink
Browse files
[Qt][EFL][WK2] Remove redundant device pixel ratio adjustment from Pa…
…geViewportController

https://bugs.webkit.org/show_bug.cgi?id=106355

Reviewed by Kenneth Rohde Christiansen.

Since r137597 Qt uses the device pixel ratio of the underlying
platform window as the device pixel ratio in WebCore.
The tiles are rendered with the effective scale (scale adjusted with
the device scale factor) and the projection matrix is also adjusted
with the device pixel ratio when painting.
As a result we can follow the same approach as QtQuick and all the
coordinates in PageViewportController need to be in device independent
pixels (UI pixels) thus we do no longer need to adjust with the device
pixel ratio when calculating the viewport attributes.
This simplifies the logic significantly and increases robustness,
but does not allow to set a custom device pixel ratio different from
the factor of the underlying platform (eg. for testing purposes).
This patch is conceptually a follow-up of r137597 and fixes layout
and canvas size on retina display.

* UIProcess/PageViewportController.cpp:
(WebKit::PageViewportController::PageViewportController):
(WebKit::PageViewportController::innerBoundedViewportScale):
(WebKit::PageViewportController::outerBoundedViewportScale):
(WebKit::PageViewportController::pixelAlignedFloatPoint):
(WebKit::PageViewportController::boundContentsPosition):
(WebKit::PageViewportController::didRenderFrame):
(WebKit::PageViewportController::pageTransitionViewportReady):
(WebKit::PageViewportController::didChangeContentsVisibility):
(WebKit::PageViewportController::syncVisibleContents):
(WebKit::PageViewportController::visibleContentsSize):
(WebKit::PageViewportController::applyScaleAfterRenderingContents):
(WebKit::PageViewportController::updateMinimumScaleToFit):
* UIProcess/PageViewportController.h:
(WebKit::PageViewportController::currentContentsScale):
(PageViewportController):
* UIProcess/efl/PageViewportControllerClientEfl.cpp:
(WebKit::PageViewportControllerClientEfl::updateViewportSize):
Adjust the viewport size with the device pixel ratio to keep previous
behaviour.
* UIProcess/qt/PageViewportControllerClientQt.cpp:
(WebKit::PageViewportControllerClientQt::focusEditableArea):
(WebKit::PageViewportControllerClientQt::zoomToAreaGestureEnded):
* UIProcess/qt/QtWebPageSGNode.cpp:
(WebKit::ContentsSGNode::clipRect):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::sendViewportAttributesChanged):

Canonical link: https://commits.webkit.org/124638@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@139189 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
bbandix committed Jan 9, 2013
1 parent 3554d9d commit eb24144a102366f9d27c5b15c224d1736b2cf8d3
Showing 7 changed files with 88 additions and 36 deletions.
@@ -1,3 +1,53 @@
2013-01-09 Andras Becsi <andras.becsi@digia.com>

[Qt][EFL][WK2] Remove redundant device pixel ratio adjustment from PageViewportController
https://bugs.webkit.org/show_bug.cgi?id=106355

Reviewed by Kenneth Rohde Christiansen.

Since r137597 Qt uses the device pixel ratio of the underlying
platform window as the device pixel ratio in WebCore.
The tiles are rendered with the effective scale (scale adjusted with
the device scale factor) and the projection matrix is also adjusted
with the device pixel ratio when painting.
As a result we can follow the same approach as QtQuick and all the
coordinates in PageViewportController need to be in device independent
pixels (UI pixels) thus we do no longer need to adjust with the device
pixel ratio when calculating the viewport attributes.
This simplifies the logic significantly and increases robustness,
but does not allow to set a custom device pixel ratio different from
the factor of the underlying platform (eg. for testing purposes).
This patch is conceptually a follow-up of r137597 and fixes layout
and canvas size on retina display.

* UIProcess/PageViewportController.cpp:
(WebKit::PageViewportController::PageViewportController):
(WebKit::PageViewportController::innerBoundedViewportScale):
(WebKit::PageViewportController::outerBoundedViewportScale):
(WebKit::PageViewportController::pixelAlignedFloatPoint):
(WebKit::PageViewportController::boundContentsPosition):
(WebKit::PageViewportController::didRenderFrame):
(WebKit::PageViewportController::pageTransitionViewportReady):
(WebKit::PageViewportController::didChangeContentsVisibility):
(WebKit::PageViewportController::syncVisibleContents):
(WebKit::PageViewportController::visibleContentsSize):
(WebKit::PageViewportController::applyScaleAfterRenderingContents):
(WebKit::PageViewportController::updateMinimumScaleToFit):
* UIProcess/PageViewportController.h:
(WebKit::PageViewportController::currentContentsScale):
(PageViewportController):
* UIProcess/efl/PageViewportControllerClientEfl.cpp:
(WebKit::PageViewportControllerClientEfl::updateViewportSize):
Adjust the viewport size with the device pixel ratio to keep previous
behaviour.
* UIProcess/qt/PageViewportControllerClientQt.cpp:
(WebKit::PageViewportControllerClientQt::focusEditableArea):
(WebKit::PageViewportControllerClientQt::zoomToAreaGestureEnded):
* UIProcess/qt/QtWebPageSGNode.cpp:
(WebKit::ContentsSGNode::clipRect):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::sendViewportAttributesChanged):

2013-01-09 Carlos Garcia Campos <cgarcia@igalia.com>

Unreviewed. Fix make distcheck.
@@ -47,7 +47,7 @@ PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, Page
, m_initiallyFitToViewport(true)
, m_hasSuspendedContent(false)
, m_hadUserInteraction(false)
, m_effectiveScale(1)
, m_contentsScale(1)
, m_pendingPositionChange(false)
, m_pendingScaleChange(false)
{
@@ -68,15 +68,15 @@ PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, Page

float PageViewportController::innerBoundedViewportScale(float viewportScale) const
{
return clampTo(viewportScale, toViewportScale(m_minimumScaleToFit), toViewportScale(m_rawAttributes.maximumScale));
return clampTo(viewportScale, m_minimumScaleToFit, m_rawAttributes.maximumScale);
}

float PageViewportController::outerBoundedViewportScale(float viewportScale) const
{
if (m_allowsUserScaling) {
// Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
float hardMin = toViewportScale(std::max<float>(0.1, 0.5 * m_minimumScaleToFit));
float hardMax = toViewportScale(std::min<float>(10, 2 * m_rawAttributes.maximumScale));
float hardMin = std::max<float>(0.1, 0.5 * m_minimumScaleToFit);
float hardMax = std::min<float>(10, 2 * m_rawAttributes.maximumScale);
return clampTo(viewportScale, hardMin, hardMax);
}
return innerBoundedViewportScale(viewportScale);
@@ -95,18 +95,18 @@ static inline bool isIntegral(float value)
FloatPoint PageViewportController::pixelAlignedFloatPoint(const FloatPoint& framePosition)
{
#if PLATFORM(EFL)
if (!isIntegral(m_effectiveScale)) {
if (!isIntegral(m_contentsScale)) {
// To avoid blurryness, modify the position so that it maps into a discrete device position.
FloatPoint scaledPos(framePosition);

// Scale by the effective scale factor to compute the screen-relative position.
scaledPos.scale(m_effectiveScale, m_effectiveScale);
scaledPos.scale(m_contentsScale, m_contentsScale);

// Round to integer boundaries.
FloatPoint alignedPos = roundedIntPoint(scaledPos);

// Convert back to CSS coordinates.
alignedPos.scale(1 / m_effectiveScale, 1 / m_effectiveScale);
alignedPos.scale(1 / m_contentsScale, 1 / m_contentsScale);

return alignedPos;
}
@@ -133,7 +133,7 @@ FloatPoint PageViewportController::boundContentsPositionAtScale(const WebCore::F

FloatPoint PageViewportController::boundContentsPosition(const WebCore::FloatPoint& framePosition)
{
return boundContentsPositionAtScale(framePosition, m_effectiveScale);
return boundContentsPositionAtScale(framePosition, m_contentsScale);
}

void PageViewportController::didCommitLoad()
@@ -189,7 +189,7 @@ void PageViewportController::didRenderFrame(const IntSize& contentsSize, const I

if (m_pendingScaleChange) {
m_pendingScaleChange = false;
m_client->setContentsScale(m_effectiveScale);
m_client->setContentsScale(m_contentsScale);

// The scale changed, we have to re-pixel align.
m_pendingPositionChange = true;
@@ -211,7 +211,7 @@ void PageViewportController::pageTransitionViewportReady()
if (!m_rawAttributes.layoutSize.isEmpty()) {
m_hadUserInteraction = false;
float initialScale = m_initiallyFitToViewport ? m_minimumScaleToFit : m_rawAttributes.initialScale;
applyScaleAfterRenderingContents(innerBoundedViewportScale(toViewportScale(initialScale)));
applyScaleAfterRenderingContents(innerBoundedViewportScale(initialScale));
}

// At this point we should already have received the first viewport arguments and the requested scroll
@@ -256,7 +256,7 @@ void PageViewportController::didChangeContentsVisibility(const FloatPoint& posit
if (!m_pendingPositionChange)
m_contentsPosition = position;
if (!m_pendingScaleChange)
m_effectiveScale = scale;
m_contentsScale = scale;

syncVisibleContents(trajectoryVector);
}
@@ -269,7 +269,7 @@ void PageViewportController::syncVisibleContents(const FloatPoint& trajectoryVec

FloatRect visibleContentsRect(boundContentsPosition(m_contentsPosition), visibleContentsSize());
visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize));
drawingArea->setVisibleContentsRect(visibleContentsRect, m_effectiveScale, trajectoryVector);
drawingArea->setVisibleContentsRect(visibleContentsRect, m_contentsScale, trajectoryVector);

m_client->didChangeVisibleContents();
}
@@ -299,7 +299,7 @@ void PageViewportController::didChangeViewportAttributes(const WebCore::Viewport

FloatSize PageViewportController::visibleContentsSize() const
{
return FloatSize(m_viewportSize.width() / m_effectiveScale, m_viewportSize.height() / m_effectiveScale);
return FloatSize(m_viewportSize.width() / m_contentsScale, m_viewportSize.height() / m_contentsScale);
}

void PageViewportController::suspendContent()
@@ -324,7 +324,7 @@ void PageViewportController::resumeContent()

void PageViewportController::applyScaleAfterRenderingContents(float scale)
{
m_effectiveScale = scale;
m_contentsScale = scale;
m_pendingScaleChange = true;
syncVisibleContents();
}
@@ -341,9 +341,9 @@ bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate)
if (m_viewportSize.isEmpty() || m_contentsSize.isEmpty())
return false;

bool currentlyScaledToFit = fuzzyCompare(m_effectiveScale, toViewportScale(m_minimumScaleToFit), 0.0001);
bool currentlyScaledToFit = fuzzyCompare(m_contentsScale, m_minimumScaleToFit, 0.0001);

float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize), devicePixelRatio());
float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize), 1);

if (minimumScale <= 0)
return false;
@@ -353,11 +353,11 @@ bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate)

if (!hasSuspendedContent()) {
if (!m_hadUserInteraction || (userInitiatedUpdate && currentlyScaledToFit))
applyScaleAfterRenderingContents(toViewportScale(m_minimumScaleToFit));
applyScaleAfterRenderingContents(m_minimumScaleToFit);
else {
// Ensure the effective scale stays within bounds.
float boundedScale = innerBoundedViewportScale(m_effectiveScale);
if (!fuzzyCompare(boundedScale, m_effectiveScale, 0.0001))
float boundedScale = innerBoundedViewportScale(m_contentsScale);
if (!fuzzyCompare(boundedScale, m_contentsScale, 0.0001))
applyScaleAfterRenderingContents(boundedScale);
}
}
@@ -68,7 +68,7 @@ class PageViewportController {
float devicePixelRatio() const;
float minimumContentsScale() const { return m_minimumScaleToFit; }
float maximumContentsScale() const { return m_rawAttributes.maximumScale; }
float currentContentsScale() const { return fromViewportScale(m_effectiveScale); }
float currentContentsScale() const { return m_contentsScale; }

void setHadUserInteraction(bool didUserInteract) { m_hadUserInteraction = didUserInteract; }

@@ -85,8 +85,6 @@ class PageViewportController {
void pageDidRequestScroll(const WebCore::IntPoint& cssPosition);

private:
float fromViewportScale(float scale) const { return scale / devicePixelRatio(); }
float toViewportScale(float scale) const { return scale * devicePixelRatio(); }
void syncVisibleContents(const WebCore::FloatPoint &trajectoryVector = WebCore::FloatPoint::zero());
void applyScaleAfterRenderingContents(float scale);
void applyPositionAfterRenderingContents(const WebCore::FloatPoint& pos);
@@ -108,7 +106,7 @@ class PageViewportController {
WebCore::FloatSize m_contentsSize;
WebCore::FloatSize m_viewportSize;
WebCore::IntSize m_clientContentsSize;
float m_effectiveScale; // Should always be cssScale * devicePixelRatio.
float m_contentsScale;

bool m_pendingPositionChange;
bool m_pendingScaleChange;
@@ -62,7 +62,10 @@ void PageViewportControllerClientEfl::setRendererActive(bool active)
void PageViewportControllerClientEfl::updateViewportSize()
{
ASSERT(m_controller);
m_controller->didChangeViewportSize(m_viewImpl->size());
FloatSize size = m_viewImpl->size();
// The viewport controller expects sizes in UI units, and not raw device units.
size.scale(1 / m_controller->devicePixelRatio());
m_controller->didChangeViewportSize(size);
}

void PageViewportControllerClientEfl::didChangeContentsSize(const WebCore::IntSize& contentsSize)
@@ -182,12 +182,12 @@ void PageViewportControllerClientQt::focusEditableArea(const QRectF& caretArea,
// This can only happen as a result of a user interaction.
ASSERT(m_controller->hadUserInteraction());

const float editingFixedScale = 2 * m_controller->devicePixelRatio();
const float editingFixedScale = 2;
float targetScale = m_controller->innerBoundedViewportScale(editingFixedScale);
const QRectF viewportRect = m_viewportItem->boundingRect();

qreal x;
const qreal borderOffset = 10 * m_controller->devicePixelRatio();
const qreal borderOffset = 10;
if ((targetArea.width() + borderOffset) * targetScale <= viewportRect.width()) {
// Center the input field in the middle of the view, if it is smaller than
// the view at the scale target.
@@ -221,14 +221,14 @@ void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touch
if (m_controller->hasSuspendedContent())
return;

const float margin = 10 * m_controller->devicePixelRatio(); // We want at least a little bit of margin.
const float margin = 10; // We want at least a little bit of margin.
QRectF endArea = targetArea.adjusted(-margin, -margin, margin, margin);

const QRectF viewportRect = m_viewportItem->boundingRect();

qreal minViewportScale = qreal(2.5) * m_controller->devicePixelRatio();
const qreal minViewportScale = qreal(2.5);
qreal targetScale = viewportRect.size().width() / endArea.size().width();
targetScale = m_controller->innerBoundedViewportScale(qMin(minViewportScale, targetScale));
targetScale = m_controller->innerBoundedViewportScale(qMax(minViewportScale, targetScale));
qreal currentScale = m_pageItem->contentsScale();

// We want to end up with the target area filling the whole width of the viewport (if possible),
@@ -268,7 +268,7 @@ void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touch
break;
case ZoomBack: {
if (m_scaleStack.isEmpty()) {
targetScale = m_controller->minimumContentsScale() * m_controller->devicePixelRatio();
targetScale = m_controller->minimumContentsScale();
endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale);
endPosition.setX(0);
m_zoomOutScale = 0;
@@ -87,9 +87,12 @@ class ContentsSGNode : public QSGRenderNode {

for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) {
QMatrix4x4 clipMatrix;
if (clip->matrix())
if (pageNode()->devicePixelRatio() != 1.0) {
clipMatrix.scale(pageNode()->devicePixelRatio());
if (clip->matrix())
clipMatrix *= (*clip->matrix());
} else if (clip->matrix())
clipMatrix = *clip->matrix();
clipMatrix.scale(pageNode()->devicePixelRatio());

QRectF currentClip;

@@ -1031,13 +1031,13 @@ void WebPage::sendViewportAttributesChanged()
// Recalculate the recommended layout size, when the available size (device pixel) changes.
Settings* settings = m_page->settings();

int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), int(m_viewportSize.width() / m_page->deviceScaleFactor()));
int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), m_viewportSize.width());

// If unset we use the viewport dimensions. This fits with the behavior of desktop browsers.
int deviceWidth = (settings->deviceWidth() > 0) ? settings->deviceWidth() : m_viewportSize.width();
int deviceHeight = (settings->deviceHeight() > 0) ? settings->deviceHeight() : m_viewportSize.height();

ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, m_page->deviceScaleFactor(), m_viewportSize);
ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewportSize);

FrameView* view = m_page->mainFrame()->view();

@@ -1048,8 +1048,6 @@ void WebPage::sendViewportAttributesChanged()
// Use FloatSize to avoid truncated values during scale.
FloatSize contentFixedSize = m_viewportSize;

contentFixedSize.scale(1 / m_page->deviceScaleFactor());

#if ENABLE(CSS_DEVICE_ADAPTATION)
// CSS viewport descriptors might be applied to already affected viewport size
// if the page enables/disables stylesheets, so need to keep initial viewport size.

0 comments on commit eb24144

Please sign in to comment.