Bug 839641 - Add a syncFrameMetrics code path to push viewport changes from APZC to Java. r=Cwiiis, BenWa

This commit is contained in:
Kartikaya Gupta 2013-04-26 13:26:39 -04:00
parent 59ba0d1140
commit ec0ecf5c78
10 changed files with 116 additions and 4 deletions

View File

@ -1112,7 +1112,8 @@ AsyncPanZoomController::FireAsyncScrollOnTimeout()
bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ContainerLayer* aLayer,
ViewTransform* aNewTransform) {
ViewTransform* aNewTransform,
gfxPoint* aScrollOffset) {
// The eventual return value of this function. The compositor needs to know
// whether or not to advance by a frame as soon as it can. For example, if a
// fling is happening, it has to keep compositing so that the animation is
@ -1221,6 +1222,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
gfxPoint scrollCompensation(
(scrollOffset / rootScale - metricsScrollOffset) * localScale);
*aNewTransform = ViewTransform(-scrollCompensation, localScale);
*aScrollOffset = scrollOffset * localScale;
mLastSampleTime = aSampleTime;

View File

@ -177,7 +177,8 @@ public:
*/
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ContainerLayer* aLayer,
ViewTransform* aTransform);
ViewTransform* aNewTransform,
gfxPoint* aScrollOffset);
/**
* A shadow layer update has arrived. |aViewportFrame| is the new FrameMetrics

View File

@ -846,10 +846,22 @@ CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
LayerComposite* layerComposite = aLayer->AsLayerComposite();
ViewTransform treeTransform;
gfxPoint scrollOffset;
*aWantNextFrame |=
controller->SampleContentTransformForFrame(aCurrentFrame,
container,
&treeTransform);
&treeTransform,
&scrollOffset);
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
float offsetX = 0, offsetY = 0;
SyncFrameMetrics(aLayer, treeTransform, scrollOffset, fixedLayerMargins,
offsetX, offsetY, mIsFirstPaint, mLayersUpdated);
mIsFirstPaint = false;
mLayersUpdated = false;
// Apply the render offset
mLayerManager->GetCompositor()->SetScreenRenderOffset(gfx::Point(offsetX, offsetY));
gfx3DMatrix transform(gfx3DMatrix(treeTransform) * aLayer->GetTransform());
// The transform already takes the resolution scale into account. Since we
@ -863,7 +875,6 @@ CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
1);
layerComposite->SetShadowTransform(transform);
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
TransformFixedLayers(
aLayer,
-treeTransform.mTranslation / treeTransform.mScale,

View File

@ -181,6 +181,12 @@ protected:
virtual void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
virtual void SyncFrameMetrics(Layer* aLayer, const ViewTransform& aTreeTransform,
const gfxPoint& aScrollOffset, gfx::Margin& aFixedLayerMargins,
float& aOffsetX, float& aOffsetY,
bool aIsFirstPaint, bool aLayersUpdated) {
}
void SetEGLSurfaceSize(int width, int height);
private:

View File

@ -657,6 +657,21 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return mCurrentViewTransform;
}
/* Invoked by JNI from the compositor thread */
public ViewTransform syncFrameMetrics(float offsetX, float offsetY, float zoom,
float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom,
boolean layersUpdated, int x, int y, int width, int height, float resolution,
boolean isFirstPaint)
{
if (isFirstPaint) {
RectF pageRect = RectUtils.scale(new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom), zoom);
setFirstPaintViewport(offsetX, offsetY, zoom, pageRect.left, pageRect.top, pageRect.right,
pageRect.bottom, cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
}
return syncViewportInfo(x, y, width, height, resolution, layersUpdated);
}
/** This function is invoked by Gecko via JNI; be careful when modifying signature. */
public LayerRenderer.Frame createFrame() {
// Create the shaders and textures if necessary.

View File

@ -2120,6 +2120,19 @@ AndroidBridge::SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayRes
aOffsetX, aOffsetY);
}
void AndroidBridge::SyncFrameMetrics(const gfx::Point& aOffset, float aZoom, const gfx::Rect& aCssPageRect,
bool aLayersUpdated, const gfx::Rect& aDisplayPort, float aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
return;
client->SyncFrameMetrics(aOffset, aZoom, aCssPageRect,
aLayersUpdated, aDisplayPort, aDisplayResolution,
aIsFirstPaint, aFixedLayerMargins, aOffsetX, aOffsetY);
}
AndroidBridge::AndroidBridge()
: mLayerClient(NULL),
mNativePanZoomController(NULL)

View File

@ -344,6 +344,9 @@ public:
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
void SyncFrameMetrics(const gfx::Point& aOffset, float aZoom, const gfx::Rect& aCssPageRect,
bool aLayersUpdated, const gfx::Rect& aDisplayPort, float aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
void AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen);
void RemovePluginView(jobject view, bool isFullScreen);

View File

@ -89,6 +89,7 @@ jclass AndroidGeckoLayerClient::jDisplayportClass = 0;
jmethodID AndroidGeckoLayerClient::jSetFirstPaintViewport = 0;
jmethodID AndroidGeckoLayerClient::jSetPageRect = 0;
jmethodID AndroidGeckoLayerClient::jSyncViewportInfoMethod = 0;
jmethodID AndroidGeckoLayerClient::jSyncFrameMetricsMethod = 0;
jmethodID AndroidGeckoLayerClient::jCreateFrameMethod = 0;
jmethodID AndroidGeckoLayerClient::jActivateProgramMethod = 0;
jmethodID AndroidGeckoLayerClient::jDeactivateProgramMethod = 0;
@ -349,6 +350,8 @@ AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv)
jSetPageRect = getMethod("setPageRect", "(FFFF)V");
jSyncViewportInfoMethod = getMethod("syncViewportInfo",
"(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
jSyncFrameMetricsMethod = getMethod("syncFrameMetrics",
"(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
jActivateProgramMethod = getMethod("activateProgram", "()V");
jDeactivateProgramMethod = getMethod("deactivateProgram", "()V");
@ -911,6 +914,42 @@ AndroidGeckoLayerClient::SyncViewportInfo(const nsIntRect& aDisplayPort, float a
aOffsetY = viewTransform.GetOffsetY(env);
}
void
AndroidGeckoLayerClient::SyncFrameMetrics(const gfx::Point& aOffset, float aZoom, const gfx::Rect& aCssPageRect,
bool aLayersUpdated, const gfx::Rect& aDisplayPort, float aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY)
{
NS_ASSERTION(!isNull(), "SyncFrameMetrics called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
if (!env)
return;
AutoLocalJNIFrame jniFrame(env);
// convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels
int dpX = NS_lround((aDisplayPort.x * aDisplayResolution) + aOffset.x);
int dpY = NS_lround((aDisplayPort.y * aDisplayResolution) + aOffset.y);
int dpW = NS_lround(aDisplayPort.width * aDisplayResolution);
int dpH = NS_lround(aDisplayPort.height * aDisplayResolution);
jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncFrameMetricsMethod,
aOffset.x, aOffset.y, aZoom,
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(),
aLayersUpdated, dpX, dpY, dpW, dpH, aDisplayResolution,
aIsFirstPaint);
if (jniFrame.CheckForException())
return;
NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!");
AndroidViewTransform viewTransform;
viewTransform.Init(viewTransformJObj);
viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins);
aOffsetX = viewTransform.GetOffsetX(env);
aOffsetY = viewTransform.GetOffsetY(env);
}
bool
AndroidGeckoLayerClient::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
const gfx::Rect& aDisplayPort,

View File

@ -272,6 +272,9 @@ public:
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
void SyncFrameMetrics(const gfx::Point& aOffset, float aZoom, const gfx::Rect& aCssPageRect,
bool aLayersUpdated, const gfx::Rect& aDisplayPort, float aDisplayResolution,
bool aIsFirstPaint, gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const gfx::Rect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY);
bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
bool ActivateProgram(AutoLocalJNIFrame *jniFrame);
@ -283,6 +286,7 @@ protected:
static jmethodID jSetFirstPaintViewport;
static jmethodID jSetPageRect;
static jmethodID jSyncViewportInfoMethod;
static jmethodID jSyncFrameMetricsMethod;
static jmethodID jCreateFrameMethod;
static jmethodID jActivateProgramMethod;
static jmethodID jDeactivateProgramMethod;

View File

@ -2491,6 +2491,24 @@ public:
controller->NotifyLayersUpdated(targetLayer->AsContainerLayer()->GetFrameMetrics(), isFirstPaint);
}
}
virtual void SyncFrameMetrics(Layer* aLayer, const ViewTransform& aTreeTransform,
const gfxPoint& aScrollOffset, mozilla::gfx::Margin& aFixedLayerMargins,
float& aOffsetX, float& aOffsetY,
bool aIsFirstPaint, bool aLayersUpdated) MOZ_OVERRIDE
{
const gfx3DMatrix& rootTransform = GetLayerManager()->GetRoot()->GetTransform();
ContainerLayer* container = aLayer->AsContainerLayer();
const FrameMetrics& metrics = container->GetFrameMetrics();
mozilla::gfx::Rect displayPortLayersPixels(metrics.mCriticalDisplayPort.IsEmpty() ?
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
mozilla::gfx::Point scrollOffset(aScrollOffset.x, aScrollOffset.y);
AndroidBridge::Bridge()->SyncFrameMetrics(scrollOffset, aTreeTransform.mScale.width, metrics.mScrollableRect,
aLayersUpdated, displayPortLayersPixels, 1 / rootTransform.GetXScale(),
aIsFirstPaint, aFixedLayerMargins, aOffsetX, aOffsetY);
}
};
CompositorParent*