Bug 716403 - Offset fixed layers so the toolbar doesn't obscure them. r=nrc,kats

Offset fixed layers in the compositor so that the toolbar in Firefox for Android
doesn't obscure them. This does not affect layout, so input on the elements in
said layers will appear broken.
This commit is contained in:
Chris Lord 2013-03-07 10:17:33 +00:00
parent c733a1eca6
commit 792e39c1fd
11 changed files with 173 additions and 17 deletions

View File

@ -640,7 +640,8 @@ Translate2D(gfx3DMatrix& aTransform, const gfxPoint& aOffset)
void
CompositorParent::TransformFixedLayers(Layer* aLayer,
const gfxPoint& aTranslation,
const gfxSize& aScaleDiff)
const gfxSize& aScaleDiff,
const gfx::Margin& aFixedLayerMargins)
{
if (aLayer->GetIsFixedPosition() &&
!aLayer->GetParent()->GetIsFixedPosition()) {
@ -650,6 +651,20 @@ CompositorParent::TransformFixedLayers(Layer* aLayer,
const gfxPoint& anchor = aLayer->GetFixedPositionAnchor();
gfxPoint translation(aTranslation - (anchor - anchor / aScaleDiff));
// Offset this translation by the fixed layer margins, depending on what
// side of the viewport the layer is anchored to.
if (anchor.x > 0) {
translation.x -= aFixedLayerMargins.right;
} else {
translation.x += aFixedLayerMargins.left;
}
if (anchor.y > 0) {
translation.y -= aFixedLayerMargins.bottom;
} else {
translation.y += aFixedLayerMargins.top;
}
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
@ -676,7 +691,7 @@ CompositorParent::TransformFixedLayers(Layer* aLayer,
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
TransformFixedLayers(child, aTranslation, aScaleDiff);
TransformFixedLayers(child, aTranslation, aScaleDiff, aFixedLayerMargins);
}
}
@ -869,10 +884,12 @@ CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
1);
shadow->SetShadowTransform(transform);
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
TransformFixedLayers(
aLayer,
-treeTransform.mTranslation / treeTransform.mScale,
treeTransform.mScale);
treeTransform.mScale,
fixedLayerMargins);
appliedTransform = true;
}
@ -937,8 +954,9 @@ CompositorParent::TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRo
displayPortDevPixels.x += scrollOffsetDevPixels.x;
displayPortDevPixels.y += scrollOffsetDevPixels.y;
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
SyncViewportInfo(displayPortDevPixels, 1/rootScaleX, mLayersUpdated,
mScrollOffset, mXScale, mYScale);
mScrollOffset, mXScale, mYScale, fixedLayerMargins);
mLayersUpdated = false;
// Handle transformations for asynchronous panning and zooming. We determine the
@ -995,7 +1013,7 @@ CompositorParent::TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRo
1.0f/container->GetPostYScale(),
1);
shadow->SetShadowTransform(computedTransform);
TransformFixedLayers(aLayer, offset, scaleDiff);
TransformFixedLayers(aLayer, offset, scaleDiff, fixedLayerMargins);
}
bool
@ -1059,11 +1077,12 @@ CompositorParent::SetPageRect(const gfx::Rect& aCssPageRect)
void
CompositorParent::SyncViewportInfo(const nsIntRect& aDisplayPort,
float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY)
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins)
{
#ifdef MOZ_WIDGET_ANDROID
AndroidBridge::Bridge()->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated,
aScrollOffset, aScaleX, aScaleY);
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins);
#endif
}

View File

@ -181,7 +181,8 @@ protected:
virtual void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
virtual void SetPageRect(const gfx::Rect& aCssPageRect);
virtual void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins);
void SetEGLSurfaceSize(int width, int height);
// If SetPanZoomControllerForLayerTree is not set, Compositor will use
// derived class AsyncPanZoomController transformations.
@ -261,7 +262,8 @@ private:
*/
void TransformFixedLayers(Layer* aLayer,
const gfxPoint& aTranslation,
const gfxSize& aScaleDiff);
const gfxSize& aScaleDiff,
const gfx::Margin& aFixedLayerMargins);
virtual PGrallocBufferParent* AllocPGrallocBuffer(
const gfxIntSize&, const uint32_t&, const uint32_t&,

View File

@ -400,6 +400,7 @@ abstract public class BrowserApp extends GeckoApp
mBrowserToolbar.updateBackButton(false);
mBrowserToolbar.updateForwardButton(false);
((BrowserToolbarLayout)mBrowserToolbar.getLayout()).refreshMargins();
mDoorHangerPopup.setAnchor(mBrowserToolbar.mFavicon);

View File

@ -30,5 +30,30 @@ public class BrowserToolbarLayout extends LinearLayout {
return super.onTouchEvent(event);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (t != oldt) {
refreshMargins();
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (h != oldh) {
refreshMargins();
}
}
public void refreshMargins() {
LayerView view = GeckoApp.mAppContext.getLayerView();
if (view != null) {
view.getLayerClient().setFixedLayerMargins(0, getHeight() - getScrollY(), 0, 0);
}
}
}

View File

@ -17,6 +17,7 @@ import org.mozilla.gecko.util.FloatUtils;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.SystemClock;
import android.util.DisplayMetrics;
@ -303,7 +304,8 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
default:
case UPDATE:
// Keep the old viewport size
metrics = messageMetrics.setViewportSize(oldMetrics.getWidth(), oldMetrics.getHeight());
metrics = messageMetrics.setViewportSize(oldMetrics.getWidth(), oldMetrics.getHeight())
.setFixedLayerMarginsFrom(oldMetrics);
if (!oldMetrics.fuzzyEquals(metrics)) {
abortPanZoomAnimation();
}
@ -346,6 +348,15 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
}
}
/**
* Sets margins on fixed-position layers, to be used when compositing.
* Must be called on the UI thread!
*/
public void setFixedLayerMargins(float left, float top, float right, float bottom) {
ImmutableViewportMetrics oldMetrics = getViewportMetrics();
setViewportMetrics(oldMetrics.setFixedLayerMargins(left, top, right, bottom), false);
}
// This is called on the Gecko thread to determine if we're still interested
// in the update of this display-port to continue. We can return true here
// to abort the current update and continue with any subsequent ones. This
@ -536,6 +547,10 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
mCurrentViewTransform.x = mFrameMetrics.viewportRectLeft;
mCurrentViewTransform.y = mFrameMetrics.viewportRectTop;
mCurrentViewTransform.scale = mFrameMetrics.zoomFactor;
mCurrentViewTransform.fixedLayerMarginLeft = mFrameMetrics.fixedLayerMarginLeft;
mCurrentViewTransform.fixedLayerMarginTop = mFrameMetrics.fixedLayerMarginTop;
mCurrentViewTransform.fixedLayerMarginRight = mFrameMetrics.fixedLayerMarginRight;
mCurrentViewTransform.fixedLayerMarginBottom = mFrameMetrics.fixedLayerMarginBottom;
mRootLayer.setPositionAndResolution(x, y, x + width, y + height, resolution);
@ -673,7 +688,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return;
}
ImmutableViewportMetrics m = mViewportMetrics;
BrowserApp.mBrowserToolbar.setShadowVisibility(m.viewportRectTop >= m.pageRectTop);
BrowserApp.mBrowserToolbar.setShadowVisibility(m.viewportRectTop >= m.pageRectTop - m.fixedLayerMarginTop);
}
});
}

View File

@ -32,6 +32,10 @@ public class ImmutableViewportMetrics {
public final float viewportRectTop;
public final float viewportRectRight;
public final float viewportRectBottom;
public final float fixedLayerMarginLeft;
public final float fixedLayerMarginTop;
public final float fixedLayerMarginRight;
public final float fixedLayerMarginBottom;
public final float zoomFactor;
public ImmutableViewportMetrics(DisplayMetrics metrics) {
@ -39,6 +43,7 @@ public class ImmutableViewportMetrics {
viewportRectTop = pageRectTop = cssPageRectTop = 0;
viewportRectRight = pageRectRight = cssPageRectRight = metrics.widthPixels;
viewportRectBottom = pageRectBottom = cssPageRectBottom = metrics.heightPixels;
fixedLayerMarginLeft = fixedLayerMarginTop = fixedLayerMarginRight = fixedLayerMarginBottom = 0;
zoomFactor = 1.0f;
}
@ -47,6 +52,21 @@ public class ImmutableViewportMetrics {
float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight,
float aViewportRectBottom, float aZoomFactor)
{
this(aPageRectLeft, aPageRectTop,
aPageRectRight, aPageRectBottom, aCssPageRectLeft,
aCssPageRectTop, aCssPageRectRight, aCssPageRectBottom,
aViewportRectLeft, aViewportRectTop, aViewportRectRight,
aViewportRectBottom, 0.0f, 0.0f, 0.0f, 0.0f, aZoomFactor);
}
private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight,
float aViewportRectBottom, float aFixedLayerMarginLeft,
float aFixedLayerMarginTop, float aFixedLayerMarginRight,
float aFixedLayerMarginBottom, float aZoomFactor)
{
pageRectLeft = aPageRectLeft;
pageRectTop = aPageRectTop;
@ -60,6 +80,10 @@ public class ImmutableViewportMetrics {
viewportRectTop = aViewportRectTop;
viewportRectRight = aViewportRectRight;
viewportRectBottom = aViewportRectBottom;
fixedLayerMarginLeft = aFixedLayerMarginLeft;
fixedLayerMarginTop = aFixedLayerMarginTop;
fixedLayerMarginRight = aFixedLayerMarginRight;
fixedLayerMarginBottom = aFixedLayerMarginBottom;
zoomFactor = aZoomFactor;
}
@ -125,6 +149,10 @@ public class ImmutableViewportMetrics {
FloatUtils.interpolate(viewportRectTop, to.viewportRectTop, t),
FloatUtils.interpolate(viewportRectRight, to.viewportRectRight, t),
FloatUtils.interpolate(viewportRectBottom, to.viewportRectBottom, t),
FloatUtils.interpolate(fixedLayerMarginLeft, to.fixedLayerMarginLeft, t),
FloatUtils.interpolate(fixedLayerMarginTop, to.fixedLayerMarginTop, t),
FloatUtils.interpolate(fixedLayerMarginRight, to.fixedLayerMarginRight, t),
FloatUtils.interpolate(fixedLayerMarginBottom, to.fixedLayerMarginBottom, t),
FloatUtils.interpolate(zoomFactor, to.zoomFactor, t));
}
@ -133,6 +161,7 @@ public class ImmutableViewportMetrics {
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
viewportRectLeft, viewportRectTop, viewportRectLeft + width, viewportRectTop + height,
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
zoomFactor);
}
@ -141,6 +170,7 @@ public class ImmutableViewportMetrics {
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
newOriginX, newOriginY, newOriginX + getWidth(), newOriginY + getHeight(),
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
zoomFactor);
}
@ -149,6 +179,7 @@ public class ImmutableViewportMetrics {
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
newZoomFactor);
}
@ -161,9 +192,25 @@ public class ImmutableViewportMetrics {
pageRect.left, pageRect.top, pageRect.right, pageRect.bottom,
cssPageRect.left, cssPageRect.top, cssPageRect.right, cssPageRect.bottom,
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
zoomFactor);
}
public ImmutableViewportMetrics setFixedLayerMargins(float left, float top, float right, float bottom) {
return new ImmutableViewportMetrics(
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
left, top, right, bottom, zoomFactor);
}
public ImmutableViewportMetrics setFixedLayerMarginsFrom(ImmutableViewportMetrics fromMetrics) {
return setFixedLayerMargins(fromMetrics.fixedLayerMarginLeft,
fromMetrics.fixedLayerMarginTop,
fromMetrics.fixedLayerMarginRight,
fromMetrics.fixedLayerMarginBottom);
}
/* This will set the zoom factor and re-scale page-size and viewport offset
* accordingly. The given focus will remain at the same point on the screen
* after scaling.
@ -185,6 +232,7 @@ public class ImmutableViewportMetrics {
newPageRectLeft, newPageRectTop, newPageRectRight, newPageRectBottom,
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
origin.x, origin.y, origin.x + getWidth(), origin.y + getHeight(),
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
newZoomFactor);
}
@ -207,6 +255,7 @@ public class ImmutableViewportMetrics {
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
newViewport.left, newViewport.top, newViewport.right, newViewport.bottom,
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
zoomFactor);
}
@ -214,6 +263,10 @@ public class ImmutableViewportMetrics {
// Don't bother checking the pageRectXXX values because they are a product
// of the cssPageRectXXX values and the zoomFactor, except with more rounding
// error. Checking those is both inefficient and can lead to false negatives.
//
// This doesn't return false if the fixed layer margins differ as none
// of the users of this function are interested in the margins in that
// way.
return FloatUtils.fuzzyEquals(cssPageRectLeft, other.cssPageRectLeft)
&& FloatUtils.fuzzyEquals(cssPageRectTop, other.cssPageRectTop)
&& FloatUtils.fuzzyEquals(cssPageRectRight, other.cssPageRectRight)
@ -231,6 +284,8 @@ public class ImmutableViewportMetrics {
+ viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + ","
+ pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=("
+ cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + ","
+ cssPageRectBottom + ") z=" + zoomFactor;
+ cssPageRectBottom + ") m=(" + fixedLayerMarginLeft + ","
+ fixedLayerMarginTop + "," + fixedLayerMarginRight + ","
+ fixedLayerMarginBottom + ") z=" + zoomFactor;
}
}

View File

@ -9,11 +9,19 @@ public class ViewTransform {
public float x;
public float y;
public float scale;
public float fixedLayerMarginLeft;
public float fixedLayerMarginTop;
public float fixedLayerMarginRight;
public float fixedLayerMarginBottom;
public ViewTransform(float inX, float inY, float inScale) {
x = inX;
y = inY;
scale = inScale;
fixedLayerMarginLeft = 0;
fixedLayerMarginTop = 0;
fixedLayerMarginRight = 0;
fixedLayerMarginBottom = 0;
}
}

View File

@ -2110,13 +2110,15 @@ AndroidBridge::SetPageRect(const gfx::Rect& aCssPageRect)
void
AndroidBridge::SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY)
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins)
{
AndroidGeckoLayerClient *client = mLayerClient;
if (!client)
return;
client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated, aScrollOffset, aScaleX, aScaleY);
client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated,
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins);
}
AndroidBridge::AndroidBridge()

View File

@ -332,7 +332,8 @@ public:
void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
void SetPageRect(const gfx::Rect& aCssPageRect);
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins);
void AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen);
void RemovePluginView(jobject view, bool isFullScreen);

View File

@ -100,6 +100,10 @@ jclass AndroidViewTransform::jViewTransformClass = 0;
jfieldID AndroidViewTransform::jXField = 0;
jfieldID AndroidViewTransform::jYField = 0;
jfieldID AndroidViewTransform::jScaleField = 0;
jfieldID AndroidViewTransform::jFixedLayerMarginLeft = 0;
jfieldID AndroidViewTransform::jFixedLayerMarginTop = 0;
jfieldID AndroidViewTransform::jFixedLayerMarginRight = 0;
jfieldID AndroidViewTransform::jFixedLayerMarginBottom = 0;
jclass AndroidProgressiveUpdateData::jProgressiveUpdateDataClass = 0;
jfieldID AndroidProgressiveUpdateData::jXField = 0;
@ -365,6 +369,10 @@ AndroidViewTransform::InitViewTransformClass(JNIEnv *jEnv)
jXField = getField("x", "F");
jYField = getField("y", "F");
jScaleField = getField("scale", "F");
jFixedLayerMarginLeft = getField("fixedLayerMarginLeft", "F");
jFixedLayerMarginTop = getField("fixedLayerMarginTop", "F");
jFixedLayerMarginRight = getField("fixedLayerMarginRight", "F");
jFixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F");
}
void
@ -739,7 +747,8 @@ AndroidGeckoLayerClient::SetPageRect(const gfx::Rect& aCssPageRect)
void
AndroidGeckoLayerClient::SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY)
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins)
{
NS_ASSERTION(!isNull(), "SyncViewportInfo called on null layer client!");
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
@ -762,6 +771,7 @@ AndroidGeckoLayerClient::SyncViewportInfo(const nsIntRect& aDisplayPort, float a
aScrollOffset = nsIntPoint(viewTransform.GetX(env), viewTransform.GetY(env));
aScaleX = aScaleY = viewTransform.GetScale(env);
viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins);
}
bool
@ -996,6 +1006,18 @@ AndroidViewTransform::GetScale(JNIEnv *env)
return env->GetFloatField(wrapped_obj, jScaleField);
}
void
AndroidViewTransform::GetFixedLayerMargins(JNIEnv *env, gfx::Margin &aFixedLayerMargins)
{
if (!env)
return;
aFixedLayerMargins.top = env->GetFloatField(wrapped_obj, jFixedLayerMarginTop);
aFixedLayerMargins.right = env->GetFloatField(wrapped_obj, jFixedLayerMarginRight);
aFixedLayerMargins.bottom = env->GetFloatField(wrapped_obj, jFixedLayerMarginBottom);
aFixedLayerMargins.left = env->GetFloatField(wrapped_obj, jFixedLayerMarginLeft);
}
float
AndroidProgressiveUpdateData::GetX(JNIEnv *env)
{

View File

@ -191,12 +191,17 @@ public:
float GetX(JNIEnv *env);
float GetY(JNIEnv *env);
float GetScale(JNIEnv *env);
void GetFixedLayerMargins(JNIEnv *env, gfx::Margin &aFixedLayerMargins);
private:
static jclass jViewTransformClass;
static jfieldID jXField;
static jfieldID jYField;
static jfieldID jScaleField;
static jfieldID jFixedLayerMarginLeft;
static jfieldID jFixedLayerMarginTop;
static jfieldID jFixedLayerMarginRight;
static jfieldID jFixedLayerMarginBottom;
};
class AndroidProgressiveUpdateData : public WrappedJavaObject {
@ -257,7 +262,8 @@ public:
void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
void SetPageRect(const gfx::Rect& aCssPageRect);
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
gfx::Margin& aFixedLayerMargins);
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);