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:
Chris Lord 2011-11-30 17:27:13 +00:00
Родитель e2a9da84a1
Коммит dc4c4696ff
7 изменённых файлов: 80 добавлений и 9 удалений

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

@ -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);
}