blob: 30c077c2e879bd76f7fb8dc0f7854d3069107749 [file] [log] [blame]
Romain Guy3b748a42013-04-17 18:54:38 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
19import android.graphics.Canvas;
20import android.graphics.PixelFormat;
21import android.graphics.Rect;
22import android.os.Parcel;
23import android.os.Parcelable;
24
25/**
26 * Simple wrapper for the native GraphicBuffer class.
27 *
28 * @hide
29 */
30@SuppressWarnings("UnusedDeclaration")
31public class GraphicBuffer implements Parcelable {
32 // Note: keep usage flags in sync with GraphicBuffer.h and gralloc.h
33 public static final int USAGE_SW_READ_NEVER = 0x0;
34 public static final int USAGE_SW_READ_RARELY = 0x2;
35 public static final int USAGE_SW_READ_OFTEN = 0x3;
36 public static final int USAGE_SW_READ_MASK = 0xF;
37
38 public static final int USAGE_SW_WRITE_NEVER = 0x0;
39 public static final int USAGE_SW_WRITE_RARELY = 0x20;
40 public static final int USAGE_SW_WRITE_OFTEN = 0x30;
41 public static final int USAGE_SW_WRITE_MASK = 0xF0;
42
43 public static final int USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK;
44
45 public static final int USAGE_PROTECTED = 0x4000;
46
47 public static final int USAGE_HW_TEXTURE = 0x100;
48 public static final int USAGE_HW_RENDER = 0x200;
49 public static final int USAGE_HW_2D = 0x400;
50 public static final int USAGE_HW_COMPOSER = 0x800;
51 public static final int USAGE_HW_VIDEO_ENCODER = 0x10000;
52 public static final int USAGE_HW_MASK = 0x71F00;
53
54 private final int mWidth;
55 private final int mHeight;
56 private final int mFormat;
57 private final int mUsage;
58 // Note: do not rename, this field is used by native code
59 private final int mNativeObject;
60
61 // These two fields are only used by lock/unlockCanvas()
62 private Canvas mCanvas;
63 private int mSaveCount;
64
Romain Guyb2ed04a2013-07-09 18:56:57 -070065 // If set to true, this GraphicBuffer instance cannot be used anymore
66 private boolean mDestroyed;
67
Romain Guy3b748a42013-04-17 18:54:38 -070068 /**
69 * Creates new <code>GraphicBuffer</code> instance. This method will return null
70 * if the buffer cannot be created.
71 *
72 * @param width The width in pixels of the buffer
73 * @param height The height in pixels of the buffer
74 * @param format The format of each pixel as specified in {@link PixelFormat}
75 * @param usage Hint indicating how the buffer will be used
76 *
77 * @return A <code>GraphicBuffer</code> instance or null
78 */
79 public static GraphicBuffer create(int width, int height, int format, int usage) {
80 int nativeObject = nCreateGraphicBuffer(width, height, format, usage);
81 if (nativeObject != 0) {
82 return new GraphicBuffer(width, height, format, usage, nativeObject);
83 }
84 return null;
85 }
86
87 /**
88 * Private use only. See {@link #create(int, int, int, int)}.
89 */
90 private GraphicBuffer(int width, int height, int format, int usage, int nativeObject) {
91 mWidth = width;
92 mHeight = height;
93 mFormat = format;
94 mUsage = usage;
95 mNativeObject = nativeObject;
96 }
97
98 /**
99 * Returns the width of this buffer in pixels.
100 */
101 public int getWidth() {
102 return mWidth;
103 }
104
105 /**
106 * Returns the height of this buffer in pixels.
107 */
108 public int getHeight() {
109 return mHeight;
110 }
111
112 /**
113 * Returns the pixel format of this buffer. The pixel format must be one of
114 * the formats defined in {@link PixelFormat}.
115 */
116 public int getFormat() {
117 return mFormat;
118 }
119
120 /**
121 * Returns the usage hint set on this buffer.
122 */
123 public int getUsage() {
124 return mUsage;
125 }
126
127 /**
128 * <p>Start editing the pixels in the buffer. A null is returned if the buffer
129 * cannot be locked for editing.</p>
130 *
131 * <p>The content of the buffer is preserved between unlockCanvas()
132 * and lockCanvas().</p>
133 *
Romain Guyb2ed04a2013-07-09 18:56:57 -0700134 * <p>If this method is called after {@link #destroy()}, the return value will
135 * always be null.</p>
136 *
Romain Guy3b748a42013-04-17 18:54:38 -0700137 * @return A Canvas used to draw into the buffer, or null.
138 *
139 * @see #lockCanvas(android.graphics.Rect)
140 * @see #unlockCanvasAndPost(android.graphics.Canvas)
Romain Guyb2ed04a2013-07-09 18:56:57 -0700141 * @see #isDestroyed()
Romain Guy3b748a42013-04-17 18:54:38 -0700142 */
143 public Canvas lockCanvas() {
144 return lockCanvas(null);
145 }
146
147 /**
148 * Just like {@link #lockCanvas()} but allows specification of a dirty
149 * rectangle.
150 *
Romain Guyb2ed04a2013-07-09 18:56:57 -0700151 * <p>If this method is called after {@link #destroy()}, the return value will
152 * always be null.</p>
153 *
Romain Guy3b748a42013-04-17 18:54:38 -0700154 * @param dirty Area of the buffer that may be modified.
155
Romain Guyb2ed04a2013-07-09 18:56:57 -0700156 * @return A Canvas used to draw into the surface, or null.
Romain Guy3b748a42013-04-17 18:54:38 -0700157 *
158 * @see #lockCanvas()
159 * @see #unlockCanvasAndPost(android.graphics.Canvas)
Romain Guyb2ed04a2013-07-09 18:56:57 -0700160 * @see #isDestroyed()
Romain Guy3b748a42013-04-17 18:54:38 -0700161 */
162 public Canvas lockCanvas(Rect dirty) {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700163 if (mDestroyed) {
164 return null;
165 }
166
Romain Guy3b748a42013-04-17 18:54:38 -0700167 if (mCanvas == null) {
168 mCanvas = new Canvas();
169 }
170
171 if (nLockCanvas(mNativeObject, mCanvas, dirty)) {
172 mSaveCount = mCanvas.save();
173 return mCanvas;
174 }
175
176 return null;
177 }
178
179 /**
180 * Finish editing pixels in the buffer.
181 *
Romain Guyb2ed04a2013-07-09 18:56:57 -0700182 * <p>This method doesn't do anything if {@link #destroy()} was
183 * previously called.</p>
184 *
Romain Guy3b748a42013-04-17 18:54:38 -0700185 * @param canvas The Canvas previously returned by lockCanvas()
186 *
187 * @see #lockCanvas()
188 * @see #lockCanvas(android.graphics.Rect)
Romain Guyb2ed04a2013-07-09 18:56:57 -0700189 * @see #isDestroyed()
Romain Guy3b748a42013-04-17 18:54:38 -0700190 */
191 public void unlockCanvasAndPost(Canvas canvas) {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700192 if (!mDestroyed && mCanvas != null && canvas == mCanvas) {
Romain Guy3b748a42013-04-17 18:54:38 -0700193 canvas.restoreToCount(mSaveCount);
194 mSaveCount = 0;
195
196 nUnlockCanvasAndPost(mNativeObject, mCanvas);
197 }
198 }
199
Romain Guyb2ed04a2013-07-09 18:56:57 -0700200 /**
201 * Destroyes this buffer immediately. Calling this method frees up any
202 * underlying native resources. After calling this method, this buffer
203 * must not be used in any way ({@link #lockCanvas()} must not be called,
204 * etc.)
205 *
206 * @see #isDestroyed()
207 */
208 public void destroy() {
209 if (!mDestroyed) {
210 mDestroyed = true;
211 nDestroyGraphicBuffer(mNativeObject);
212 }
213 }
214
215 /**
216 * Indicates whether this buffer has been destroyed. A destroyed buffer
217 * cannot be used in any way: locking a Canvas will return null, the buffer
218 * cannot be written to a parcel, etc.
219 *
220 * @return True if this <code>GraphicBuffer</code> is in a destroyed state,
221 * false otherwise.
222 *
223 * @see #destroy()
224 */
225 public boolean isDestroyed() {
226 return mDestroyed;
227 }
228
Romain Guy3b748a42013-04-17 18:54:38 -0700229 @Override
230 protected void finalize() throws Throwable {
231 try {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700232 if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
Romain Guy3b748a42013-04-17 18:54:38 -0700233 } finally {
234 super.finalize();
235 }
236 }
237
238 @Override
239 public int describeContents() {
240 return 0;
241 }
242
Romain Guyb2ed04a2013-07-09 18:56:57 -0700243 /**
244 * Flatten this object in to a Parcel.
245 *
246 * <p>Calling this method will throw an <code>IllegalStateException</code> if
247 * {@link #destroy()} has been previously called.</p>
248 *
249 * @param dest The Parcel in which the object should be written.
250 * @param flags Additional flags about how the object should be written.
251 * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
252 */
Romain Guy3b748a42013-04-17 18:54:38 -0700253 @Override
254 public void writeToParcel(Parcel dest, int flags) {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700255 if (mDestroyed) {
256 throw new IllegalStateException("This GraphicBuffer has been destroyed and cannot be "
257 + "written to a parcel.");
258 }
259
Romain Guy3b748a42013-04-17 18:54:38 -0700260 dest.writeInt(mWidth);
261 dest.writeInt(mHeight);
262 dest.writeInt(mFormat);
263 dest.writeInt(mUsage);
264 nWriteGraphicBufferToParcel(mNativeObject, dest);
265 }
266
267 public static final Parcelable.Creator<GraphicBuffer> CREATOR =
268 new Parcelable.Creator<GraphicBuffer>() {
269 public GraphicBuffer createFromParcel(Parcel in) {
270 int width = in.readInt();
271 int height = in.readInt();
272 int format = in.readInt();
273 int usage = in.readInt();
274 int nativeObject = nReadGraphicBufferFromParcel(in);
275 if (nativeObject != 0) {
276 return new GraphicBuffer(width, height, format, usage, nativeObject);
277 }
278 return null;
279 }
280
281 public GraphicBuffer[] newArray(int size) {
282 return new GraphicBuffer[size];
283 }
284 };
285
286 private static native int nCreateGraphicBuffer(int width, int height, int format, int usage);
287 private static native void nDestroyGraphicBuffer(int nativeObject);
288 private static native void nWriteGraphicBufferToParcel(int nativeObject, Parcel dest);
289 private static native int nReadGraphicBufferFromParcel(Parcel in);
290 private static native boolean nLockCanvas(int nativeObject, Canvas canvas, Rect dirty);
291 private static native boolean nUnlockCanvasAndPost(int nativeObject, Canvas canvas);
292}