This commit is contained in:
Benoit Girard 2012-02-08 20:42:17 -05:00
Родитель b7a8f90e50 a4dab36b43
Коммит c64be82706
9 изменённых файлов: 101 добавлений и 87 удалений

Просмотреть файл

@ -52,9 +52,9 @@ namespace mozilla {
namespace layers { namespace layers {
CompositorParent::CompositorParent(nsIWidget* aWidget) CompositorParent::CompositorParent(nsIWidget* aWidget)
: mPaused(false) : mWidget(aWidget)
, mWidget(aWidget)
, mCurrentCompositeTask(NULL) , mCurrentCompositeTask(NULL)
, mPaused(false)
{ {
MOZ_COUNT_CTOR(CompositorParent); MOZ_COUNT_CTOR(CompositorParent);
} }
@ -104,13 +104,11 @@ CompositorParent::PauseComposition()
void void
CompositorParent::ResumeComposition() CompositorParent::ResumeComposition()
{ {
if (mPaused) { mPaused = false;
mPaused = false;
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
static_cast<LayerManagerOGL*>(mLayerManager.get())->gl()->RenewSurface(); static_cast<LayerManagerOGL*>(mLayerManager.get())->gl()->RenewSurface();
#endif #endif
}
} }
void void
@ -184,13 +182,49 @@ CompositorParent::Composite()
printf_stderr("Correcting for position fixed %i, %i\n", -mScrollOffset.x, -mScrollOffset.y); printf_stderr("Correcting for position fixed %i, %i\n", -mScrollOffset.x, -mScrollOffset.y);
worldTransform.Translate(offset); worldTransform.Translate(offset);
worldTransform.Scale(mXScale, mYScale, 1.0f); worldTransform.Scale(mXScale, mYScale, 1.0f);
Layer* root = mLayerManager->GetRoot(); #ifdef MOZ_WIDGET_ANDROID
root->AsShadowLayer()->SetShadowTransform(worldTransform); Layer* layer = GetPrimaryScrollableLayer();
#else
Layer* layer = mLayerManager->GetRoot();
#endif
layer->AsShadowLayer()->SetShadowTransform(worldTransform);
mLayerManager->EndEmptyTransaction(); mLayerManager->EndEmptyTransaction();
mLastCompose = mozilla::TimeStamp::Now(); mLastCompose = mozilla::TimeStamp::Now();
} }
#ifdef MOZ_WIDGET_ANDROID
// Do a breadth-first search to find the first layer in the tree with a
// displayport set.
Layer*
CompositorParent::GetPrimaryScrollableLayer()
{
Layer* root = mLayerManager->GetRoot();
nsTArray<Layer*> queue;
queue.AppendElement(root);
for (int i = 0; i < queue.Length(); i++) {
ContainerLayer* containerLayer = queue[i]->AsContainerLayer();
if (!containerLayer) {
continue;
}
const FrameMetrics& frameMetrics = containerLayer->GetFrameMetrics();
if (!frameMetrics.mDisplayPort.IsEmpty()) {
return containerLayer;
}
Layer* child = containerLayer->GetFirstChild();
while (child) {
queue.AppendElement(child);
child = child->GetNextSibling();
}
}
return root;
}
#endif
// Go down shadow layer tree, setting properties to match their non-shadow // Go down shadow layer tree, setting properties to match their non-shadow
// counterparts. // counterparts.
static void static void
@ -383,12 +417,6 @@ CompositorParent::TestScroll()
PLayersParent* PLayersParent*
CompositorParent::AllocPLayers(const LayersBackend &backendType) CompositorParent::AllocPLayers(const LayersBackend &backendType)
{ {
#ifdef MOZ_WIDGET_ANDROID
// Registering with the compositor will create the surface view that
// the layer manager expects to attach to.
//RegisterCompositorWithJava();
#endif
if (backendType == LayerManager::LAYERS_OPENGL) { if (backendType == LayerManager::LAYERS_OPENGL) {
nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(mWidget); nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(mWidget);
mWidget = NULL; mWidget = NULL;
@ -417,14 +445,6 @@ CompositorParent::DeallocPLayers(PLayersParent* actor)
return true; return true;
} }
#ifdef MOZ_WIDGET_ANDROID
void
CompositorParent::RegisterCompositorWithJava()
{
mozilla::AndroidBridge::Bridge()->RegisterCompositor();
}
#endif
} // namespace layers } // namespace layers
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -114,18 +114,17 @@ private:
// Platform specific functions // Platform specific functions
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
/**
* Register the compositor thread with the Java native thread.
* This will replace the temporary compositor with the real
* Gecko compositor thread.
**/
void RegisterCompositorWithJava();
/** /**
* Asks Java for the viewport position and updates the world transform * Asks Java for the viewport position and updates the world transform
* accordingly. * accordingly.
*/ */
void RequestViewTransform(); void RequestViewTransform();
/**
* Does a breadth-first search to find the first layer in the tree with a
* displayport set.
*/
Layer* GetPrimaryScrollableLayer();
#endif #endif
nsRefPtr<LayerManager> mLayerManager; nsRefPtr<LayerManager> mLayerManager;

Просмотреть файл

@ -782,18 +782,7 @@ LayerManagerOGL::Render()
mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST); mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
static int i = 0; mGLContext->fClearColor(1.0, 1.0, 1.0, 0.0);
i++;
i=i%3;
if( i == 0 ) {
mGLContext->fClearColor(1.0, 0.0, 0.0, 0.0);
} else if( i == 1 ) {
mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
} else if( i == 2 ) {
mGLContext->fClearColor(1.0, 1.0, 0.0, 0.0);
} else {
mGLContext->fClearColor(0.0, 1.0, 0.0, 0.0);
}
mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT); mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
// Render our layers. // Render our layers.

Просмотреть файл

@ -871,6 +871,8 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y)); matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y));
layer->SetTransform(gfx3DMatrix::From2D(matrix)); layer->SetTransform(gfx3DMatrix::From2D(matrix));
// FIXME: Temporary workaround for bug 681192 and bug 724786. Uncomment this code before review!
#if 0
// Calculate exact position of the top-left of the active scrolled root. // Calculate exact position of the top-left of the active scrolled root.
// This might not be 0,0 due to the snapping in ScaleToNearestPixels. // This might not be 0,0 due to the snapping in ScaleToNearestPixels.
gfxPoint activeScrolledRootTopLeft = scaledOffset - matrix.GetTranslation(); gfxPoint activeScrolledRootTopLeft = scaledOffset - matrix.GetTranslation();
@ -882,6 +884,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
nsIntRect invalidate = layer->GetValidRegion().GetBounds(); nsIntRect invalidate = layer->GetValidRegion().GetBounds();
layer->InvalidateRegion(invalidate); layer->InvalidateRegion(invalidate);
} }
#endif
return layer.forget(); return layer.forget();
} }

Просмотреть файл

@ -2043,16 +2043,18 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Since making new layers is expensive, only use nsDisplayScrollLayer // Since making new layers is expensive, only use nsDisplayScrollLayer
// if the area is scrollable. // if the area is scrollable and there's a displayport (or we're the content
// process).
nsRect scrollRange = GetScrollRange(); nsRect scrollRange = GetScrollRange();
ScrollbarStyles styles = GetScrollbarStylesFromFrame(); ScrollbarStyles styles = GetScrollbarStylesFromFrame();
mShouldBuildLayer = mShouldBuildLayer =
(XRE_GetProcessType() == GeckoProcessType_Content && ((XRE_GetProcessType() == GeckoProcessType_Content || usingDisplayport) &&
(styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN || (styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN ||
styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) && styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) &&
(scrollRange.width > 0 || (scrollRange.width > 0 ||
scrollRange.height > 0) && scrollRange.height > 0) &&
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument())); (usingDisplayport || !mIsRoot ||
!mOuter->PresContext()->IsRootContentDocument()));
if (ShouldBuildLayer()) { if (ShouldBuildLayer()) {
// ScrollLayerWrapper must always be created because it initializes the // ScrollLayerWrapper must always be created because it initializes the

Просмотреть файл

@ -157,8 +157,7 @@ public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.
} }
if (mListener != null) { if (mListener != null) {
mListener.compositionResumeRequested(); mListener.surfaceChanged(width, height);
mListener.renderRequested();
} }
} }
@ -203,6 +202,7 @@ public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.
void renderRequested(); void renderRequested();
void compositionPauseRequested(); void compositionPauseRequested();
void compositionResumeRequested(); void compositionResumeRequested();
void surfaceChanged(int width, int height);
} }
public static class FlexibleGLSurfaceViewException extends RuntimeException { public static class FlexibleGLSurfaceViewException extends RuntimeException {

Просмотреть файл

@ -203,5 +203,13 @@ public class GeckoGLLayerClient extends GeckoLayerClient
Log.e(LOGTAG, "### Scheduling ResumeComposition"); Log.e(LOGTAG, "### Scheduling ResumeComposition");
GeckoAppShell.scheduleResumeComposition(); GeckoAppShell.scheduleResumeComposition();
} }
public void surfaceChanged(int width, int height) {
compositionPauseRequested();
LayerController layerController = getLayerController();
layerController.setViewportSize(new FloatSize(width, height));
compositionResumeRequested();
renderRequested();
}
} }

Просмотреть файл

@ -74,7 +74,7 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
/* The viewport that Gecko will display when drawing is finished */ /* The viewport that Gecko will display when drawing is finished */
protected ViewportMetrics mNewGeckoViewport; protected ViewportMetrics mNewGeckoViewport;
private static final long MIN_VIEWPORT_CHANGE_DELAY = 200L; private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
private long mLastViewportChangeTime; private long mLastViewportChangeTime;
private boolean mPendingViewportAdjust; private boolean mPendingViewportAdjust;
private boolean mViewportSizeChanged; private boolean mViewportSizeChanged;
@ -265,8 +265,10 @@ public abstract class GeckoLayerClient extends LayerClient implements GeckoEvent
} }
private void adjustViewportWithThrottling() { private void adjustViewportWithThrottling() {
if (!getLayerController().getRedrawHint()) // FIXME: Allow redraw while a finger is down, but only if we're about to checkerboard.
return; // This requires fixing aboutToCheckerboard() to know about the new buffer size.
/*if (!getLayerController().getRedrawHint())
return;*/
if (mPendingViewportAdjust) if (mPendingViewportAdjust)
return; return;

Просмотреть файл

@ -102,6 +102,12 @@ const kElementsReceivingInput = {
video: true video: true
}; };
// How many pixels on each side to buffer.
const kBufferAmount = 300;
// Whether we're using GL layers.
const kUsingGLLayers = true;
function dump(a) { function dump(a) {
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a); Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
} }
@ -863,27 +869,20 @@ var BrowserApp = {
top: focusedRect.top - tab.viewportExcess.y, top: focusedRect.top - tab.viewportExcess.y,
bottom: focusedRect.bottom - tab.viewportExcess.y bottom: focusedRect.bottom - tab.viewportExcess.y
}; };
let transformChanged = false;
if (focusedRect.right >= visibleContentWidth && focusedRect.left > 0) { if (focusedRect.right >= visibleContentWidth && focusedRect.left > 0) {
// the element is too far off the right side, so we need to scroll to the right more // the element is too far off the right side, so we need to scroll to the right more
tab.viewportExcess.x += Math.min(focusedRect.left, focusedRect.right - visibleContentWidth); tab.viewportExcess.x += Math.min(focusedRect.left, focusedRect.right - visibleContentWidth);
transformChanged = true;
} else if (focusedRect.left < 0) { } else if (focusedRect.left < 0) {
// the element is too far off the left side, so we need to scroll to the left more // the element is too far off the left side, so we need to scroll to the left more
tab.viewportExcess.x += focusedRect.left; tab.viewportExcess.x += focusedRect.left;
transformChanged = true;
} }
if (focusedRect.bottom >= visibleContentHeight && focusedRect.top > 0) { if (focusedRect.bottom >= visibleContentHeight && focusedRect.top > 0) {
// the element is too far down, so we need to scroll down more // the element is too far down, so we need to scroll down more
tab.viewportExcess.y += Math.min(focusedRect.top, focusedRect.bottom - visibleContentHeight); tab.viewportExcess.y += Math.min(focusedRect.top, focusedRect.bottom - visibleContentHeight);
transformChanged = true;
} else if (focusedRect.top < 0) { } else if (focusedRect.top < 0) {
// the element is too far up, so we need to scroll up more // the element is too far up, so we need to scroll up more
tab.viewportExcess.y += focusedRect.top; tab.viewportExcess.y += focusedRect.top;
transformChanged = true;
} }
if (transformChanged)
tab.updateTransform();
// finally, let java know where we ended up // finally, let java know where we ended up
tab.sendViewportUpdate(); tab.sendViewportUpdate();
} }
@ -1409,6 +1408,8 @@ let gTabIDFactory = 0;
let gScreenWidth = 1; let gScreenWidth = 1;
let gScreenHeight = 1; let gScreenHeight = 1;
let gBrowserWidth = null;
function Tab(aURL, aParams) { function Tab(aURL, aParams) {
this.browser = null; this.browser = null;
this.vbox = null; this.vbox = null;
@ -1438,14 +1439,19 @@ Tab.prototype = {
this.browser = document.createElement("browser"); this.browser = document.createElement("browser");
this.browser.setAttribute("type", "content-targetable"); this.browser.setAttribute("type", "content-targetable");
this.setBrowserSize(980, 480); this.setBrowserSize(980, 480);
this.browser.style.MozTransformOrigin = "0 0"; this.browser.style.width = gScreenWidth + "px";
this.browser.style.height = gScreenHeight + "px";
this.vbox.appendChild(this.browser); this.vbox.appendChild(this.browser);
this.browser.stop(); this.browser.stop();
// Turn off clipping so we can buffer areas outside of the browser element.
let frameLoader = this.browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader; let frameLoader = this.browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
frameLoader.clipSubdocument = false; if (kUsingGLLayers) {
frameLoader.renderMode = Ci.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL;
} else {
// Turn off clipping so we can buffer areas outside of the browser element.
frameLoader.clipSubdocument = false;
}
this.id = ++gTabIDFactory; this.id = ++gTabIDFactory;
@ -1568,27 +1574,19 @@ Tab.prototype = {
this._viewport.height = gScreenHeight = aViewport.height; this._viewport.height = gScreenHeight = aViewport.height;
dump("### gScreenWidth = " + gScreenWidth + "\n"); dump("### gScreenWidth = " + gScreenWidth + "\n");
let transformChanged = false;
if ((aViewport.offsetX != this._viewport.offsetX) || if ((aViewport.offsetX != this._viewport.offsetX) ||
(excessX != this.viewportExcess.x)) { (excessX != this.viewportExcess.x)) {
this._viewport.offsetX = aViewport.offsetX; this._viewport.offsetX = aViewport.offsetX;
this.viewportExcess.x = excessX; this.viewportExcess.x = excessX;
transformChanged = true;
} }
if ((aViewport.offsetY != this._viewport.offsetY) || if ((aViewport.offsetY != this._viewport.offsetY) ||
(excessY != this.viewportExcess.y)) { (excessY != this.viewportExcess.y)) {
this._viewport.offsetY = aViewport.offsetY; this._viewport.offsetY = aViewport.offsetY;
this.viewportExcess.y = excessY; this.viewportExcess.y = excessY;
transformChanged = true;
} }
if (Math.abs(aViewport.zoom - this._viewport.zoom) >= 1e-6) { if (Math.abs(aViewport.zoom - this._viewport.zoom) >= 1e-6) {
this._viewport.zoom = aViewport.zoom; this._viewport.zoom = aViewport.zoom;
transformChanged = true;
} }
if (transformChanged)
this.updateTransform();
}, },
screenshot: function(aSrc, aDst) { screenshot: function(aSrc, aDst) {
@ -1619,20 +1617,6 @@ Tab.prototype = {
}, Ci.nsIThread.DISPATCH_NORMAL); }, Ci.nsIThread.DISPATCH_NORMAL);
}, },
updateTransform: function() {
let hasZoom = (Math.abs(this._viewport.zoom - 1.0) >= 1e-6);
let x = this._viewport.offsetX + Math.round(-this.viewportExcess.x * this._viewport.zoom);
let y = this._viewport.offsetY + Math.round(-this.viewportExcess.y * this._viewport.zoom);
let transform =
"translate(" + x + "px, " +
y + "px)";
if (hasZoom)
transform += " scale(" + this._viewport.zoom + ")";
this.browser.style.MozTransform = transform;
},
get viewport() { get viewport() {
// Update the viewport to current dimensions // Update the viewport to current dimensions
this._viewport.x = (this.browser.contentWindow.scrollX + this._viewport.x = (this.browser.contentWindow.scrollX +
@ -1747,6 +1731,14 @@ Tab.prototype = {
if (this._pluginCount && !this._pluginOverlayShowing) if (this._pluginCount && !this._pluginOverlayShowing)
PluginHelper.showDoorHanger(this); PluginHelper.showDoorHanger(this);
// FIXME: This should not be in DOMContentLoaded; it should happen earlier.
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
cwu.setDisplayPortForElement(-kBufferAmount, -kBufferAmount,
gScreenWidth + kBufferAmount * 2,
gScreenHeight + kBufferAmount * 2,
this.browser.contentDocument.documentElement);
break; break;
} }
@ -2068,7 +2060,7 @@ Tab.prototype = {
let minScale = this.getPageZoomLevel(screenW); let minScale = this.getPageZoomLevel(screenW);
viewportH = Math.max(viewportH, screenH / minScale); viewportH = Math.max(viewportH, screenH / minScale);
let oldBrowserWidth = parseInt(this.browser.style.width); let oldBrowserWidth = gBrowserWidth;
this.setBrowserSize(viewportW, viewportH); this.setBrowserSize(viewportW, viewportH);
// Avoid having the scroll position jump around after device rotation. // Avoid having the scroll position jump around after device rotation.
@ -2079,7 +2071,7 @@ Tab.prototype = {
// If the browser width changes, we change the zoom proportionally. This ensures sensible // If the browser width changes, we change the zoom proportionally. This ensures sensible
// behavior when rotating the device on pages with automatically-resizing viewports. // behavior when rotating the device on pages with automatically-resizing viewports.
if (viewportW == oldBrowserWidth) if (oldBrowserWidth == null || viewportW == oldBrowserWidth)
return; return;
let viewport = this.viewport; let viewport = this.viewport;
@ -2092,9 +2084,8 @@ Tab.prototype = {
if ("defaultZoom" in md && md.defaultZoom) if ("defaultZoom" in md && md.defaultZoom)
return md.defaultZoom; return md.defaultZoom;
let browserWidth = parseInt(this.browser.style.width);
dump("### getDefaultZoomLevel gScreenWidth=" + gScreenWidth); dump("### getDefaultZoomLevel gScreenWidth=" + gScreenWidth);
return gScreenWidth / browserWidth; return gScreenWidth / gBrowserWidth;
}, },
getPageZoomLevel: function getPageZoomLevel() { getPageZoomLevel: function getPageZoomLevel() {
@ -2107,8 +2098,8 @@ Tab.prototype = {
}, },
setBrowserSize: function(aWidth, aHeight) { setBrowserSize: function(aWidth, aHeight) {
this.browser.style.width = aWidth + "px"; // TODO: Use nsIDOMWindowUtils::SetCSSViewport() here.
this.browser.style.height = aHeight + "px"; gBrowserWidth = aWidth;
}, },
getRequestLoadContext: function(aRequest) { getRequestLoadContext: function(aRequest) {