13b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/*
23b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Copyright (C) 2013 The Android Open Source Project
33b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
43b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
53b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * you may not use this file except in compliance with the License.
63b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * You may obtain a copy of the License at
73b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
83b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
93b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Unless required by applicable law or agreed to in writing, software
113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * See the License for the specific language governing permissions and
143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * limitations under the License.
153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */
163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guypackage android.view;
183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.graphics.Canvas;
203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.graphics.PixelFormat;
213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.graphics.Rect;
223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.os.Parcel;
233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyimport android.os.Parcelable;
243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/**
263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Simple wrapper for the native GraphicBuffer class.
273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * @hide
293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */
303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy@SuppressWarnings("UnusedDeclaration")
313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guypublic class GraphicBuffer implements Parcelable {
323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    // Note: keep usage flags in sync with GraphicBuffer.h and gralloc.h
333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_READ_NEVER = 0x0;
343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_READ_RARELY = 0x2;
353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_READ_OFTEN = 0x3;
363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_READ_MASK = 0xF;
373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_WRITE_NEVER = 0x0;
393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_WRITE_RARELY = 0x20;
403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_WRITE_OFTEN = 0x30;
413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SW_WRITE_MASK = 0xF0;
423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK;
443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_PROTECTED = 0x4000;
463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_HW_TEXTURE = 0x100;
483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_HW_RENDER = 0x200;
493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_HW_2D = 0x400;
503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_HW_COMPOSER = 0x800;
513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_HW_VIDEO_ENCODER = 0x10000;
523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final int USAGE_HW_MASK = 0x71F00;
533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private final int mWidth;
553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private final int mHeight;
563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private final int mFormat;
573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private final int mUsage;
583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    // Note: do not rename, this field is used by native code
593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private final int mNativeObject;
603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    // These two fields are only used by lock/unlockCanvas()
623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private Canvas mCanvas;
633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private int mSaveCount;
643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
65b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    // If set to true, this GraphicBuffer instance cannot be used anymore
66b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    private boolean mDestroyed;
67b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy
683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Creates new <code>GraphicBuffer</code> instance. This method will return null
703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * if the buffer cannot be created.
713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param width The width in pixels of the buffer
733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param height The height in pixels of the buffer
743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param format The format of each pixel as specified in {@link PixelFormat}
753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param usage Hint indicating how the buffer will be used
763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @return A <code>GraphicBuffer</code> instance or null
783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static GraphicBuffer create(int width, int height, int format, int usage) {
803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        int nativeObject = nCreateGraphicBuffer(width, height, format, usage);
813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (nativeObject != 0) {
823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            return new GraphicBuffer(width, height, format, usage, nativeObject);
833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return null;
853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Private use only. See {@link #create(int, int, int, int)}.
893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private GraphicBuffer(int width, int height, int format, int usage, int nativeObject) {
913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mWidth = width;
923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mHeight = height;
933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mFormat = format;
943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mUsage = usage;
953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        mNativeObject = nativeObject;
963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the width of this buffer in pixels.
1003b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public int getWidth() {
1023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return mWidth;
1033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1043b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the height of this buffer in pixels.
1073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public int getHeight() {
1093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return mHeight;
1103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the pixel format of this buffer. The pixel format must be one of
1143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * the formats defined in {@link PixelFormat}.
1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public int getFormat() {
1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return mFormat;
1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the usage hint set on this buffer.
1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public int getUsage() {
1243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return mUsage;
1253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * <p>Start editing the pixels in the buffer. A null is returned if the buffer
1293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * cannot be locked for editing.</p>
1303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
1313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * <p>The content of the buffer is preserved between unlockCanvas()
1323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * and lockCanvas().</p>
1333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
134b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * <p>If this method is called after {@link #destroy()}, the return value will
135b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * always be null.</p>
136b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
1373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @return A Canvas used to draw into the buffer, or null.
1383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
1393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @see #lockCanvas(android.graphics.Rect)
1403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @see #unlockCanvasAndPost(android.graphics.Canvas)
141b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @see #isDestroyed()
1423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public Canvas lockCanvas() {
1443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return lockCanvas(null);
1453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Just like {@link #lockCanvas()} but allows specification of a dirty
1493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * rectangle.
1503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
151b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * <p>If this method is called after {@link #destroy()}, the return value will
152b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * always be null.</p>
153b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
1543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param dirty Area of the buffer that may be modified.
1553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
156b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @return A Canvas used to draw into the surface, or null.
1573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
1583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @see #lockCanvas()
1593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @see #unlockCanvasAndPost(android.graphics.Canvas)
160b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @see #isDestroyed()
1613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public Canvas lockCanvas(Rect dirty) {
163b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        if (mDestroyed) {
164b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy            return null;
165b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        }
166b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy
1673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (mCanvas == null) {
1683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            mCanvas = new Canvas();
1693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
1703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        if (nLockCanvas(mNativeObject, mCanvas, dirty)) {
1723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            mSaveCount = mCanvas.save();
1733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            return mCanvas;
1743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
1753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return null;
1773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Finish editing pixels in the buffer.
1813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
182b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * <p>This method doesn't do anything if {@link #destroy()} was
183b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * previously called.</p>
184b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
1853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @param canvas The Canvas previously returned by lockCanvas()
1863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
1873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @see #lockCanvas()
1883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * @see #lockCanvas(android.graphics.Rect)
189b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @see #isDestroyed()
1903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public void unlockCanvasAndPost(Canvas canvas) {
192b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        if (!mDestroyed && mCanvas != null && canvas == mCanvas) {
1933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            canvas.restoreToCount(mSaveCount);
1943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            mSaveCount = 0;
1953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            nUnlockCanvasAndPost(mNativeObject, mCanvas);
1973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
1983b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1993b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
200b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    /**
201b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * Destroyes this buffer immediately. Calling this method frees up any
202b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * underlying native resources. After calling this method, this buffer
203b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * must not be used in any way ({@link #lockCanvas()} must not be called,
204b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * etc.)
205b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
206b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @see #isDestroyed()
207b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     */
208b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    public void destroy() {
209b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        if (!mDestroyed) {
210b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy            mDestroyed = true;
211b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy            nDestroyGraphicBuffer(mNativeObject);
212b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        }
213b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    }
214b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy
215b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    /**
216b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * Indicates whether this buffer has been destroyed. A destroyed buffer
217b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * cannot be used in any way: locking a Canvas will return null, the buffer
218b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * cannot be written to a parcel, etc.
219b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
220b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @return True if this <code>GraphicBuffer</code> is in a destroyed state,
221b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *         false otherwise.
222b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
223b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @see #destroy()
224b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     */
225b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    public boolean isDestroyed() {
226b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        return mDestroyed;
227b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    }
228b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy
2293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    @Override
2303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    protected void finalize() throws Throwable {
2313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        try {
232b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy            if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
2333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        } finally {
2343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            super.finalize();
2353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
2363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
2373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
2383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    @Override
2393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public int describeContents() {
2403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        return 0;
2413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
2423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
243b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy    /**
244b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * Flatten this object in to a Parcel.
245b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
246b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * <p>Calling this method will throw an <code>IllegalStateException</code> if
247b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * {@link #destroy()} has been previously called.</p>
248b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *
249b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @param dest The Parcel in which the object should be written.
250b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     * @param flags Additional flags about how the object should be written.
251b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
252b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy     */
2533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    @Override
2543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public void writeToParcel(Parcel dest, int flags) {
255b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        if (mDestroyed) {
256b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy            throw new IllegalStateException("This GraphicBuffer has been destroyed and cannot be "
257b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy                    + "written to a parcel.");
258b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy        }
259b2ed04a68913f4d84d7cb7e979b6f0ae96f43058Romain Guy
2603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        dest.writeInt(mWidth);
2613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        dest.writeInt(mHeight);
2623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        dest.writeInt(mFormat);
2633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        dest.writeInt(mUsage);
2643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        nWriteGraphicBufferToParcel(mNativeObject, dest);
2653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
2663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
2673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    public static final Parcelable.Creator<GraphicBuffer> CREATOR =
2683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            new Parcelable.Creator<GraphicBuffer>() {
2693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        public GraphicBuffer createFromParcel(Parcel in) {
2703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            int width = in.readInt();
2713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            int height = in.readInt();
2723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            int format = in.readInt();
2733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            int usage = in.readInt();
2743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            int nativeObject = nReadGraphicBufferFromParcel(in);
2753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            if (nativeObject != 0) {
2763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy                return new GraphicBuffer(width, height, format, usage, nativeObject);
2773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            }
2783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            return null;
2793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
2803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
2813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        public GraphicBuffer[] newArray(int size) {
2823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy            return new GraphicBuffer[size];
2833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        }
2843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    };
2853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
2863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private static native int nCreateGraphicBuffer(int width, int height, int format, int usage);
2873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private static native void nDestroyGraphicBuffer(int nativeObject);
2883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private static native void nWriteGraphicBufferToParcel(int nativeObject, Parcel dest);
2893b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private static native int nReadGraphicBufferFromParcel(Parcel in);
2903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private static native boolean nLockCanvas(int nativeObject, Canvas canvas, Rect dirty);
2913b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private static native boolean nUnlockCanvasAndPost(int nativeObject, Canvas canvas);
2923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}
293