mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
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:
parent
911626890a
commit
fc6d547510
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -20,6 +20,7 @@ EXPORTS_NAMESPACES = mozilla/layout
|
||||
EXPORTS_mozilla/layout = \
|
||||
RenderFrameChild.h \
|
||||
RenderFrameParent.h \
|
||||
RenderFrameUtils.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
@ -8,8 +8,6 @@
|
||||
include protocol PBrowser;
|
||||
include protocol PLayers;
|
||||
|
||||
using mozilla::layers::LayersBackend;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
43
layout/ipc/RenderFrameUtils.h
Normal file
43
layout/ipc/RenderFrameUtils.h
Normal 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
|
Loading…
Reference in New Issue
Block a user