blob: 74086830fae2010e8aaae2636c48e4a09dcd6292 [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
sergeyv0a0f2312017-01-04 13:58:52 -080017package android.graphics;
Romain Guy3b748a42013-04-17 18:54:38 -070018
Mathew Inwood0d649f22018-07-31 14:29:22 +010019import android.annotation.UnsupportedAppUsage;
Romain Guy3b748a42013-04-17 18:54:38 -070020import android.os.Parcel;
21import android.os.Parcelable;
22
23/**
24 * Simple wrapper for the native GraphicBuffer class.
25 *
26 * @hide
27 */
28@SuppressWarnings("UnusedDeclaration")
29public class GraphicBuffer implements Parcelable {
30 // Note: keep usage flags in sync with GraphicBuffer.h and gralloc.h
31 public static final int USAGE_SW_READ_NEVER = 0x0;
32 public static final int USAGE_SW_READ_RARELY = 0x2;
33 public static final int USAGE_SW_READ_OFTEN = 0x3;
34 public static final int USAGE_SW_READ_MASK = 0xF;
35
36 public static final int USAGE_SW_WRITE_NEVER = 0x0;
37 public static final int USAGE_SW_WRITE_RARELY = 0x20;
38 public static final int USAGE_SW_WRITE_OFTEN = 0x30;
39 public static final int USAGE_SW_WRITE_MASK = 0xF0;
40
41 public static final int USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK;
42
43 public static final int USAGE_PROTECTED = 0x4000;
44
45 public static final int USAGE_HW_TEXTURE = 0x100;
46 public static final int USAGE_HW_RENDER = 0x200;
47 public static final int USAGE_HW_2D = 0x400;
48 public static final int USAGE_HW_COMPOSER = 0x800;
49 public static final int USAGE_HW_VIDEO_ENCODER = 0x10000;
50 public static final int USAGE_HW_MASK = 0x71F00;
51
52 private final int mWidth;
53 private final int mHeight;
54 private final int mFormat;
55 private final int mUsage;
56 // Note: do not rename, this field is used by native code
Mathew Inwood0d649f22018-07-31 14:29:22 +010057 @UnsupportedAppUsage
Ashok Bhat36bef0b2014-01-20 20:08:01 +000058 private final long mNativeObject;
Romain Guy3b748a42013-04-17 18:54:38 -070059
60 // These two fields are only used by lock/unlockCanvas()
61 private Canvas mCanvas;
62 private int mSaveCount;
63
Romain Guyb2ed04a2013-07-09 18:56:57 -070064 // If set to true, this GraphicBuffer instance cannot be used anymore
65 private boolean mDestroyed;
66
Romain Guy3b748a42013-04-17 18:54:38 -070067 /**
68 * Creates new <code>GraphicBuffer</code> instance. This method will return null
69 * if the buffer cannot be created.
70 *
71 * @param width The width in pixels of the buffer
72 * @param height The height in pixels of the buffer
73 * @param format The format of each pixel as specified in {@link PixelFormat}
74 * @param usage Hint indicating how the buffer will be used
75 *
76 * @return A <code>GraphicBuffer</code> instance or null
77 */
78 public static GraphicBuffer create(int width, int height, int format, int usage) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +000079 long nativeObject = nCreateGraphicBuffer(width, height, format, usage);
Romain Guy3b748a42013-04-17 18:54:38 -070080 if (nativeObject != 0) {
81 return new GraphicBuffer(width, height, format, usage, nativeObject);
82 }
83 return null;
84 }
85
86 /**
87 * Private use only. See {@link #create(int, int, int, int)}.
88 */
Mathew Inwood0d649f22018-07-31 14:29:22 +010089 @UnsupportedAppUsage
Ashok Bhat36bef0b2014-01-20 20:08:01 +000090 private GraphicBuffer(int width, int height, int format, int usage, long nativeObject) {
Romain Guy3b748a42013-04-17 18:54:38 -070091 mWidth = width;
92 mHeight = height;
93 mFormat = format;
94 mUsage = usage;
95 mNativeObject = nativeObject;
96 }
97
98 /**
Robert Carr6486d312017-01-09 19:48:29 -080099 * For SurfaceControl JNI.
100 * @hide
101 */
Mathew Inwood0d649f22018-07-31 14:29:22 +0100102 @UnsupportedAppUsage
Robert Carr6486d312017-01-09 19:48:29 -0800103 public static GraphicBuffer createFromExisting(int width, int height,
104 int format, int usage, long unwrappedNativeObject) {
105 long nativeObject = nWrapGraphicBuffer(unwrappedNativeObject);
106 if (nativeObject != 0) {
107 return new GraphicBuffer(width, height, format, usage, nativeObject);
108 }
109 return null;
110 }
111
112 /**
Romain Guy3b748a42013-04-17 18:54:38 -0700113 * Returns the width of this buffer in pixels.
114 */
115 public int getWidth() {
116 return mWidth;
117 }
118
119 /**
120 * Returns the height of this buffer in pixels.
121 */
122 public int getHeight() {
123 return mHeight;
124 }
125
126 /**
127 * Returns the pixel format of this buffer. The pixel format must be one of
128 * the formats defined in {@link PixelFormat}.
129 */
130 public int getFormat() {
131 return mFormat;
132 }
133
134 /**
135 * Returns the usage hint set on this buffer.
136 */
137 public int getUsage() {
138 return mUsage;
139 }
140
141 /**
142 * <p>Start editing the pixels in the buffer. A null is returned if the buffer
143 * cannot be locked for editing.</p>
144 *
145 * <p>The content of the buffer is preserved between unlockCanvas()
146 * and lockCanvas().</p>
147 *
Romain Guyb2ed04a2013-07-09 18:56:57 -0700148 * <p>If this method is called after {@link #destroy()}, the return value will
149 * always be null.</p>
150 *
Romain Guy3b748a42013-04-17 18:54:38 -0700151 * @return A Canvas used to draw into the buffer, or null.
152 *
153 * @see #lockCanvas(android.graphics.Rect)
154 * @see #unlockCanvasAndPost(android.graphics.Canvas)
Romain Guyb2ed04a2013-07-09 18:56:57 -0700155 * @see #isDestroyed()
Romain Guy3b748a42013-04-17 18:54:38 -0700156 */
157 public Canvas lockCanvas() {
158 return lockCanvas(null);
159 }
160
161 /**
162 * Just like {@link #lockCanvas()} but allows specification of a dirty
163 * rectangle.
164 *
Romain Guyb2ed04a2013-07-09 18:56:57 -0700165 * <p>If this method is called after {@link #destroy()}, the return value will
166 * always be null.</p>
167 *
Romain Guy3b748a42013-04-17 18:54:38 -0700168 * @param dirty Area of the buffer that may be modified.
169
Romain Guyb2ed04a2013-07-09 18:56:57 -0700170 * @return A Canvas used to draw into the surface, or null.
Romain Guy3b748a42013-04-17 18:54:38 -0700171 *
172 * @see #lockCanvas()
173 * @see #unlockCanvasAndPost(android.graphics.Canvas)
Romain Guyb2ed04a2013-07-09 18:56:57 -0700174 * @see #isDestroyed()
Romain Guy3b748a42013-04-17 18:54:38 -0700175 */
176 public Canvas lockCanvas(Rect dirty) {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700177 if (mDestroyed) {
178 return null;
179 }
180
Romain Guy3b748a42013-04-17 18:54:38 -0700181 if (mCanvas == null) {
182 mCanvas = new Canvas();
183 }
184
185 if (nLockCanvas(mNativeObject, mCanvas, dirty)) {
186 mSaveCount = mCanvas.save();
187 return mCanvas;
188 }
189
190 return null;
191 }
192
193 /**
194 * Finish editing pixels in the buffer.
195 *
Romain Guyb2ed04a2013-07-09 18:56:57 -0700196 * <p>This method doesn't do anything if {@link #destroy()} was
197 * previously called.</p>
198 *
Romain Guy3b748a42013-04-17 18:54:38 -0700199 * @param canvas The Canvas previously returned by lockCanvas()
200 *
201 * @see #lockCanvas()
202 * @see #lockCanvas(android.graphics.Rect)
Romain Guyb2ed04a2013-07-09 18:56:57 -0700203 * @see #isDestroyed()
Romain Guy3b748a42013-04-17 18:54:38 -0700204 */
205 public void unlockCanvasAndPost(Canvas canvas) {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700206 if (!mDestroyed && mCanvas != null && canvas == mCanvas) {
Romain Guy3b748a42013-04-17 18:54:38 -0700207 canvas.restoreToCount(mSaveCount);
208 mSaveCount = 0;
209
210 nUnlockCanvasAndPost(mNativeObject, mCanvas);
211 }
212 }
213
Romain Guyb2ed04a2013-07-09 18:56:57 -0700214 /**
215 * Destroyes this buffer immediately. Calling this method frees up any
216 * underlying native resources. After calling this method, this buffer
217 * must not be used in any way ({@link #lockCanvas()} must not be called,
218 * etc.)
219 *
220 * @see #isDestroyed()
221 */
222 public void destroy() {
223 if (!mDestroyed) {
224 mDestroyed = true;
225 nDestroyGraphicBuffer(mNativeObject);
226 }
227 }
228
229 /**
230 * Indicates whether this buffer has been destroyed. A destroyed buffer
231 * cannot be used in any way: locking a Canvas will return null, the buffer
232 * cannot be written to a parcel, etc.
233 *
234 * @return True if this <code>GraphicBuffer</code> is in a destroyed state,
235 * false otherwise.
236 *
237 * @see #destroy()
238 */
239 public boolean isDestroyed() {
240 return mDestroyed;
241 }
242
Romain Guy3b748a42013-04-17 18:54:38 -0700243 @Override
244 protected void finalize() throws Throwable {
245 try {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700246 if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
Romain Guy3b748a42013-04-17 18:54:38 -0700247 } finally {
248 super.finalize();
249 }
250 }
251
252 @Override
253 public int describeContents() {
254 return 0;
255 }
256
Romain Guyb2ed04a2013-07-09 18:56:57 -0700257 /**
258 * Flatten this object in to a Parcel.
259 *
260 * <p>Calling this method will throw an <code>IllegalStateException</code> if
261 * {@link #destroy()} has been previously called.</p>
262 *
263 * @param dest The Parcel in which the object should be written.
264 * @param flags Additional flags about how the object should be written.
265 * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
266 */
Romain Guy3b748a42013-04-17 18:54:38 -0700267 @Override
268 public void writeToParcel(Parcel dest, int flags) {
Romain Guyb2ed04a2013-07-09 18:56:57 -0700269 if (mDestroyed) {
270 throw new IllegalStateException("This GraphicBuffer has been destroyed and cannot be "
271 + "written to a parcel.");
272 }
273
Romain Guy3b748a42013-04-17 18:54:38 -0700274 dest.writeInt(mWidth);
275 dest.writeInt(mHeight);
276 dest.writeInt(mFormat);
277 dest.writeInt(mUsage);
278 nWriteGraphicBufferToParcel(mNativeObject, dest);
279 }
280
Mathew Inwood0d649f22018-07-31 14:29:22 +0100281 @UnsupportedAppUsage
Romain Guy3b748a42013-04-17 18:54:38 -0700282 public static final Parcelable.Creator<GraphicBuffer> CREATOR =
283 new Parcelable.Creator<GraphicBuffer>() {
284 public GraphicBuffer createFromParcel(Parcel in) {
285 int width = in.readInt();
286 int height = in.readInt();
287 int format = in.readInt();
288 int usage = in.readInt();
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000289 long nativeObject = nReadGraphicBufferFromParcel(in);
Romain Guy3b748a42013-04-17 18:54:38 -0700290 if (nativeObject != 0) {
291 return new GraphicBuffer(width, height, format, usage, nativeObject);
292 }
293 return null;
294 }
295
296 public GraphicBuffer[] newArray(int size) {
297 return new GraphicBuffer[size];
298 }
299 };
300
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000301 private static native long nCreateGraphicBuffer(int width, int height, int format, int usage);
302 private static native void nDestroyGraphicBuffer(long nativeObject);
303 private static native void nWriteGraphicBufferToParcel(long nativeObject, Parcel dest);
304 private static native long nReadGraphicBufferFromParcel(Parcel in);
305 private static native boolean nLockCanvas(long nativeObject, Canvas canvas, Rect dirty);
306 private static native boolean nUnlockCanvasAndPost(long nativeObject, Canvas canvas);
Robert Carr6486d312017-01-09 19:48:29 -0800307 private static native long nWrapGraphicBuffer(long nativeObject);
Romain Guy3b748a42013-04-17 18:54:38 -0700308}