115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2009 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
174c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornpackage com.android.internal.view;
184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.graphics.Canvas;
204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.graphics.PixelFormat;
214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.graphics.Rect;
224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.SystemClock;
234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.util.Log;
244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.Surface;
254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.SurfaceHolder;
264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.ArrayList;
284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.concurrent.locks.ReentrantLock;
294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornpublic abstract class BaseSurfaceHolder implements SurfaceHolder {
314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    private static final String TAG = "BaseSurfaceHolder";
324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    static final boolean DEBUG = false;
334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public final ArrayList<SurfaceHolder.Callback> mCallbacks
354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            = new ArrayList<SurfaceHolder.Callback>();
36dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    SurfaceHolder.Callback[] mGottenCallbacks;
37dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    boolean mHaveGottenCallbacks;
38dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn
394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public final ReentrantLock mSurfaceLock = new ReentrantLock();
40dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    public Surface mSurface = new Surface();
414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mRequestedWidth = -1;
434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mRequestedHeight = -1;
4462bf4a0283e855e2fb5f40f36909501e5b4a09ebMathias Agopian    /** @hide */
4562bf4a0283e855e2fb5f40f36909501e5b4a09ebMathias Agopian    protected int mRequestedFormat = PixelFormat.OPAQUE;
464c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mRequestedType = -1;
474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    long mLastLockTime = 0;
494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mType = -1;
514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final Rect mSurfaceFrame = new Rect();
5230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    Rect mTmpDirty;
534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public abstract void onUpdateSurface();
554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public abstract void onRelayoutContainer();
564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public abstract boolean onAllowLockCanvas();
574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public int getRequestedWidth() {
594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return mRequestedWidth;
604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public int getRequestedHeight() {
634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return mRequestedHeight;
644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public int getRequestedFormat() {
674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return mRequestedFormat;
684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public int getRequestedType() {
714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return mRequestedType;
724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
744c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void addCallback(Callback callback) {
754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        synchronized (mCallbacks) {
764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            // This is a linear search, but in practice we'll
774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            // have only a couple callbacks, so it doesn't matter.
784c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            if (mCallbacks.contains(callback) == false) {
794c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mCallbacks.add(callback);
804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
814c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
824c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
834c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
844c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void removeCallback(Callback callback) {
854c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        synchronized (mCallbacks) {
864c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mCallbacks.remove(callback);
874c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
884c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
8925cfa134835e3791bdb6572f5e25cf4599015678Robert Carr
90dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    public SurfaceHolder.Callback[] getCallbacks() {
91dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn        if (mHaveGottenCallbacks) {
92dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn            return mGottenCallbacks;
93dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn        }
94dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn
95dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn        synchronized (mCallbacks) {
96dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn            final int N = mCallbacks.size();
97dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn            if (N > 0) {
98dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn                if (mGottenCallbacks == null || mGottenCallbacks.length != N) {
99dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn                    mGottenCallbacks = new SurfaceHolder.Callback[N];
100dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn                }
101dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn                mCallbacks.toArray(mGottenCallbacks);
102dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn            } else {
103dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn                mGottenCallbacks = null;
104dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn            }
105dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn            mHaveGottenCallbacks = true;
106dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn        }
107dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn
108dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn        return mGottenCallbacks;
109dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    }
110dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn
111dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    public void ungetCallbacks() {
112dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn        mHaveGottenCallbacks = false;
113dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn    }
114dc8a7f69d7df5f1ca29763995a0d55acf7936fc6Dianne Hackborn
1154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setFixedSize(int width, int height) {
1164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (mRequestedWidth != width || mRequestedHeight != height) {
1174c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mRequestedWidth = width;
1184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mRequestedHeight = height;
1194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            onRelayoutContainer();
1204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setSizeFromLayout() {
1244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (mRequestedWidth != -1 || mRequestedHeight != -1) {
1254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mRequestedWidth = mRequestedHeight = -1;
1264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            onRelayoutContainer();
1274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setFormat(int format) {
1314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (mRequestedFormat != format) {
1324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mRequestedFormat = format;
1334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            onUpdateSurface();
1344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setType(int type) {
1384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        switch (type) {
1394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        case SURFACE_TYPE_HARDWARE:
1404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        case SURFACE_TYPE_GPU:
141317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            // these are deprecated, treat as "NORMAL"
142317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            type = SURFACE_TYPE_NORMAL;
143317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            break;
144317a6280cc109e873646e4652be1582d870eedfdMathias Agopian        }
145317a6280cc109e873646e4652be1582d870eedfdMathias Agopian        switch (type) {
146317a6280cc109e873646e4652be1582d870eedfdMathias Agopian        case SURFACE_TYPE_NORMAL:
1474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        case SURFACE_TYPE_PUSH_BUFFERS:
1484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            if (mRequestedType != type) {
1494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mRequestedType = type;
1504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                onUpdateSurface();
1514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            break;
1534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1566bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck    @Override
1574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public Canvas lockCanvas() {
1586bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck        return internalLockCanvas(null, false);
1594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1616bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck    @Override
1624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public Canvas lockCanvas(Rect dirty) {
1636bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck        return internalLockCanvas(dirty, false);
1644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1666bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck    @Override
1676bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck    public Canvas lockHardwareCanvas() {
1686bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck        return internalLockCanvas(null, true);
1696bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck    }
1706bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck
1716bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck    private final Canvas internalLockCanvas(Rect dirty, boolean hardware) {
1724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
1734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            throw new BadSurfaceTypeException(
1744c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
1754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mSurfaceLock.lock();
1774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1784c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (DEBUG) Log.i(TAG, "Locking canvas..,");
1794c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        Canvas c = null;
1814c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (onAllowLockCanvas()) {
18230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown            if (dirty == null) {
18330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown                if (mTmpDirty == null) {
18430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown                    mTmpDirty = new Rect();
18530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown                }
18630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown                mTmpDirty.set(mSurfaceFrame);
18730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown                dirty = mTmpDirty;
18830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown            }
18930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown
1904c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            try {
1916bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck                if (hardware) {
1926bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck                    c = mSurface.lockHardwareCanvas();
1936bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck                } else {
1946bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck                    c = mSurface.lockCanvas(dirty);
1956bc701421047bf881ee16c49b242ea19ae4cd9b9John Reck                }
1964c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            } catch (Exception e) {
1974c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                Log.e(TAG, "Exception locking surface", e);
1984c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1994c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2004c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
2014c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (DEBUG) Log.i(TAG, "Returned canvas: " + c);
2024c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (c != null) {
2034c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mLastLockTime = SystemClock.uptimeMillis();
2044c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            return c;
2054c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2064c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
2074c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        // If the Surface is not ready to be drawn, then return null,
2084c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        // but throttle calls to this function so it isn't called more
2094c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        // than every 100ms.
2104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        long now = SystemClock.uptimeMillis();
2114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        long nextTime = mLastLockTime + 100;
2124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (nextTime > now) {
2134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            try {
2144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                Thread.sleep(nextTime-now);
2154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            } catch (InterruptedException e) {
2164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2174c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            now = SystemClock.uptimeMillis();
2184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mLastLockTime = now;
2204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mSurfaceLock.unlock();
2214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
2224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return null;
2234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
2244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
2254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void unlockCanvasAndPost(Canvas canvas) {
2264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mSurface.unlockCanvasAndPost(canvas);
2274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mSurfaceLock.unlock();
2284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
2294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
2304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public Surface getSurface() {
2314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return mSurface;
2324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
2334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
2344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public Rect getSurfaceFrame() {
2354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return mSurfaceFrame;
2364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
23730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown
23830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    public void setSurfaceFrameSize(int width, int height) {
23930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown        mSurfaceFrame.top = 0;
24030bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown        mSurfaceFrame.left = 0;
24130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown        mSurfaceFrame.right = width;
24230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown        mSurfaceFrame.bottom = height;
24330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown    }
2444c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn};
245