gfx/layers/apz/util/APZCCallbackHelper.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "APZCCallbackHelper.h"
michael@0 7 #include "gfxPrefs.h" // For gfxPrefs::LayersTilesEnabled, LayersTileWidth/Height
michael@0 8 #include "mozilla/Preferences.h"
michael@0 9 #include "nsIScrollableFrame.h"
michael@0 10 #include "nsLayoutUtils.h"
michael@0 11 #include "nsIDOMElement.h"
michael@0 12 #include "nsIInterfaceRequestorUtils.h"
michael@0 13
michael@0 14 namespace mozilla {
michael@0 15 namespace layers {
michael@0 16
michael@0 17 bool
michael@0 18 APZCCallbackHelper::HasValidPresShellId(nsIDOMWindowUtils* aUtils,
michael@0 19 const FrameMetrics& aMetrics)
michael@0 20 {
michael@0 21 MOZ_ASSERT(aUtils);
michael@0 22
michael@0 23 uint32_t presShellId;
michael@0 24 nsresult rv = aUtils->GetPresShellId(&presShellId);
michael@0 25 MOZ_ASSERT(NS_SUCCEEDED(rv));
michael@0 26 return NS_SUCCEEDED(rv) && aMetrics.mPresShellId == presShellId;
michael@0 27 }
michael@0 28
michael@0 29 /**
michael@0 30 * Expands a given rectangle to the next tile boundary. Note, this will
michael@0 31 * expand the rectangle if it is already on tile boundaries.
michael@0 32 */
michael@0 33 static CSSRect ExpandDisplayPortToTileBoundaries(
michael@0 34 const CSSRect& aDisplayPort,
michael@0 35 const CSSToLayerScale& aLayerPixelsPerCSSPixel)
michael@0 36 {
michael@0 37 // Convert the given rect to layer coordinates so we can inflate to tile
michael@0 38 // boundaries (layer space corresponds to texture pixel space here).
michael@0 39 LayerRect displayPortInLayerSpace = aDisplayPort * aLayerPixelsPerCSSPixel;
michael@0 40
michael@0 41 // Inflate the rectangle by 1 so that we always push to the next tile
michael@0 42 // boundary. This is desirable to stop from having a rectangle with a
michael@0 43 // moving origin occasionally being smaller when it coincidentally lines
michael@0 44 // up to tile boundaries.
michael@0 45 displayPortInLayerSpace.Inflate(1);
michael@0 46
michael@0 47 // Now nudge the rectangle to the nearest equal or larger tile boundary.
michael@0 48 int32_t tileWidth = gfxPrefs::LayersTileWidth();
michael@0 49 int32_t tileHeight = gfxPrefs::LayersTileHeight();
michael@0 50 gfxFloat left = tileWidth * floor(displayPortInLayerSpace.x / tileWidth);
michael@0 51 gfxFloat right = tileWidth * ceil(displayPortInLayerSpace.XMost() / tileWidth);
michael@0 52 gfxFloat top = tileHeight * floor(displayPortInLayerSpace.y / tileHeight);
michael@0 53 gfxFloat bottom = tileHeight * ceil(displayPortInLayerSpace.YMost() / tileHeight);
michael@0 54
michael@0 55 displayPortInLayerSpace = LayerRect(left, top, right - left, bottom - top);
michael@0 56 CSSRect displayPort = displayPortInLayerSpace / aLayerPixelsPerCSSPixel;
michael@0 57
michael@0 58 return displayPort;
michael@0 59 }
michael@0 60
michael@0 61 static void
michael@0 62 MaybeAlignAndClampDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics,
michael@0 63 const CSSPoint& aActualScrollOffset)
michael@0 64 {
michael@0 65 // Correct the display-port by the difference between the requested scroll
michael@0 66 // offset and the resulting scroll offset after setting the requested value.
michael@0 67 if (!aFrameMetrics.GetUseDisplayPortMargins()) {
michael@0 68 CSSRect& displayPort = aFrameMetrics.mDisplayPort;
michael@0 69 displayPort += aFrameMetrics.GetScrollOffset() - aActualScrollOffset;
michael@0 70
michael@0 71 // Expand the display port to the next tile boundaries, if tiled thebes layers
michael@0 72 // are enabled.
michael@0 73 if (gfxPrefs::LayersTilesEnabled()) {
michael@0 74 // We don't use LayersPixelsPerCSSPixel() here as mCumulativeResolution on
michael@0 75 // this FrameMetrics may be incorrect (and is about to be reset by mZoom).
michael@0 76 displayPort =
michael@0 77 ExpandDisplayPortToTileBoundaries(displayPort + aActualScrollOffset,
michael@0 78 aFrameMetrics.GetZoom() *
michael@0 79 ScreenToLayerScale(1.0))
michael@0 80 - aActualScrollOffset;
michael@0 81 }
michael@0 82
michael@0 83 // Finally, clamp the display port to the expanded scrollable rect.
michael@0 84 CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
michael@0 85 displayPort = scrollableRect.Intersect(displayPort + aActualScrollOffset)
michael@0 86 - aActualScrollOffset;
michael@0 87 } else {
michael@0 88 LayerPoint shift =
michael@0 89 (aFrameMetrics.GetScrollOffset() - aActualScrollOffset) *
michael@0 90 aFrameMetrics.LayersPixelsPerCSSPixel();
michael@0 91 LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
michael@0 92 margins.left -= shift.x;
michael@0 93 margins.right += shift.x;
michael@0 94 margins.top -= shift.y;
michael@0 95 margins.bottom += shift.y;
michael@0 96 aFrameMetrics.SetDisplayPortMargins(margins);
michael@0 97 }
michael@0 98 }
michael@0 99
michael@0 100 static void
michael@0 101 RecenterDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics)
michael@0 102 {
michael@0 103 if (!aFrameMetrics.GetUseDisplayPortMargins()) {
michael@0 104 CSSSize compositionSize = aFrameMetrics.CalculateCompositedSizeInCssPixels();
michael@0 105 aFrameMetrics.mDisplayPort.x = (compositionSize.width - aFrameMetrics.mDisplayPort.width) / 2;
michael@0 106 aFrameMetrics.mDisplayPort.y = (compositionSize.height - aFrameMetrics.mDisplayPort.height) / 2;
michael@0 107 } else {
michael@0 108 LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
michael@0 109 margins.right = margins.left = margins.LeftRight() / 2;
michael@0 110 margins.top = margins.bottom = margins.TopBottom() / 2;
michael@0 111 aFrameMetrics.SetDisplayPortMargins(margins);
michael@0 112 }
michael@0 113 }
michael@0 114
michael@0 115 static CSSPoint
michael@0 116 ScrollFrameTo(nsIScrollableFrame* aFrame, const CSSPoint& aPoint, bool& aSuccessOut)
michael@0 117 {
michael@0 118 aSuccessOut = false;
michael@0 119
michael@0 120 if (!aFrame) {
michael@0 121 return aPoint;
michael@0 122 }
michael@0 123
michael@0 124 CSSPoint targetScrollPosition = aPoint;
michael@0 125
michael@0 126 // If the frame is overflow:hidden on a particular axis, we don't want to allow
michael@0 127 // user-driven scroll on that axis. Simply set the scroll position on that axis
michael@0 128 // to whatever it already is. Note that this will leave the APZ's async scroll
michael@0 129 // position out of sync with the gecko scroll position, but APZ can deal with that
michael@0 130 // (by design). Note also that when we run into this case, even if both axes
michael@0 131 // have overflow:hidden, we want to set aSuccessOut to true, so that the displayport
michael@0 132 // follows the async scroll position rather than the gecko scroll position.
michael@0 133 CSSPoint geckoScrollPosition = CSSPoint::FromAppUnits(aFrame->GetScrollPosition());
michael@0 134 if (aFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
michael@0 135 targetScrollPosition.y = geckoScrollPosition.y;
michael@0 136 }
michael@0 137 if (aFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
michael@0 138 targetScrollPosition.x = geckoScrollPosition.x;
michael@0 139 }
michael@0 140
michael@0 141 // If the scrollable frame is currently in the middle of an async or smooth
michael@0 142 // scroll then we don't want to interrupt it (see bug 961280).
michael@0 143 // Also if the scrollable frame got a scroll request from something other than us
michael@0 144 // since the last layers update, then we don't want to push our scroll request
michael@0 145 // because we'll clobber that one, which is bad.
michael@0 146 if (!aFrame->IsProcessingAsyncScroll() &&
michael@0 147 (!aFrame->OriginOfLastScroll() || aFrame->OriginOfLastScroll() == nsGkAtoms::apz)) {
michael@0 148 aFrame->ScrollToCSSPixelsApproximate(targetScrollPosition, nsGkAtoms::apz);
michael@0 149 geckoScrollPosition = CSSPoint::FromAppUnits(aFrame->GetScrollPosition());
michael@0 150 aSuccessOut = true;
michael@0 151 }
michael@0 152 // Return the final scroll position after setting it so that anything that relies
michael@0 153 // on it can have an accurate value. Note that even if we set it above re-querying it
michael@0 154 // is a good idea because it may have gotten clamped or rounded.
michael@0 155 return geckoScrollPosition;
michael@0 156 }
michael@0 157
michael@0 158 void
michael@0 159 APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
michael@0 160 FrameMetrics& aMetrics)
michael@0 161 {
michael@0 162 // Precondition checks
michael@0 163 MOZ_ASSERT(aUtils);
michael@0 164 if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
michael@0 165 return;
michael@0 166 }
michael@0 167
michael@0 168 // Set the scroll port size, which determines the scroll range. For example if
michael@0 169 // a 500-pixel document is shown in a 100-pixel frame, the scroll port length would
michael@0 170 // be 100, and gecko would limit the maximum scroll offset to 400 (so as to prevent
michael@0 171 // overscroll). Note that if the content here was zoomed to 2x, the document would
michael@0 172 // be 1000 pixels long but the frame would still be 100 pixels, and so the maximum
michael@0 173 // scroll range would be 900. Therefore this calculation depends on the zoom applied
michael@0 174 // to the content relative to the container.
michael@0 175 CSSSize scrollPort = aMetrics.CalculateCompositedSizeInCssPixels();
michael@0 176 aUtils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
michael@0 177
michael@0 178 // Scroll the window to the desired spot
michael@0 179 nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId());
michael@0 180 bool scrollUpdated = false;
michael@0 181 CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated);
michael@0 182
michael@0 183 if (!scrollUpdated) {
michael@0 184 // For whatever reason we couldn't update the scroll offset on the scroll frame,
michael@0 185 // which means the data APZ used for its displayport calculation is stale. Fall
michael@0 186 // back to a sane default behaviour. Note that we don't tile-align the recentered
michael@0 187 // displayport because tile-alignment depends on the scroll position, and the
michael@0 188 // scroll position here is out of our control. See bug 966507 comment 21 for a
michael@0 189 // more detailed explanation.
michael@0 190 RecenterDisplayPort(aMetrics);
michael@0 191 }
michael@0 192
michael@0 193 // Correct the display port due to the difference between mScrollOffset and the
michael@0 194 // actual scroll offset, possibly align it to tile boundaries (if tiled layers are
michael@0 195 // enabled), and clamp it to the scrollable rect.
michael@0 196 MaybeAlignAndClampDisplayPort(aMetrics, actualScrollOffset);
michael@0 197
michael@0 198 aMetrics.SetScrollOffset(actualScrollOffset);
michael@0 199
michael@0 200 // The mZoom variable on the frame metrics stores the CSS-to-screen scale for this
michael@0 201 // frame. This scale includes all of the (cumulative) resolutions set on the presShells
michael@0 202 // from the root down to this frame. However, when setting the resolution, we only
michael@0 203 // want the piece of the resolution that corresponds to this presShell, rather than
michael@0 204 // all of the cumulative stuff, so we need to divide out the parent resolutions.
michael@0 205 // Finally, we multiply by a ScreenToLayerScale of 1.0f because the goal here is to
michael@0 206 // take the async zoom calculated by the APZC and tell gecko about it (turning it into
michael@0 207 // a "sync" zoom) which will update the resolution at which the layer is painted.
michael@0 208 ParentLayerToLayerScale presShellResolution =
michael@0 209 aMetrics.GetZoom()
michael@0 210 / aMetrics.mDevPixelsPerCSSPixel
michael@0 211 / aMetrics.GetParentResolution()
michael@0 212 * ScreenToLayerScale(1.0f);
michael@0 213 aUtils->SetResolution(presShellResolution.scale, presShellResolution.scale);
michael@0 214
michael@0 215 // Finally, we set the displayport.
michael@0 216 nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());
michael@0 217 if (!content) {
michael@0 218 return;
michael@0 219 }
michael@0 220 nsCOMPtr<nsIDOMElement> element = do_QueryInterface(content);
michael@0 221 if (!element) {
michael@0 222 return;
michael@0 223 }
michael@0 224 if (!aMetrics.GetUseDisplayPortMargins()) {
michael@0 225 aUtils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
michael@0 226 aMetrics.mDisplayPort.y,
michael@0 227 aMetrics.mDisplayPort.width,
michael@0 228 aMetrics.mDisplayPort.height,
michael@0 229 element, 0);
michael@0 230 } else {
michael@0 231 gfx::IntSize alignment = gfxPrefs::LayersTilesEnabled()
michael@0 232 ? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :
michael@0 233 gfx::IntSize(0, 0);
michael@0 234 LayerMargin margins = aMetrics.GetDisplayPortMargins();
michael@0 235 aUtils->SetDisplayPortMarginsForElement(margins.left,
michael@0 236 margins.top,
michael@0 237 margins.right,
michael@0 238 margins.bottom,
michael@0 239 alignment.width,
michael@0 240 alignment.height,
michael@0 241 element, 0);
michael@0 242 CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
michael@0 243 nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
michael@0 244 baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(),
michael@0 245 baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
michael@0 246 baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
michael@0 247 nsLayoutUtils::SetDisplayPortBaseIfNotSet(content, base);
michael@0 248 }
michael@0 249 }
michael@0 250
michael@0 251 void
michael@0 252 APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
michael@0 253 FrameMetrics& aMetrics)
michael@0 254 {
michael@0 255 // Precondition checks
michael@0 256 MOZ_ASSERT(aContent);
michael@0 257 if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) {
michael@0 258 return;
michael@0 259 }
michael@0 260
michael@0 261 nsCOMPtr<nsIDOMWindowUtils> utils = GetDOMWindowUtils(aContent);
michael@0 262 if (!utils) {
michael@0 263 return;
michael@0 264 }
michael@0 265
michael@0 266 // We currently do not support zooming arbitrary subframes. They can only
michael@0 267 // be scrolled, so here we only have to set the scroll position and displayport.
michael@0 268
michael@0 269 nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId());
michael@0 270 bool scrollUpdated = false;
michael@0 271 CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated);
michael@0 272
michael@0 273 nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
michael@0 274 if (element) {
michael@0 275 if (!scrollUpdated) {
michael@0 276 RecenterDisplayPort(aMetrics);
michael@0 277 }
michael@0 278 MaybeAlignAndClampDisplayPort(aMetrics, actualScrollOffset);
michael@0 279 if (!aMetrics.GetUseDisplayPortMargins()) {
michael@0 280 utils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
michael@0 281 aMetrics.mDisplayPort.y,
michael@0 282 aMetrics.mDisplayPort.width,
michael@0 283 aMetrics.mDisplayPort.height,
michael@0 284 element, 0);
michael@0 285 } else {
michael@0 286 gfx::IntSize alignment = gfxPrefs::LayersTilesEnabled()
michael@0 287 ? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :
michael@0 288 gfx::IntSize(0, 0);
michael@0 289 LayerMargin margins = aMetrics.GetDisplayPortMargins();
michael@0 290 utils->SetDisplayPortMarginsForElement(margins.left,
michael@0 291 margins.top,
michael@0 292 margins.right,
michael@0 293 margins.bottom,
michael@0 294 alignment.width,
michael@0 295 alignment.height,
michael@0 296 element, 0);
michael@0 297 CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
michael@0 298 nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
michael@0 299 baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(),
michael@0 300 baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
michael@0 301 baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
michael@0 302 nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base);
michael@0 303 }
michael@0 304 }
michael@0 305
michael@0 306 aMetrics.SetScrollOffset(actualScrollOffset);
michael@0 307 }
michael@0 308
michael@0 309 already_AddRefed<nsIDOMWindowUtils>
michael@0 310 APZCCallbackHelper::GetDOMWindowUtils(const nsIDocument* aDoc)
michael@0 311 {
michael@0 312 nsCOMPtr<nsIDOMWindowUtils> utils;
michael@0 313 nsCOMPtr<nsIDOMWindow> window = aDoc->GetDefaultView();
michael@0 314 if (window) {
michael@0 315 utils = do_GetInterface(window);
michael@0 316 }
michael@0 317 return utils.forget();
michael@0 318 }
michael@0 319
michael@0 320 already_AddRefed<nsIDOMWindowUtils>
michael@0 321 APZCCallbackHelper::GetDOMWindowUtils(const nsIContent* aContent)
michael@0 322 {
michael@0 323 nsCOMPtr<nsIDOMWindowUtils> utils;
michael@0 324 nsIDocument* doc = aContent->GetCurrentDoc();
michael@0 325 if (doc) {
michael@0 326 utils = GetDOMWindowUtils(doc);
michael@0 327 }
michael@0 328 return utils.forget();
michael@0 329 }
michael@0 330
michael@0 331 bool
michael@0 332 APZCCallbackHelper::GetScrollIdentifiers(const nsIContent* aContent,
michael@0 333 uint32_t* aPresShellIdOut,
michael@0 334 FrameMetrics::ViewID* aViewIdOut)
michael@0 335 {
michael@0 336 if (!aContent || !nsLayoutUtils::FindIDFor(aContent, aViewIdOut)) {
michael@0 337 return false;
michael@0 338 }
michael@0 339 nsCOMPtr<nsIDOMWindowUtils> utils = GetDOMWindowUtils(aContent);
michael@0 340 return utils && (utils->GetPresShellId(aPresShellIdOut) == NS_OK);
michael@0 341 }
michael@0 342
michael@0 343 class AcknowledgeScrollUpdateEvent : public nsRunnable
michael@0 344 {
michael@0 345 typedef mozilla::layers::FrameMetrics::ViewID ViewID;
michael@0 346
michael@0 347 public:
michael@0 348 AcknowledgeScrollUpdateEvent(const ViewID& aScrollId, const uint32_t& aScrollGeneration)
michael@0 349 : mScrollId(aScrollId)
michael@0 350 , mScrollGeneration(aScrollGeneration)
michael@0 351 {
michael@0 352 }
michael@0 353
michael@0 354 NS_IMETHOD Run() {
michael@0 355 MOZ_ASSERT(NS_IsMainThread());
michael@0 356
michael@0 357 nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(mScrollId);
michael@0 358 if (sf) {
michael@0 359 sf->ResetOriginIfScrollAtGeneration(mScrollGeneration);
michael@0 360 }
michael@0 361
michael@0 362 return NS_OK;
michael@0 363 }
michael@0 364
michael@0 365 protected:
michael@0 366 ViewID mScrollId;
michael@0 367 uint32_t mScrollGeneration;
michael@0 368 };
michael@0 369
michael@0 370 void
michael@0 371 APZCCallbackHelper::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
michael@0 372 const uint32_t& aScrollGeneration)
michael@0 373 {
michael@0 374 nsCOMPtr<nsIRunnable> r1 = new AcknowledgeScrollUpdateEvent(aScrollId, aScrollGeneration);
michael@0 375 if (!NS_IsMainThread()) {
michael@0 376 NS_DispatchToMainThread(r1);
michael@0 377 } else {
michael@0 378 r1->Run();
michael@0 379 }
michael@0 380 }
michael@0 381
michael@0 382 void
michael@0 383 APZCCallbackHelper::UpdateCallbackTransform(const FrameMetrics& aApzcMetrics, const FrameMetrics& aActualMetrics)
michael@0 384 {
michael@0 385 nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aApzcMetrics.GetScrollId());
michael@0 386 if (!content) {
michael@0 387 return;
michael@0 388 }
michael@0 389 CSSPoint scrollDelta = aApzcMetrics.GetScrollOffset() - aActualMetrics.GetScrollOffset();
michael@0 390 content->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(scrollDelta),
michael@0 391 nsINode::DeleteProperty<CSSPoint>);
michael@0 392 }
michael@0 393
michael@0 394 CSSPoint
michael@0 395 APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput, const ScrollableLayerGuid& aGuid)
michael@0 396 {
michael@0 397 // XXX: technically we need to walk all the way up the layer tree from the layer
michael@0 398 // represented by |aGuid.mScrollId| up to the root of the layer tree and apply
michael@0 399 // the input transforms at each level in turn. However, it is quite difficult
michael@0 400 // to do this given that the structure of the layer tree may be different from
michael@0 401 // the structure of the content tree. Also it may be impossible to do correctly
michael@0 402 // at this point because there are other CSS transforms and such interleaved in
michael@0 403 // between so applying the inputTransforms all in a row at the end may leave
michael@0 404 // some things transformed improperly. In practice we should rarely hit scenarios
michael@0 405 // where any of this matters, so I'm skipping it for now and just doing the single
michael@0 406 // transform for the layer that the input hit.
michael@0 407
michael@0 408 if (aGuid.mScrollId != FrameMetrics::NULL_SCROLL_ID) {
michael@0 409 nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aGuid.mScrollId);
michael@0 410 if (content) {
michael@0 411 void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
michael@0 412 if (property) {
michael@0 413 CSSPoint delta = (*static_cast<CSSPoint*>(property));
michael@0 414 return aInput + delta;
michael@0 415 }
michael@0 416 }
michael@0 417 }
michael@0 418 return aInput;
michael@0 419 }
michael@0 420
michael@0 421 nsIntPoint
michael@0 422 APZCCallbackHelper::ApplyCallbackTransform(const nsIntPoint& aPoint,
michael@0 423 const ScrollableLayerGuid& aGuid,
michael@0 424 const CSSToLayoutDeviceScale& aScale)
michael@0 425 {
michael@0 426 LayoutDevicePoint point = LayoutDevicePoint(aPoint.x, aPoint.y);
michael@0 427 point = ApplyCallbackTransform(point / aScale, aGuid) * aScale;
michael@0 428 LayoutDeviceIntPoint ret = gfx::RoundedToInt(point);
michael@0 429 return nsIntPoint(ret.x, ret.y);
michael@0 430 }
michael@0 431
michael@0 432 }
michael@0 433 }

mercurial