зеркало из https://github.com/mozilla/gecko-dev.git
Bug 705171 - Render when necessary, instead of continuously. r=kats,pcwalton
Set the render mode to RENDERMODE_WHEN_DIRTY and request a redraw when a layer transaction ends and when the viewport in LayerController changes. This stops us from drawing continuously.
This commit is contained in:
Родитель
e2a9da84a1
Коммит
dc4c4696ff
|
@ -124,7 +124,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
}
|
||||
|
||||
public void beginDrawing() {
|
||||
mTileLayer.beginTransaction();
|
||||
beginTransaction(mTileLayer);
|
||||
}
|
||||
|
||||
private void updateViewport(String viewportDescription, final boolean onlyUpdatePageSize) {
|
||||
|
@ -169,7 +169,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
Rect rect = new Rect(x, y, x + width, y + height);
|
||||
mTileLayer.invalidate(rect);
|
||||
} finally {
|
||||
mTileLayer.endTransaction();
|
||||
endTransaction(mTileLayer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,13 +264,13 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
if ("Viewport:Update".equals(event)) {
|
||||
mTileLayer.beginTransaction();
|
||||
beginTransaction(mTileLayer);
|
||||
try {
|
||||
updateViewport(message.getString("viewport"), false);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Unable to update viewport", e);
|
||||
} finally {
|
||||
mTileLayer.endTransaction();
|
||||
endTransaction(mTileLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ public abstract class Layer {
|
|||
private Point mNewOrigin;
|
||||
private float mResolution;
|
||||
private float mNewResolution;
|
||||
private LayerView mView;
|
||||
|
||||
public Layer() {
|
||||
mTransactionLock = new ReentrantLock();
|
||||
|
@ -95,20 +96,28 @@ public abstract class Layer {
|
|||
*
|
||||
* This function may block, so you should never call this on the main UI thread.
|
||||
*/
|
||||
public void beginTransaction() {
|
||||
public void beginTransaction(LayerView aView) {
|
||||
if (mTransactionLock.isHeldByCurrentThread())
|
||||
throw new RuntimeException("Nested transactions are not supported");
|
||||
mTransactionLock.lock();
|
||||
mView = aView;
|
||||
mInTransaction = true;
|
||||
mNewResolution = mResolution;
|
||||
}
|
||||
|
||||
public void beginTransaction() {
|
||||
beginTransaction(null);
|
||||
}
|
||||
|
||||
/** Call this when you're done modifying the layer. */
|
||||
public void endTransaction() {
|
||||
if (!mInTransaction)
|
||||
throw new RuntimeException("endTransaction() called outside a transaction");
|
||||
mInTransaction = false;
|
||||
mTransactionLock.unlock();
|
||||
|
||||
if (mView != null)
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Returns true if the layer is currently in a transaction and false otherwise. */
|
||||
|
|
|
@ -50,5 +50,26 @@ public abstract class LayerClient {
|
|||
public void setLayerController(LayerController layerController) {
|
||||
mLayerController = layerController;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility function for calling TileLayer.beginTransaction with the
|
||||
* appropriate LayerView.
|
||||
*/
|
||||
public void beginTransaction(TileLayer aTileLayer) {
|
||||
if (mLayerController != null) {
|
||||
LayerView view = mLayerController.getView();
|
||||
if (view != null) {
|
||||
aTileLayer.beginTransaction(view);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aTileLayer.beginTransaction();
|
||||
}
|
||||
|
||||
// Included for symmetry.
|
||||
public void endTransaction(TileLayer aTileLayer) {
|
||||
aTileLayer.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,7 @@ public class LayerController {
|
|||
|
||||
notifyLayerClientOfGeometryChange();
|
||||
mPanZoomController.geometryChanged();
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public void scrollTo(PointF point) {
|
||||
|
@ -171,6 +172,7 @@ public class LayerController {
|
|||
notifyLayerClientOfGeometryChange();
|
||||
mPanZoomController.geometryChanged();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public void scrollBy(PointF point) {
|
||||
|
@ -181,6 +183,7 @@ public class LayerController {
|
|||
notifyLayerClientOfGeometryChange();
|
||||
mPanZoomController.geometryChanged();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public void setViewport(RectF viewport) {
|
||||
|
@ -188,6 +191,7 @@ public class LayerController {
|
|||
notifyLayerClientOfGeometryChange();
|
||||
mPanZoomController.geometryChanged();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public void setPageSize(FloatSize size) {
|
||||
|
@ -199,6 +203,7 @@ public class LayerController {
|
|||
// Page size is owned by the LayerClient, so no need to notify it of
|
||||
// this change.
|
||||
mPanZoomController.geometryChanged();
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public void setViewportMetrics(ViewportMetrics viewport) {
|
||||
|
@ -208,6 +213,7 @@ public class LayerController {
|
|||
// size), so no need to notify it of this change.
|
||||
mPanZoomController.geometryChanged();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public void scaleTo(float zoomFactor, PointF focus) {
|
||||
|
@ -217,6 +223,7 @@ public class LayerController {
|
|||
// PanZoomController, so no need to notify it of this change.
|
||||
notifyLayerClientOfGeometryChange();
|
||||
GeckoApp.mAppContext.repositionPluginViews(false);
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
public boolean post(Runnable action) { return mView.post(action); }
|
||||
|
|
|
@ -77,6 +77,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
|
||||
// FPS display
|
||||
private long mFrameCountTimestamp;
|
||||
private long mFrameTime;
|
||||
private int mFrameCount; // number of frames since last timestamp
|
||||
|
||||
public LayerRenderer(LayerView view) {
|
||||
|
@ -225,9 +226,17 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
}
|
||||
|
||||
private void checkFPS() {
|
||||
mFrameTime += mView.getRenderTime();
|
||||
mFrameCount ++;
|
||||
|
||||
if (System.currentTimeMillis() >= mFrameCountTimestamp + 1000) {
|
||||
mFrameCountTimestamp = System.currentTimeMillis();
|
||||
|
||||
// Extrapolate FPS based on time taken by frames drawn.
|
||||
// XXX This doesn't take into account the vblank, so the FPS
|
||||
// can show higher than it actually is.
|
||||
mFrameCount = (int)(mFrameCount * 1000000000L / mFrameTime);
|
||||
|
||||
mFPSLayer.beginTransaction();
|
||||
try {
|
||||
mFPSLayer.setText(mFrameCount + " FPS");
|
||||
|
@ -236,8 +245,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
}
|
||||
|
||||
mFrameCount = 0;
|
||||
} else {
|
||||
mFrameCount++;
|
||||
mFrameTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,8 @@ public class LayerView extends GLSurfaceView {
|
|||
private LayerRenderer mRenderer;
|
||||
private GestureDetector mGestureDetector;
|
||||
private ScaleGestureDetector mScaleGestureDetector;
|
||||
private long mRenderTime;
|
||||
private boolean mRenderTimeReset;
|
||||
|
||||
public LayerView(Context context, LayerController controller) {
|
||||
super(context);
|
||||
|
@ -70,6 +72,7 @@ public class LayerView extends GLSurfaceView {
|
|||
mController = controller;
|
||||
mRenderer = new LayerRenderer(this);
|
||||
setRenderer(mRenderer);
|
||||
setRenderMode(RENDERMODE_WHEN_DIRTY);
|
||||
mGestureDetector = new GestureDetector(context, controller.getGestureListener());
|
||||
mScaleGestureDetector = new ScaleGestureDetector(context, controller.getScaleGestureListener());
|
||||
mInputConnectionHandler = null;
|
||||
|
@ -140,5 +143,28 @@ public class LayerView extends GLSurfaceView {
|
|||
return mInputConnectionHandler.onKeyUp(keyCode, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestRender() {
|
||||
super.requestRender();
|
||||
|
||||
synchronized(this) {
|
||||
if (!mRenderTimeReset) {
|
||||
mRenderTimeReset = true;
|
||||
mRenderTime = System.nanoTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time elapsed between the first call of requestRender() after
|
||||
* the last call of getRenderTime(), in nanoseconds.
|
||||
*/
|
||||
public long getRenderTime() {
|
||||
synchronized(this) {
|
||||
mRenderTimeReset = false;
|
||||
return System.nanoTime() - mRenderTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,9 +136,9 @@ public class PlaceholderLayerClient extends LayerClient {
|
|||
BufferedCairoImage image = new BufferedCairoImage(mBuffer, mWidth, mHeight, mFormat);
|
||||
SingleTileLayer tileLayer = new SingleTileLayer(image);
|
||||
|
||||
tileLayer.beginTransaction();
|
||||
beginTransaction(tileLayer);
|
||||
tileLayer.setOrigin(PointUtils.round(mViewport.getDisplayportOrigin()));
|
||||
tileLayer.endTransaction();
|
||||
endTransaction(tileLayer);
|
||||
|
||||
getLayerController().setRoot(tileLayer);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче