Surface.java revision 8b5aa4846939975adacd6ea1d2a57a2493ac0216
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
200b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Canvas;
210b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Matrix;
220b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Rect;
230b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.SurfaceTexture;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
253866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.os.Parcelable;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
273866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport dalvik.system.CloseGuard;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
30334031cd07c3bd09d23fce0ebaf946fc6ecfee26Glenn Kasten * Handle onto a raw buffer that is being managed by the screen compositor.
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Surface implements Parcelable {
3364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private static final String TAG = "Surface";
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3552800617946c456e78ed010c82d0ec4358368164Mathias Agopian    private static native int nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
3629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            throws OutOfResourcesException;
3752800617946c456e78ed010c82d0ec4358368164Mathias Agopian
3829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private native Canvas nativeLockCanvas(int nativeObject, Rect dirty);
3929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas);
4029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
4129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native void nativeRelease(int nativeObject);
4229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native void nativeDestroy(int nativeObject);
4329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native boolean nativeIsValid(int nativeObject);
4429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native boolean nativeIsConsumerRunningBehind(int nativeObject);
4529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native int nativeCopyFrom(int nativeObject, int surfaceControlNativeObject);
4629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native int nativeReadFromParcel(int nativeObject, Parcel source);
4729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native void nativeWriteToParcel(int nativeObject, Parcel dest);
4829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
4964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static final Parcelable.Creator<Surface> CREATOR =
5064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            new Parcelable.Creator<Surface>() {
5164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface createFromParcel(Parcel source) {
5264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            try {
5364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Surface s = new Surface();
5464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                s.readFromParcel(source);
5564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return s;
5664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } catch (Exception e) {
5764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Log.e(TAG, "Exception creating surface from parcel", e);
5864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return null;
5964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
60b85c933d850286874005f97a9764c9b22e49a597Kevin Hester        }
6164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface[] newArray(int size) {
6264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return new Surface[size];
63df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis        }
6464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    };
65df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis
6664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final CloseGuard mCloseGuard = CloseGuard.get();
6764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private String mName;
68c87c4a3e3b3c3949ae3c6f8fd245b71691d5ca3bMathias Agopian
6964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    // Note: These fields are accessed by native code.
700de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg    // The mSurfaceControl will only be present for Surfaces used by the window
710de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg    // server or system processes. When this class is parceled we defer to the
72b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    // mSurfaceControl to do the parceling. Otherwise we parcel the
73b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    // mNativeSurface.
743866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    int mNativeObject; // package scope only for SurfaceControl access
753866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
7664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private int mGenerationId; // incremented each time mNativeSurface changes
778b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy    @SuppressWarnings("UnusedDeclaration")
7864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final Canvas mCanvas = new CompatibleCanvas();
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
80240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // A matrix to scale the matrix set by application. This is set to null for
81240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // non compatibility mode.
82240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    private Matrix mCompatibleMatrix;
8338ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
8464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
8529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 0 degree rotation (natural orientation)
8629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
8729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_0 = 0;
8829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
8929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
9029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 90 degree rotation.
9129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
9229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_90 = 1;
9329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
9429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
9529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 180 degree rotation.
9629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
9729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_180 = 2;
9829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
9929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
10029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 270 degree rotation.
10129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_270 = 3;
10329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
10564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create an empty surface, which will later be filled in by readFromParcel().
10664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface() {
10964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.open("release");
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create Surface from a {@link SurfaceTexture}.
11464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
11564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Images drawn to the Surface will be made available to the {@link
11664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
11764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture#updateTexImage}.
11864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
11964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
12064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Surface.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface(SurfaceTexture surfaceTexture) {
12364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (surfaceTexture == null) {
12464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("surfaceTexture must not be null");
12564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
12664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
12764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mName = surfaceTexture.toString();
12864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
1293866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = nativeCreateFromSurfaceTexture(surfaceTexture);
13064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        } catch (OutOfResourcesException ex) {
13164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            // We can't throw OutOfResourcesException because it would be an API change.
13264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new RuntimeException(ex);
133f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
13464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
13564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.open("release");
136240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    }
137240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
1383866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    private Surface(int nativeObject) {
1393866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mNativeObject = nativeObject;
1403866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mCloseGuard.open("release");
1413866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
1423866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
14364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
14464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    protected void finalize() throws Throwable {
14564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
14664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCloseGuard != null) {
14764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mCloseGuard.warnIfOpen();
14864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
1493866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            if (mNativeObject != 0) {
1503866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                nativeRelease(mNativeObject);
1513866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
15264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        } finally {
15364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.finalize();
15464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
155b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
156b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
157240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    /**
15864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Release the local reference to the server-side surface.
15964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Always call release() when you're done with a Surface.
16064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This will make the surface invalid.
16164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
16264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void release() {
1633866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject != 0) {
1643866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            nativeRelease(mNativeObject);
1653866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = 0;
1668b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy            mGenerationId++;
1673866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
16864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.close();
16964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
17064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
17164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
17264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Free all server-side state associated with this surface and
17364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * release this object's reference.  This method can only be
17464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * called from the process that created the service.
175b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * @hide
176b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     */
17764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void destroy() {
1783866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject != 0) {
1793866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            nativeDestroy(mNativeObject);
1803866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = 0;
1818b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy            mGenerationId++;
1823866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
18364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.close();
18464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
18561566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
18661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    /**
18764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if this object holds a valid surface.
18864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
18964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if it holds a physical surface, so lockCanvas() will succeed.
19064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Otherwise returns false.
19161566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn     */
19264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isValid() {
1933866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject == 0) return false;
1943866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        return nativeIsValid(mNativeObject);
19564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
19661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
19764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
19864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets the generation number of this surface, incremented each time
19964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the native surface contained within this object changes.
20064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
20164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return The current generation number.
20264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
20364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
204b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    public int getGenerationId() {
20564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return mGenerationId;
206b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
207b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
208c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    /**
20964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if the consumer of this Surface is running behind the producer.
21064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
21164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if the consumer is more than one buffer ahead of the producer.
212c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     * @hide
213c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     */
21464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isConsumerRunningBehind() {
2153866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        checkNotReleased();
2163866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        return nativeIsConsumerRunningBehind(mNativeObject);
21764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
218c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian
219b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    /**
22064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets a {@link Canvas} for drawing into this surface.
22164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
22264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * After drawing into the provided {@link Canvas}, the caller should
22364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
22464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
22530d7ab9a10fcde397bae7bed5f16d1094fded8b2Mathias Agopian     * @param inOutDirty A rectangle that represents the dirty region that the caller wants
22664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to redraw.  This function may choose to expand the dirty rectangle if for example
22764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the surface has been resized or if the previous contents of the surface were
22864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * not available.  The caller should redraw the entire dirty region as represented
22964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the contents of the dirty rect upon return from this function.
23064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * The caller may also pass <code>null</code> instead, in the case where the
23164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * entire surface should be redrawn.
23264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return A canvas for drawing into the surface.
233240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima     */
2343866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public Canvas lockCanvas(Rect inOutDirty)
23564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throws OutOfResourcesException, IllegalArgumentException {
2363866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        checkNotReleased();
2373866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        return nativeLockCanvas(mNativeObject, inOutDirty);
23864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
239240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
24064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
24164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Posts the new contents of the {@link Canvas} to the surface and
24264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * releases the {@link Canvas}.
24364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
24464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param canvas The canvas previously obtained from {@link #lockCanvas}.
24564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
24664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvasAndPost(Canvas canvas) {
2473866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        checkNotReleased();
2483866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        nativeUnlockCanvasAndPost(mNativeObject, canvas);
24964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
250240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
25164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
25264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @deprecated This API has been removed and is not supported.  Do not use.
25364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
25464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Deprecated
25564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvas(Canvas canvas) {
25664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        throw new UnsupportedOperationException();
257d10cd5765a2b706fc174f16b951d6b0a5d3740d3Romain Guy    }
25838ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
25938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima    /**
260b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * Sets the translator used to scale canvas's width/height in compatibility
261b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * mode.
26238ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima     */
2635be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    void setCompatibilityTranslator(Translator translator) {
264240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        if (translator != null) {
265240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            float appScale = translator.applicationScale;
266240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix = new Matrix();
267240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix.setScale(appScale, appScale);
268240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
27264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
27364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Copy another surface to this one.  This surface now holds a reference
27464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to the same data as the original surface, and is -not- the owner.
27564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the window manager when returning a window surface
27664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * back from a client, converting it from the representation being managed
27764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the window manager to the representation the client uses to draw
27864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in to it.
27964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
28064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
2813866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public void copyFrom(SurfaceControl other) {
28264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
28364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2853866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (other.mNativeObject == 0) {
2863866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            throw new NullPointerException(
2873866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
28864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
2893866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mNativeObject = nativeCopyFrom(mNativeObject, other.mNativeObject);
2908b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy        mGenerationId++;
29164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
29264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
29364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
29464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Transfer the native state from 'other' to this surface, releasing it
29564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * from 'other'.  This is for use in the client side for drawing into a
29664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * surface; not guaranteed to work on the window manager side.
29764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the client to move the underlying surface from
29864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * one Surface object to another, in particular in SurfaceFlinger.
29964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide.
30064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
30164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void transferFrom(Surface other) {
30264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
30364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
30464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
30564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other != this) {
3063866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            if (mNativeObject != 0) {
3073866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                // release our reference to our native object
3083866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                nativeRelease(mNativeObject);
3093866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
3103866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            // transfer the reference from other to us
3113866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = other.mNativeObject;
3128b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy            mGenerationId++;
3138b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy
3143866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            other.mNativeObject = 0;
3158b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy            other.mGenerationId++;
31664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
31764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
32064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public int describeContents() {
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return 0;
32264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
32364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
32464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void readFromParcel(Parcel source) {
32564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (source == null) {
32664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("source must not be null");
327f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
32864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mName = source.readString();
3293866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mNativeObject = nativeReadFromParcel(mNativeObject, source);
3308b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy        mGenerationId++;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
33464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void writeToParcel(Parcel dest, int flags) {
33564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (dest == null) {
33664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("dest must not be null");
33764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
33864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dest.writeString(mName);
3393866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        nativeWriteToParcel(mNativeObject, dest);
34064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
34164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            release();
34264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
34364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
3440de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg
34564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
34664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public String toString() {
347f9136fd9692158574d187af8d4031fa4b1e2b6e6Mathias Agopian        return "Surface(name=" + mName + ")";
34864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
34964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
35064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
35164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Exception thrown when a surface couldn't be created or resized.
35264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
35364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static class OutOfResourcesException extends Exception {
35464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException() {
35564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
35664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException(String name) {
35764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super(name);
35864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
35964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
36064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
36164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
362152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * Returns a human readable representation of a rotation.
363152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     *
364152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @param rotation The rotation.
365152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @return The rotation symbolic name.
366545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     *
367545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     * @hide
368152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     */
369152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    public static String rotationToString(int rotation) {
370152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        switch (rotation) {
371152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_0: {
372152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROTATION_0";
373152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
374152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_90: {
375152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_90";
376152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
377152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_180: {
378152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_180";
379152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
380152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_270: {
381152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_270";
382152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
383152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            default: {
384152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                throw new IllegalArgumentException("Invalid rotation: " + rotation);
385152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
386152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
387152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
388152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
389152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    /**
39064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * A Canvas class that can handle the compatibility mode.
39164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This does two things differently.
39264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <ul>
39364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Returns the width and height of the target metrics, rather than
39464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * native. For example, the canvas returns 320x480 even if an app is running
39564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in WVGA high density.
39664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Scales the matrix in setMatrix by the application scale, except if
39764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the matrix looks like obtained from getMatrix. This is a hack to handle
39864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the case that an application uses getMatrix to keep the original matrix,
39964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * set matrix of its own, then set the original matrix back. There is no
40064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * perfect solution that works for all cases, and there are a lot of cases
40164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * that this model does not work, but we hope this works for many apps.
40264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * </ul>
40364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
40464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final class CompatibleCanvas extends Canvas {
40564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        // A temp matrix to remember what an application obtained via {@link getMatrix}
40664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        private Matrix mOrigMatrix = null;
40764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
40864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
40964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void setMatrix(Matrix matrix) {
41064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
41164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // don't scale the matrix if it's not compatibility mode, or
41264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // the matrix was obtained from getMatrix.
41364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(matrix);
41464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } else {
41564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Matrix m = new Matrix(mCompatibleMatrix);
41664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                m.preConcat(matrix);
41764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(m);
41864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
41964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
42064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
4218b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy        @SuppressWarnings("deprecation")
42264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
42364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void getMatrix(Matrix m) {
42464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.getMatrix(m);
42564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mOrigMatrix == null) {
42664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mOrigMatrix = new Matrix();
42764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
42864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            mOrigMatrix.set(m);
42964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
43064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
4313866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
4323866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    private void checkNotReleased() {
4333866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject == 0) throw new NullPointerException(
4343866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                "mNativeObject is null. Have you called release() already?");
4353866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
437