Bug 750977: Implement glue code for asynchronous panning/zooming. r=jlebar,roc,vingtetun

This is a rollup of three separate patches
 - Add nsIDocShell.asyncPanZoomEnabled. r=jlebar
 - Have BrowserElementChild service repaint requests and handle fallback synchronous scrolling (for now). r=jlebar,vingtetun
 - Glue async pan/zoom logic up between compositing, event dispatch, and repaint requests. r=roc

--HG--
rename : b2g/chrome/content/webapi.js => dom/browser-element/BrowserElementScrolling.js
This commit is contained in:
Chris Jones 2012-07-19 23:48:27 -07:00
parent 911626890a
commit fc6d547510
21 changed files with 672 additions and 187 deletions

View File

@ -247,6 +247,7 @@ pref("ui.dragThresholdY", 25);
pref("layers.acceleration.disabled", false);
pref("layers.offmainthreadcomposition.enabled", true);
pref("layers.async-video.enabled", true);
pref("layers.async-pan-zoom.enabled", true);
// Web Notifications
pref("notification.feature.enabled", true);

View File

@ -16,7 +16,6 @@ chrome.jar:
#ifndef ANDROID
content/screen.js (content/screen.js)
#endif
content/webapi.js (content/webapi.js)
content/content.css (content/content.css)
content/touchcontrols.css (content/touchcontrols.css)

View File

@ -18,7 +18,6 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const kWebApiShimFile = 'chrome://browser/content/webapi.js';
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
@ -41,8 +40,6 @@ ProcessGlobal.prototype = {
switch (topic) {
case 'app-startup': {
Services.obs.addObserver(this, 'console-api-log-event', false);
Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
break;
}
case 'console-api-log-event': {
@ -56,17 +53,6 @@ ProcessGlobal.prototype = {
' '));
break;
}
case 'remote-browser-frame-shown':
case 'in-process-browser-frame-shown': {
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
let mm = frameLoader.messageManager;
try {
mm.loadFrameScript(kWebApiShimFile, true);
} catch (e) {
log('Error loading ' + kWebApiShimFile + ' as frame script: ' + e + '\n');
}
break;
}
}
},
};

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/Util.h"
#ifdef MOZ_LOGGING
@ -201,6 +202,7 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#endif
using namespace mozilla;
using namespace mozilla::dom;
// Number of documents currently loading
static PRInt32 gNumberOfDocumentsLoading = 0;
@ -12166,3 +12168,14 @@ nsDocShell::GetAppId(PRUint32* aAppId)
return parent->GetAppId(aAppId);
}
NS_IMETHODIMP
nsDocShell::GetAsyncPanZoomEnabled(bool* aOut)
{
if (TabChild* tabChild = GetTabChildFrom(this)) {
*aOut = tabChild->IsAsyncPanZoomEnabled();
return NS_OK;
}
*aOut = false;
return NS_OK;
}

View File

@ -39,7 +39,7 @@ interface nsIWebBrowserPrint;
interface nsIVariant;
interface nsIPrivacyTransitionObserver;
[scriptable, builtinclass, uuid(c98f0f21-fe96-4f06-9978-0a9422a789fa)]
[scriptable, builtinclass, uuid(05802c0d-3315-4245-b72e-cf92eb3118a3)]
interface nsIDocShell : nsISupports
{
/**
@ -649,4 +649,10 @@ interface nsIDocShell : nsISupports
* nsIScriptSecurityManager::NO_APP_ID if the docshell is not in an app.
*/
readonly attribute unsigned long appId;
/**
* True iff asynchronous panning and zooming is enabled for this
* docshell.
*/
readonly attribute bool asyncPanZoomEnabled;
};

View File

@ -4,13 +4,10 @@
"use strict";
let Cu = Components.utils;
let Ci = Components.interfaces;
let Cc = Components.classes;
let Cr = Components.results;
let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Geometry.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
// Event whitelisted for bubbling.
@ -575,3 +572,10 @@ BrowserElementChild.prototype = {
};
var api = new BrowserElementChild();
// FIXME/bug 775438: use a JSM?
//
// The code in this included file depends on the |addEventListener|,
// |addMessageListener|, |content|, |Geometry| and |Services| symbols
// being "exported" from here.
#include BrowserElementScrolling.js

View File

@ -1,23 +1,14 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
dump('======================= webapi.js ======================= \n');
let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/Geometry.jsm');
const ContentPanning = {
init: function cp_init() {
['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
addEventListener(type, ContentPanning, true);
});
addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
},
handleEvent: function cp_handleEvent(evt) {
@ -124,9 +115,9 @@ const ContentPanning = {
if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
return [null, null];
let content = node.ownerDocument.defaultView;
let nodeContent = node.ownerDocument.defaultView;
while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
let style = content.getComputedStyle(node, null);
let style = nodeContent.getComputedStyle(node, null);
let overflow = [style.getPropertyValue('overflow'),
style.getPropertyValue('overflow-x'),
@ -144,7 +135,13 @@ const ContentPanning = {
node = node.parentNode;
}
return [content, this._generateCallback(content)];
if (ContentPanning._asyncPanZoomForViewportFrame &&
nodeContent === content)
// The parent context is asynchronously panning and zooming our
// root scrollable frame, so don't use our synchronous fallback.
return [null, null];
return [nodeContent, this._generateCallback(nodeContent)];
},
_generateCallback: function cp_generateCallback(content) {
@ -176,6 +173,39 @@ const ContentPanning = {
const kStateActive = 0x00000001;
this._domUtils.setContentState(root.documentElement, kStateActive);
},
get _asyncPanZoomForViewportFrame() {
return docShell.asyncPanZoomEnabled;
},
_recvViewportChange: function(data) {
let viewport = data.json;
let displayPort = viewport.displayPort;
let screenWidth = viewport.screenSize.width;
let screenHeight = viewport.screenSize.height;
let x = viewport.x;
let y = viewport.y;
let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
cwu.setCSSViewport(screenWidth, screenHeight);
// Set scroll position
cwu.setScrollPositionClampingScrollPortSize(
screenWidth / viewport.zoom, screenHeight / viewport.zoom);
content.scrollTo(x, y);
cwu.setResolution(displayPort.resolution, displayPort.resolution);
let element = null;
if (content.document && (element = content.document.documentElement)) {
cwu.setDisplayPortForElement(displayPort.left,
displayPort.top,
displayPort.width,
displayPort.height,
element);
}
}
};
@ -349,4 +379,3 @@ const KineticPanning = {
content.mozRequestAnimationFrame(callback);
}
};

View File

@ -13,18 +13,23 @@ include protocol PRenderFrame;
include protocol POfflineCacheUpdate;
include protocol PIndexedDB;
include "mozilla/dom/TabMessageUtils.h";
include "gfxMatrix.h";
include "mozilla/net/NeckoMessageUtils.h";
include "IPC/nsGUIEventIPC.h";
include "mozilla/dom/TabMessageUtils.h";
include "mozilla/layout/RenderFrameUtils.h";
include "mozilla/net/NeckoMessageUtils.h";
using IPC::URI;
using gfxMatrix;
using gfxSize;
using mozilla::layers::LayersBackend;
using mozilla::layout::ScrollingBehavior;
using mozilla::WindowsHandle;
using nscolor;
using nsCompositionEvent;
using nsIMEUpdatePreference;
using nsIntPoint;
using nsIntRect;
using nsIntSize;
using nsKeyEvent;
using nsMouseEvent;
@ -176,7 +181,8 @@ parent:
* the page that is currently loaded in the <browser>.
*/
sync PRenderFrame()
returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
returns (ScrollingBehavior scrolling,
LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
/**
* Starts an offline application cache update.
@ -241,6 +247,11 @@ child:
UpdateDimensions(nsRect rect, nsIntSize size);
UpdateFrame(nsIntRect displayPort,
nsIntPoint scrollOffset,
gfxSize resolution,
nsIntRect screenSize);
/**
* Sending an activate message moves focus to the child.
*/

View File

@ -52,6 +52,7 @@
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
#include "nsPresContext.h"
#include "nsPrintfCString.h"
#include "nsScriptLoader.h"
#include "nsSerializationHelper.h"
#include "nsThreadUtils.h"
@ -625,6 +626,37 @@ TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size)
return true;
}
bool
TabChild::RecvUpdateFrame(const nsIntRect& aDisplayPort,
const nsIntPoint& aScrollOffset,
const gfxSize& aResolution,
const nsIntRect& aScreenSize)
{
nsCString data;
data += nsPrintfCString("{ \"x\" : %d", aScrollOffset.x);
data += nsPrintfCString(", \"y\" : %d", aScrollOffset.y);
// We don't treat the x and y scales any differently for this
// semi-platform-specific code.
data += nsPrintfCString(", \"zoom\" : %f", aResolution.width);
data += nsPrintfCString(", \"displayPort\" : ");
data += nsPrintfCString("{ \"left\" : %d", aDisplayPort.X());
data += nsPrintfCString(", \"top\" : %d", aDisplayPort.Y());
data += nsPrintfCString(", \"width\" : %d", aDisplayPort.Width());
data += nsPrintfCString(", \"height\" : %d", aDisplayPort.Height());
data += nsPrintfCString(", \"resolution\" : %f", aResolution.width);
data += nsPrintfCString(" }");
data += nsPrintfCString(", \"screenSize\" : ");
data += nsPrintfCString("{ \"width\" : %d", aScreenSize.width);
data += nsPrintfCString(", \"height\" : %d", aScreenSize.height);
data += nsPrintfCString(" }");
data += nsPrintfCString(" }");
// Let the BrowserElementScrolling helper (if it exists) for this
// content manipulate the frame state.
return RecvAsyncMessage(NS_LITERAL_STRING("Viewport:Change"),
NS_ConvertUTF8toUTF16(data));
}
bool
TabChild::RecvActivate()
{
@ -967,7 +999,8 @@ TabChild::RecvDestroy()
}
PRenderFrameChild*
TabChild::AllocPRenderFrame(LayersBackend* aBackend,
TabChild::AllocPRenderFrame(ScrollingBehavior* aScrolling,
LayersBackend* aBackend,
int32_t* aMaxTextureSize,
uint64_t* aLayersId)
{
@ -1040,7 +1073,7 @@ TabChild::InitWidget(const nsIntSize& size)
int32_t maxTextureSize;
RenderFrameChild* remoteFrame =
static_cast<RenderFrameChild*>(SendPRenderFrameConstructor(
&be, &maxTextureSize, &id));
&mScrolling, &be, &maxTextureSize, &id));
if (!remoteFrame) {
NS_WARNING("failed to construct RenderFrame");
return false;
@ -1103,6 +1136,12 @@ TabChild::NotifyPainted()
}
}
bool
TabChild::IsAsyncPanZoomEnabled()
{
return mScrolling == ASYNC_PAN_ZOOM;
}
NS_IMETHODIMP
TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
{

View File

@ -43,6 +43,7 @@
#include "nsIPrincipal.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIScriptContext.h"
#include "nsPIDOMWindow.h"
#include "nsWeakReference.h"
#include "nsITabChild.h"
#include "mozilla/Attributes.h"
@ -166,6 +167,10 @@ public:
virtual bool RecvLoadURL(const nsCString& uri);
virtual bool RecvShow(const nsIntSize& size);
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
virtual bool RecvUpdateFrame(const nsIntRect& aDisplayPort,
const nsIntPoint& aScrollOffset,
const gfxSize& aResolution,
const nsIntRect& aScreenSize);
virtual bool RecvActivate();
virtual bool RecvDeactivate();
virtual bool RecvMouseEvent(const nsString& aType,
@ -249,9 +254,13 @@ public:
void SetBackgroundColor(const nscolor& aColor);
void NotifyPainted();
bool IsAsyncPanZoomEnabled();
protected:
NS_OVERRIDE
virtual PRenderFrameChild* AllocPRenderFrame(LayersBackend* aBackend,
virtual PRenderFrameChild* AllocPRenderFrame(ScrollingBehavior* aScrolling,
LayersBackend* aBackend,
int32_t* aMaxTextureSize,
uint64_t* aLayersId);
NS_OVERRIDE
@ -293,6 +302,7 @@ private:
PRUint32 mChromeFlags;
nsIntRect mOuterRect;
nscolor mLastBackgroundColor;
ScrollingBehavior mScrolling;
bool mDidFakeShow;
bool mIsBrowserFrame;

View File

@ -4,46 +4,50 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TabParent.h"
#include "base/basictypes.h"
#include "IDBFactory.h"
#include "IndexedDBParent.h"
#include "mozilla/BrowserElementParent.h"
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/ipc/DocumentRendererParent.h"
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
#include "nsIURI.h"
#include "nsFocusManager.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsIDOMElement.h"
#include "nsEventDispatcher.h"
#include "nsIDOMEventTarget.h"
#include "nsIWindowWatcher.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "TabChild.h"
#include "nsIDOMEvent.h"
#include "nsFrameLoader.h"
#include "nsNetUtil.h"
#include "nsContentUtils.h"
#include "nsContentPermissionHelper.h"
#include "nsIDOMHTMLFrameElement.h"
#include "nsIDialogCreator.h"
#include "nsThreadUtils.h"
#include "nsSerializationHelper.h"
#include "nsIPromptFactory.h"
#include "nsIContent.h"
#include "nsIWidget.h"
#include "nsIViewManager.h"
#include "mozilla/Preferences.h"
#include "mozilla/unused.h"
#include "nsCOMPtr.h"
#include "nsContentPermissionHelper.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsEventDispatcher.h"
#include "nsFocusManager.h"
#include "nsFrameLoader.h"
#include "nsIContent.h"
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMHTMLFrameElement.h"
#include "nsIDOMWindow.h"
#include "nsIDialogCreator.h"
#include "nsIPromptFactory.h"
#include "nsIURI.h"
#include "nsIMozBrowserFrame.h"
#include "nsIViewManager.h"
#include "nsIWidget.h"
#include "nsIWindowWatcher.h"
#include "nsNetUtil.h"
#include "nsPIDOMWindow.h"
#include "nsPrintfCString.h"
#include "mozilla/BrowserElementParent.h"
#include "IndexedDBParent.h"
#include "IDBFactory.h"
#include "nsSerializationHelper.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "TabChild.h"
#include "TabParent.h"
using namespace mozilla::dom;
using namespace mozilla::ipc;
using namespace mozilla::layers;
using namespace mozilla::layout;
using namespace mozilla::widget;
using namespace mozilla::dom::indexedDB;
@ -92,10 +96,8 @@ TabParent::Destroy()
// destroy itself and send back __delete__().
unused << SendDestroy();
for (size_t i = 0; i < ManagedPRenderFrameParent().Length(); ++i) {
RenderFrameParent* rfp =
static_cast<RenderFrameParent*>(ManagedPRenderFrameParent()[i]);
rfp->Destroy();
if (RenderFrameParent* frame = GetRenderFrame()) {
frame->Destroy();
}
}
@ -203,7 +205,19 @@ TabParent::Show(const nsIntSize& size)
void
TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
{
unused << SendUpdateDimensions(rect, size);
unused << SendUpdateDimensions(rect, size);
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyDimensionsChanged(size.width, size.height);
}
}
void
TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
{
unused << SendUpdateFrame(aFrameMetrics.mDisplayPort,
aFrameMetrics.mViewportScrollOffset,
aFrameMetrics.mResolution,
aFrameMetrics.mViewport);
}
void
@ -302,22 +316,30 @@ TabParent::SendKeyEvent(const nsAString& aType,
bool TabParent::SendRealMouseEvent(nsMouseEvent& event)
{
return PBrowserParent::SendRealMouseEvent(event);
nsMouseEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
return PBrowserParent::SendRealMouseEvent(e);
}
bool TabParent::SendMouseScrollEvent(nsMouseScrollEvent& event)
{
return PBrowserParent::SendMouseScrollEvent(event);
nsMouseScrollEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
return PBrowserParent::SendMouseScrollEvent(e);
}
bool TabParent::SendRealKeyEvent(nsKeyEvent& event)
{
return PBrowserParent::SendRealKeyEvent(event);
nsKeyEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
return PBrowserParent::SendRealKeyEvent(e);
}
bool TabParent::SendRealTouchEvent(nsTouchEvent& event)
{
return PBrowserParent::SendRealTouchEvent(event);
nsTouchEvent e(event);
MaybeForwardEventToRenderFrame(event, &e);
return PBrowserParent::SendRealTouchEvent(e);
}
bool
@ -348,10 +370,8 @@ TabParent::RecvSetCursor(const PRUint32& aCursor)
bool
TabParent::RecvSetBackgroundColor(const nscolor& aColor)
{
if (nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader()) {
if (RenderFrameParent* frame = frameLoader->GetCurrentRemoteFrame()) {
frame->SetBackgroundColor(aColor);
}
if (RenderFrameParent* frame = GetRenderFrame()) {
frame->SetBackgroundColor(aColor);
}
return true;
}
@ -557,6 +577,15 @@ TabParent::GetFrom(nsIContent* aContent)
return GetFrom(frameLoader);
}
RenderFrameParent*
TabParent::GetRenderFrame()
{
if (ManagedPRenderFrameParent().IsEmpty()) {
return nsnull;
}
return static_cast<RenderFrameParent*>(ManagedPRenderFrameParent()[0]);
}
bool
TabParent::RecvEndIMEComposition(const bool& aCancel,
nsString* aComposition)
@ -846,12 +875,17 @@ TabParent::HandleDelayedDialogs()
}
PRenderFrameParent*
TabParent::AllocPRenderFrame(LayersBackend* aBackend,
TabParent::AllocPRenderFrame(ScrollingBehavior* aScrolling,
LayersBackend* aBackend,
int32_t* aMaxTextureSize,
uint64_t* aLayersId)
{
MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
*aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
return new RenderFrameParent(frameLoader,
*aScrolling,
aBackend, aMaxTextureSize, aLayersId);
}
@ -960,6 +994,40 @@ TabParent::GetWidget() const
return widget.forget();
}
bool
TabParent::IsForMozBrowser()
{
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(content);
if (browserFrame) {
bool isBrowser = false;
browserFrame->GetReallyIsBrowser(&isBrowser);
return isBrowser;
}
return false;
}
bool
TabParent::UseAsyncPanZoom()
{
bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
bool asyncPanZoomEnabled =
Preferences::GetBool("layers.async-pan-zoom.enabled", false);
ContentParent* cp = static_cast<ContentParent*>(Manager());
return (usingOffMainThreadCompositing &&
!cp->IsForApp() && IsForMozBrowser() &&
asyncPanZoomEnabled);
}
void
TabParent::MaybeForwardEventToRenderFrame(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyInputEvent(aEvent, aOutEvent);
}
}
bool
TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
const nsString& aURL,

View File

@ -29,6 +29,15 @@ class nsIDOMElement;
class nsIURI;
namespace mozilla {
namespace layers {
struct FrameMetrics;
}
namespace layout {
class RenderFrameParent;
}
namespace dom {
class ContentDialogParent : public PContentDialogParent {};
@ -105,6 +114,7 @@ public:
// eating the return values
void Show(const nsIntSize& size);
void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
void Activate();
void Deactivate();
@ -203,7 +213,8 @@ protected:
bool AllowContentIME();
NS_OVERRIDE
virtual PRenderFrameParent* AllocPRenderFrame(LayersBackend* aBackend,
virtual PRenderFrameParent* AllocPRenderFrame(ScrollingBehavior* aScrolling,
LayersBackend* aBackend,
int32_t* aMaxTextureSize,
uint64_t* aLayersId);
NS_OVERRIDE
@ -229,7 +240,20 @@ protected:
private:
already_AddRefed<nsFrameLoader> GetFrameLoader() const;
already_AddRefed<nsIWidget> GetWidget() const;
layout::RenderFrameParent* GetRenderFrame();
void TryCacheDPI();
// Return true iff this TabParent was created for a mozbrowser
// frame.
bool IsForMozBrowser();
// When true, we create a pan/zoom controller for our frame and
// notify it of input events targeting us.
bool UseAsyncPanZoom();
// If we have a render frame currently, notify it that we're about
// to dispatch |aEvent| to our child. If there's a relevant
// transform in place, |aOutEvent| is the transformed |aEvent| to
// dispatch to content.
void MaybeForwardEventToRenderFrame(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent);
};
} // namespace dom

View File

@ -5,4 +5,4 @@
toolkit.jar:
content/global/test-ipc.xul (test.xul)
content/global/remote-test-ipc.js (remote-test.js)
content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
* content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)

View File

@ -13,6 +13,7 @@
# include "AndroidBridge.h"
#endif
#include "AsyncPanZoomController.h"
#include "BasicLayers.h"
#include "CompositorParent.h"
#include "LayerManagerOGL.h"
@ -34,12 +35,29 @@ namespace layers {
static CompositorParent* sCurrentCompositor;
static Thread* sCompositorThread = nsnull;
struct LayerTreeState {
nsRefPtr<Layer> mRoot;
nsRefPtr<AsyncPanZoomController> mController;
};
static uint8_t sPanZoomUserDataKey;
struct PanZoomUserData : public LayerUserData {
PanZoomUserData(AsyncPanZoomController* aController)
: mController(aController)
{ }
// We don't keep a strong ref here because PanZoomUserData is only
// set transiently, and APZC is thread-safe refcounted so
// AddRef/Release is expensive.
AsyncPanZoomController* mController;
};
/**
* Lookup the indirect shadow tree for |aId| and return it if it
* exists. Otherwise null is returned. This must only be called on
* the compositor thread.
*/
static Layer* GetIndirectShadowTree(uint64_t aId);
static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
void CompositorParent::StartUp()
{
@ -338,12 +356,19 @@ private:
void WalkTheTree(Layer* aLayer, Layer* aParent)
{
if (RefLayer* ref = aLayer->AsRefLayer()) {
if (Layer* referent = GetIndirectShadowTree(ref->GetReferentId())) {
if (const LayerTreeState* state = GetIndirectShadowTree(ref->GetReferentId())) {
Layer* referent = state->mRoot;
if (OP == Resolve) {
ref->ConnectReferentLayer(referent);
TemporarilyCompensateForContentScrollOffset(ref, referent);
if (AsyncPanZoomController* apzc = state->mController) {
referent->SetUserData(&sPanZoomUserDataKey,
new PanZoomUserData(apzc));
} else {
CompensateForContentScrollOffset(ref, referent);
}
} else {
ref->DetachReferentLayer(referent);
referent->RemoveUserData(&sPanZoomUserDataKey);
}
}
}
@ -353,10 +378,9 @@ private:
}
}
// FIXME/bug 750977: async pan/zoom supersedes this. Also, the fact
// that we have to do this is evidence of bad API design.
void TemporarilyCompensateForContentScrollOffset(Layer* aContainer,
Layer* aShadowContent)
// XXX the fact that we have to do this evidence of bad API design.
void CompensateForContentScrollOffset(Layer* aContainer,
Layer* aShadowContent)
{
ContainerLayer* c = aShadowContent->AsContainerLayer();
if (!c) {
@ -391,7 +415,10 @@ CompositorParent::Composite()
Layer* aLayer = mLayerManager->GetRoot();
AutoResolveRefLayers resolve(aLayer);
TransformShadowTree();
bool requestNextFrame = TransformShadowTree(mLastCompose);
if (requestNextFrame) {
ScheduleComposition();
}
RenderTraceLayers(aLayer, "0000");
@ -493,92 +520,148 @@ SetShadowProperties(Layer* aLayer)
}
}
void
CompositorParent::TransformShadowTree()
bool
CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
Layer *aLayer,
bool* aWantNextFrame)
{
bool appliedTransform = false;
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
appliedTransform |=
ApplyAsyncContentTransformToTree(aCurrentFrame, child, aWantNextFrame);
}
ContainerLayer* container = aLayer->AsContainerLayer();
if (!container) {
return appliedTransform;
}
if (LayerUserData* data = aLayer->GetUserData(&sPanZoomUserDataKey)) {
AsyncPanZoomController* controller = static_cast<PanZoomUserData*>(data)->mController;
ShadowLayer* shadow = aLayer->AsShadowLayer();
gfx3DMatrix newTransform;
*aWantNextFrame |=
controller->SampleContentTransformForFrame(aCurrentFrame,
container->GetFrameMetrics(),
aLayer->GetTransform(),
&newTransform);
shadow->SetShadowTransform(newTransform);
appliedTransform = true;
}
return appliedTransform;
}
bool
CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
{
bool wantNextFrame = false;
Layer* layer = GetPrimaryScrollableLayer();
ShadowLayer* shadow = layer->AsShadowLayer();
ContainerLayer* container = layer->AsContainerLayer();
Layer* root = mLayerManager->GetRoot();
const FrameMetrics& metrics = container->GetFrameMetrics();
const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform();
const gfx3DMatrix& rootTransform = root->GetTransform();
const gfx3DMatrix& currentTransform = layer->GetTransform();
float rootScaleX = rootTransform.GetXScale();
float rootScaleY = rootTransform.GetYScale();
// FIXME/bug 775437: unify this interface with the ~native-fennec
// derived code
//
// Attempt to apply an async content transform to any layer that has
// an async pan zoom controller (which means that it is rendered
// async using Gecko). If this fails, fall back to transforming the
// primary scrollable layer. "Failing" here means that we don't
// find a frame that is async scrollable. Note that the fallback
// code also includes Fennec which is rendered async. Fennec uses
// its own platform-specific async rendering that is done partially
// in Gecko and partially in Java.
if (!ApplyAsyncContentTransformToTree(aCurrentFrame, root, &wantNextFrame)) {
gfx3DMatrix treeTransform;
if (mIsFirstPaint) {
mContentRect = metrics.mContentRect;
SetFirstPaintViewport(metrics.mViewportScrollOffset,
1/rootScaleX,
mContentRect,
metrics.mCSSContentRect);
mIsFirstPaint = false;
} else if (!metrics.mContentRect.IsEqualEdges(mContentRect)) {
mContentRect = metrics.mContentRect;
SetPageRect(metrics.mCSSContentRect);
// Translate fixed position layers so that they stay in the correct position
// when mScrollOffset and metricsScrollOffset differ.
gfxPoint offset;
gfxPoint scaleDiff;
float rootScaleX = rootTransform.GetXScale(),
rootScaleY = rootTransform.GetYScale();
if (mIsFirstPaint) {
mContentRect = metrics.mContentRect;
SetFirstPaintViewport(metrics.mViewportScrollOffset,
1/rootScaleX,
mContentRect,
metrics.mCSSContentRect);
mIsFirstPaint = false;
} else if (!metrics.mContentRect.IsEqualEdges(mContentRect)) {
mContentRect = metrics.mContentRect;
SetPageRect(metrics.mCSSContentRect);
}
// We synchronise the viewport information with Java after sending the above
// notifications, so that Java can take these into account in its response.
// Calculate the absolute display port to send to Java
nsIntRect displayPort = metrics.mDisplayPort;
nsIntPoint scrollOffset = metrics.mViewportScrollOffset;
displayPort.x += scrollOffset.x;
displayPort.y += scrollOffset.y;
SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated,
mScrollOffset, mXScale, mYScale);
mLayersUpdated = false;
// Handle transformations for asynchronous panning and zooming. We determine the
// zoom used by Gecko from the transformation set on the root layer, and we
// determine the scroll offset used by Gecko from the frame metrics of the
// primary scrollable layer. We compare this to the desired zoom and scroll
// offset in the view transform we obtained from Java in order to compute the
// transformation we need to apply.
float tempScaleDiffX = rootScaleX * mXScale;
float tempScaleDiffY = rootScaleY * mYScale;
nsIntPoint metricsScrollOffset(0, 0);
if (metrics.IsScrollable()) {
metricsScrollOffset = metrics.mViewportScrollOffset;
}
nsIntPoint scrollCompensation(
(mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
(mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
treeTransform = gfx3DMatrix(ViewTransform(-scrollCompensation, mXScale, mYScale));
// If the contents can fit entirely within the widget area on a particular
// dimenson, we need to translate and scale so that the fixed layers remain
// within the page boundaries.
if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) {
offset.x = -metricsScrollOffset.x;
scaleDiff.x = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width);
} else {
offset.x = clamped(mScrollOffset.x / tempScaleDiffX, (float)mContentRect.x,
mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX) -
metricsScrollOffset.x;
scaleDiff.x = tempScaleDiffX;
}
if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) {
offset.y = -metricsScrollOffset.y;
scaleDiff.y = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height);
} else {
offset.y = clamped(mScrollOffset.y / tempScaleDiffY, (float)mContentRect.y,
mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY) -
metricsScrollOffset.y;
scaleDiff.y = tempScaleDiffY;
}
shadow->SetShadowTransform(treeTransform * currentTransform);
TransformFixedLayers(layer, offset, scaleDiff);
}
// We synchronise the viewport information with Java after sending the above
// notifications, so that Java can take these into account in its response.
// Calculate the absolute display port to send to Java
nsIntRect displayPort = metrics.mDisplayPort;
nsIntPoint scrollOffset = metrics.mViewportScrollOffset;
displayPort.x += scrollOffset.x;
displayPort.y += scrollOffset.y;
SyncViewportInfo(displayPort, 1/rootScaleX, mLayersUpdated,
mScrollOffset, mXScale, mYScale);
mLayersUpdated = false;
// Handle transformations for asynchronous panning and zooming. We determine the
// zoom used by Gecko from the transformation set on the root layer, and we
// determine the scroll offset used by Gecko from the frame metrics of the
// primary scrollable layer. We compare this to the desired zoom and scroll
// offset in the view transform we obtained from Java in order to compute the
// transformation we need to apply.
float tempScaleDiffX = rootScaleX * mXScale;
float tempScaleDiffY = rootScaleY * mYScale;
nsIntPoint metricsScrollOffset(0, 0);
if (metrics.IsScrollable())
metricsScrollOffset = metrics.mViewportScrollOffset;
nsIntPoint scrollCompensation(
(mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
(mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
ViewTransform treeTransform(-scrollCompensation, mXScale, mYScale);
shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
// Translate fixed position layers so that they stay in the correct position
// when mScrollOffset and metricsScrollOffset differ.
gfxPoint offset;
gfxPoint scaleDiff;
// If the contents can fit entirely within the widget area on a particular
// dimenson, we need to translate and scale so that the fixed layers remain
// within the page boundaries.
if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) {
offset.x = -metricsScrollOffset.x;
scaleDiff.x = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width);
} else {
offset.x = clamped(mScrollOffset.x / tempScaleDiffX, (float)mContentRect.x,
mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX) -
metricsScrollOffset.x;
scaleDiff.x = tempScaleDiffX;
}
if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) {
offset.y = -metricsScrollOffset.y;
scaleDiff.y = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height);
} else {
offset.y = clamped(mScrollOffset.y / tempScaleDiffY, (float)mContentRect.y,
mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY) -
metricsScrollOffset.y;
scaleDiff.y = tempScaleDiffY;
}
TransformFixedLayers(layer, offset, scaleDiff);
return wantNextFrame;
}
void
@ -731,7 +814,7 @@ CompositorParent* CompositorParent::RemoveCompositor(PRUint64 id)
return it->second;
}
typedef map<uint64_t, RefPtr<Layer> > LayerTreeMap;
typedef map<uint64_t, LayerTreeState> LayerTreeMap;
static LayerTreeMap sIndirectLayerTrees;
/*static*/ uint64_t
@ -743,6 +826,45 @@ CompositorParent::AllocateLayerTreeId()
return ++ids;
}
static void
EraseLayerState(uint64_t aId)
{
sIndirectLayerTrees.erase(aId);
}
/*static*/ void
CompositorParent::DeallocateLayerTreeId(uint64_t aId)
{
MOZ_ASSERT(NS_IsMainThread());
CompositorLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&EraseLayerState, aId));
}
static void
UpdateControllerForLayersId(uint64_t aLayersId,
AsyncPanZoomController* aController)
{
// Adopt ref given to us by SetPanZoomControllerForLayerTree()
sIndirectLayerTrees[aLayersId].mController =
already_AddRefed<AsyncPanZoomController>(aController);
// Notify the AsyncPanZoomController about the current compositor so that it
// can request composites off the compositor thread.
aController->SetCompositorParent(sCurrentCompositor);
}
/*static*/ void
CompositorParent::SetPanZoomControllerForLayerTree(uint64_t aLayersId,
AsyncPanZoomController* aController)
{
// This ref is adopted by UpdateControllerForLayersId().
aController->AddRef();
CompositorLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&UpdateControllerForLayersId,
aLayersId,
aController));
}
/**
* This class handles layer updates pushed directly from child
* processes to the compositor thread. It's associated with a
@ -817,20 +939,24 @@ CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
}
static void
UpdateIndirectTree(uint64_t aId, Layer* aRoot)
UpdateIndirectTree(uint64_t aId, Layer* aRoot, bool isFirstPaint)
{
sIndirectLayerTrees[aId] = aRoot;
sIndirectLayerTrees[aId].mRoot = aRoot;
if (ContainerLayer* root = aRoot->AsContainerLayer()) {
if (AsyncPanZoomController* apzc = sIndirectLayerTrees[aId].mController) {
apzc->NotifyLayersUpdated(root->GetFrameMetrics(), isFirstPaint);
}
}
}
static Layer*
static const LayerTreeState*
GetIndirectShadowTree(uint64_t aId)
{
LayerTreeMap::const_iterator cit = sIndirectLayerTrees.find(aId);
if (sIndirectLayerTrees.end() == cit) {
return nsnull;
}
return cit->second;
return &cit->second;
}
static void
@ -880,7 +1006,7 @@ CrossProcessCompositorParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree
if (shadowRoot) {
SetShadowProperties(shadowRoot);
}
UpdateIndirectTree(id, shadowRoot);
UpdateIndirectTree(id, shadowRoot, isFirstPaint);
sCurrentCompositor->ScheduleComposition();
}
@ -894,4 +1020,3 @@ CrossProcessCompositorParent::DeferredDestroy()
} // namespace layers
} // namespace mozilla

View File

@ -30,6 +30,7 @@ class Thread;
namespace mozilla {
namespace layers {
class AsyncPanZoomController;
class LayerManager;
// Represents (affine) transforms that are calculated from a content view.
@ -106,8 +107,28 @@ public:
*/
static void ShutDown();
/** Must run on the content main thread. */
/**
* Allocate an ID that can be used to refer to a layer tree and
* associated resources that live only on the compositor thread.
*
* Must run on the content main thread.
*/
static uint64_t AllocateLayerTreeId();
/**
* Release compositor-thread resources referred to by |aID|.
*
* Must run on the content main thread.
*/
static void DeallocateLayerTreeId(uint64_t aId);
/**
* Set aController as the pan/zoom controller for the tree referred
* to by aLayersId.
*
* Must run on content main thread.
*/
static void SetPanZoomControllerForLayerTree(uint64_t aLayersId,
AsyncPanZoomController* aController);
/**
* A new child process has been configured to push transactions
@ -135,7 +156,14 @@ private:
void ResumeComposition();
void ResumeCompositionAndResize(int width, int height);
void TransformShadowTree();
// Sample transforms for layer trees. Return true to request
// another animation frame.
bool TransformShadowTree(TimeStamp aCurrentFrame);
// Return true if an AsyncPanZoomController content transform was
// applied for |aLayer|. *aWantNextFrame is set to true if the
// controller wants another animation frame.
bool ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer* aLayer,
bool* aWantNextFrame);
inline PlatformThreadId CompositorThreadID();

View File

@ -680,7 +680,15 @@ PresShell::PresShell()
mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
mIsThemeSupportDisabled = false;
mIsActive = true;
// FIXME/bug 735029: find a better solution to this problem
#ifdef MOZ_JAVA_COMPOSITOR
// The java pan/zoom code uses this to mean approximately "request a
// reset of pan/zoom state" which doesn't necessarily correspond
// with the first paint of content.
mIsFirstPaint = false;
#else
mIsFirstPaint = true;
#endif
mFrozen = false;
#ifdef DEBUG
mPresArenaAllocCount = 0;

View File

@ -20,6 +20,7 @@ EXPORTS_NAMESPACES = mozilla/layout
EXPORTS_mozilla/layout = \
RenderFrameChild.h \
RenderFrameParent.h \
RenderFrameUtils.h \
$(NULL)
CPPSRCS = \

View File

@ -8,8 +8,6 @@
include protocol PBrowser;
include protocol PLayers;
using mozilla::layers::LayersBackend;
namespace mozilla {
namespace layout {

View File

@ -13,6 +13,8 @@
#ifdef MOZ_ENABLE_D3D9_LAYER
# include "LayerManagerD3D9.h"
#endif //MOZ_ENABLE_D3D9_LAYER
#include "mozilla/dom/TabParent.h"
#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/ShadowLayersParent.h"
#include "nsContentUtils.h"
@ -24,6 +26,7 @@
#include "LayersBackend.h"
typedef nsContentView::ViewConfig ViewConfig;
using namespace mozilla::dom;
using namespace mozilla::layers;
namespace mozilla {
@ -453,8 +456,40 @@ GetFrom(nsFrameLoader* aFrameLoader)
return nsContentUtils::LayerManagerForDocument(doc);
}
class RemoteContentController : public GeckoContentController {
public:
RemoteContentController(RenderFrameParent* aRenderFrame)
: mUILoop(MessageLoop::current())
, mRenderFrame(aRenderFrame)
{ }
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) MOZ_OVERRIDE
{
if (MessageLoop::current() != mUILoop) {
// We have to send this message from the "UI thread" (main
// thread).
mUILoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &RemoteContentController::RequestContentRepaint,
aFrameMetrics));
return;
}
if (mRenderFrame) {
TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
browser->UpdateFrame(aFrameMetrics);
}
}
void ClearRenderFrame() { mRenderFrame = nsnull; }
private:
MessageLoop* mUILoop;
RenderFrameParent* mRenderFrame;
};
RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
mozilla::layers::LayersBackend* aBackendType,
ScrollingBehavior aScrollingBehavior,
LayersBackend* aBackendType,
int* aMaxTextureSize,
uint64_t* aId)
: mLayersId(0)
@ -477,6 +512,13 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
// Our remote frame will push layers updates to the compositor,
// and we'll keep an indirect reference to that tree.
*aId = mLayersId = CompositorParent::AllocateLayerTreeId();
if (aScrollingBehavior == ASYNC_PAN_ZOOM) {
mContentController = new RemoteContentController(this);
mPanZoomController = new AsyncPanZoomController(
mContentController, AsyncPanZoomController::USE_GESTURE_DETECTOR);
CompositorParent::SetPanZoomControllerForLayerTree(mLayersId,
mPanZoomController);
}
}
}
@ -615,9 +657,35 @@ RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
BuildViewMap();
}
void
RenderFrameParent::NotifyInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent)
{
if (mPanZoomController) {
mPanZoomController->HandleInputEvent(aEvent, aOutEvent);
}
}
void
RenderFrameParent::NotifyDimensionsChanged(int width, int height)
{
if (mPanZoomController) {
mPanZoomController->UpdateViewportSize(width, height);
}
}
void
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
{
if (mLayersId != 0) {
CompositorParent::DeallocateLayerTreeId(mLayersId);
if (mContentController) {
// Stop our content controller from requesting repaints of our
// content.
mContentController->ClearRenderFrame();
}
}
if (mFrameLoader && mFrameLoader->GetCurrentRemoteFrame() == this) {
// XXX this might cause some weird issues ... we'll just not
// redraw the part of the window covered by this until the "next"

View File

@ -8,12 +8,13 @@
#ifndef mozilla_layout_RenderFrameParent_h
#define mozilla_layout_RenderFrameParent_h
#include <map>
#include "LayersBackend.h"
#include "mozilla/layout/PRenderFrameParent.h"
#include "mozilla/layers/ShadowLayersManager.h"
#include <map>
#include "nsDisplayList.h"
#include "LayersBackend.h"
#include "RenderFrameUtils.h"
class nsContentView;
class nsFrameLoader;
@ -21,12 +22,18 @@ class nsSubDocumentFrame;
namespace mozilla {
class InputEvent;
namespace layers {
class AsyncPanZoomController;
class GestureEventListener;
class ShadowLayersParent;
}
namespace layout {
class RemoteContentController;
class RenderFrameParent : public PRenderFrameParent,
public mozilla::layers::ShadowLayersManager
{
@ -40,7 +47,13 @@ class RenderFrameParent : public PRenderFrameParent,
public:
typedef std::map<ViewID, nsRefPtr<nsContentView> > ViewMap;
/**
* Select the desired scrolling behavior. If ASYNC_PAN_ZOOM is
* chosen, then RenderFrameParent will watch input events and use
* them to asynchronously pan and zoom.
*/
RenderFrameParent(nsFrameLoader* aFrameLoader,
ScrollingBehavior aScrollingBehavior,
mozilla::layers::LayersBackend* aBackendType,
int* aMaxTextureSize,
uint64_t* aId);
@ -73,6 +86,11 @@ public:
void SetBackgroundColor(nscolor aColor) { mBackgroundColor = gfxRGBA(aColor); };
void NotifyInputEvent(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent);
void NotifyDimensionsChanged(int width, int height);
protected:
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
@ -84,6 +102,7 @@ protected:
private:
void BuildViewMap();
void TriggerRepaint();
void DispatchEventForPanZoomController(const InputEvent& aEvent);
ShadowLayersParent* GetShadowLayers() const;
uint64_t GetLayerTreeId() const;
@ -96,6 +115,11 @@ private:
nsRefPtr<nsFrameLoader> mFrameLoader;
nsRefPtr<ContainerLayer> mContainer;
// When our scrolling behavior is ASYNC_PAN_ZOOM, we have a nonnull
// AsyncPanZoomController. It's associated with the shadow layer
// tree on the compositor thread.
nsRefPtr<layers::AsyncPanZoomController> mPanZoomController;
nsRefPtr<RemoteContentController> mContentController;
// This contains the views for all the scrollable frames currently in the
// painted region of our remote content.

View File

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layer_RenderFrameUtils_h
#define mozilla_layer_RenderFrameUtils_h
namespace mozilla {
namespace layout {
enum ScrollingBehavior {
/**
* Use default scrolling behavior, which is synchronous: web content
* is reflowed and repainted for every scroll or zoom.
*/
DEFAULT_SCROLLING,
/**
* Use asynchronous panning and zooming, in which prerendered
* content can be translated and scaled independently of the thread
* painting content, without content reflowing or repainting.
*/
ASYNC_PAN_ZOOM,
SCROLLING_BEHAVIOR_SENTINEL
};
} // namespace layout
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::layout::ScrollingBehavior>
: public EnumSerializer<mozilla::layout::ScrollingBehavior,
mozilla::layout::DEFAULT_SCROLLING,
mozilla::layout::SCROLLING_BEHAVIOR_SENTINEL>
{};
} // namespace IPC
#endif // mozilla_layer_RenderFrameUtils_h