blob: 5531e539bfdbf02706432d311aff249ceca83b76 [file] [log] [blame]
Jamie Gennis8ba32fa2010-12-20 11:27:26 -08001/*
2 * Copyright (C) 2010 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
17#ifndef ANDROID_GUI_SURFACETEXTURE_H
18#define ANDROID_GUI_SURFACETEXTURE_H
19
20#include <EGL/egl.h>
21#include <EGL/eglext.h>
22#include <GLES2/gl2.h>
Jamie Gennisfb1b5a22011-09-28 12:13:31 -070023#include <GLES2/gl2ext.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080024
25#include <gui/ISurfaceTexture.h>
Daniel Lam6b091c52012-01-22 15:26:27 -080026#include <gui/BufferQueue.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080027
28#include <ui/GraphicBuffer.h>
29
Jamie Gennisfa28c352011-09-16 17:30:26 -070030#include <utils/String8.h>
Jamie Gennis9a78c902011-01-12 18:30:40 -080031#include <utils/Vector.h>
Jamie Gennisfa28c352011-09-16 17:30:26 -070032#include <utils/threads.h>
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080033
34#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
35
36namespace android {
37// ----------------------------------------------------------------------------
38
Daniel Lam6b091c52012-01-22 15:26:27 -080039
Mathias Agopian68c77942011-05-09 19:08:33 -070040class String8;
Jamie Gennis9a78c902011-01-12 18:30:40 -080041
Daniel Lam6b091c52012-01-22 15:26:27 -080042class SurfaceTexture : public BufferQueue {
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080043public:
Jamie Gennisc4d4aea2011-01-13 14:43:36 -080044
Jamie Gennis86edf4f2011-11-14 14:51:01 -080045 // SurfaceTexture constructs a new SurfaceTexture object. tex indicates the
46 // name of the OpenGL ES texture to which images are to be streamed. This
47 // texture name cannot be changed once the SurfaceTexture is created.
48 // allowSynchronousMode specifies whether or not synchronous mode can be
49 // enabled. texTarget specifies the OpenGL ES texture target to which the
50 // texture will be bound in updateTexImage. useFenceSync specifies whether
51 // fences should be used to synchronize access to buffers if that behavior
52 // is enabled at compile-time.
Jamie Gennisfb1b5a22011-09-28 12:13:31 -070053 SurfaceTexture(GLuint tex, bool allowSynchronousMode = true,
Jamie Gennis86edf4f2011-11-14 14:51:01 -080054 GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true);
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080055
56 virtual ~SurfaceTexture();
57
Daniel Lamb8560522012-01-30 15:51:27 -080058
Mathias Agopianeafabcd2011-04-20 14:20:59 -070059
Jamie Gennis8ba32fa2010-12-20 11:27:26 -080060 // updateTexImage sets the image contents of the target texture to that of
61 // the most recently queued buffer.
62 //
63 // This call may only be made while the OpenGL ES context to which the
64 // target texture belongs is bound to the calling thread.
65 status_t updateTexImage();
66
Mathias Agopian80727112011-05-02 19:51:12 -070067 // setBufferCountServer set the buffer count. If the client has requested
68 // a buffer count using setBufferCount, the server-buffer count will
69 // take effect once the client sets the count back to zero.
70 status_t setBufferCountServer(int bufferCount);
71
Jamie Gennisf238e282011-01-09 16:33:17 -080072 // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix
73 // associated with the texture image set by the most recent call to
74 // updateTexImage.
75 //
76 // This transform matrix maps 2D homogeneous texture coordinates of the form
77 // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture
78 // coordinate that should be used to sample that location from the texture.
79 // Sampling the texture outside of the range of this transform is undefined.
80 //
81 // This transform is necessary to compensate for transforms that the stream
82 // content producer may implicitly apply to the content. By forcing users of
83 // a SurfaceTexture to apply this transform we avoid performing an extra
84 // copy of the data that would be needed to hide the transform from the
85 // user.
86 //
87 // The matrix is stored in column-major order so that it may be passed
88 // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv
89 // functions.
90 void getTransformMatrix(float mtx[16]);
91
Eino-Ville Talvala1d01a122011-02-18 11:02:42 -080092 // getTimestamp retrieves the timestamp associated with the texture image
93 // set by the most recent call to updateTexImage.
94 //
95 // The timestamp is in nanoseconds, and is monotonically increasing. Its
96 // other semantics (zero point, etc) are source-dependent and should be
97 // documented by the source.
98 int64_t getTimestamp();
99
Jamie Gennisc4d4aea2011-01-13 14:43:36 -0800100 // setFrameAvailableListener sets the listener object that will be notified
101 // when a new frame becomes available.
Pannag Sanketi292a31a2011-06-24 09:56:27 -0700102 void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
Jamie Gennisc4d4aea2011-01-13 14:43:36 -0800103
Jamie Gennis1b20cde2011-02-02 15:31:47 -0800104 // getAllocator retrieves the binder object that must be referenced as long
105 // as the GraphicBuffers dequeued from this SurfaceTexture are referenced.
106 // Holding this binder reference prevents SurfaceFlinger from freeing the
107 // buffers before the client is done with them.
108 sp<IBinder> getAllocator();
109
Mathias Agopiana5c75c02011-03-31 19:10:24 -0700110 // setDefaultBufferSize is used to set the size of buffers returned by
111 // requestBuffers when a with and height of zero is requested.
112 // A call to setDefaultBufferSize() may trigger requestBuffers() to
113 // be called from the client.
Mathias Agopian194c76c2011-11-10 14:34:26 -0800114 // The width and height parameters must be no greater than the minimum of
115 // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv).
116 // An error due to invalid dimensions might not be reported until
117 // updateTexImage() is called.
118 status_t setDefaultBufferSize(uint32_t width, uint32_t height);
Mathias Agopiana5c75c02011-03-31 19:10:24 -0700119
Mathias Agopian7a042bf2011-04-11 21:19:55 -0700120 // getCurrentBuffer returns the buffer associated with the current image.
121 sp<GraphicBuffer> getCurrentBuffer() const;
122
123 // getCurrentTextureTarget returns the texture target of the current
124 // texture as returned by updateTexImage().
125 GLenum getCurrentTextureTarget() const;
126
127 // getCurrentCrop returns the cropping rectangle of the current buffer
128 Rect getCurrentCrop() const;
129
130 // getCurrentTransform returns the transform of the current buffer
131 uint32_t getCurrentTransform() const;
132
Mathias Agopian7734ebf2011-07-13 15:24:42 -0700133 // getCurrentScalingMode returns the scaling mode of the current buffer
134 uint32_t getCurrentScalingMode() const;
135
Jamie Gennis59769462011-11-19 18:04:43 -0800136 // isSynchronousMode returns whether the SurfaceTexture is currently in
137 // synchronous mode.
138 bool isSynchronousMode() const;
139
Jamie Gennis7b305ff2011-07-19 12:08:33 -0700140 // abandon frees all the buffers and puts the SurfaceTexture into the
141 // 'abandoned' state. Once put in this state the SurfaceTexture can never
142 // leave it. When in the 'abandoned' state, all methods of the
143 // ISurfaceTexture interface will fail with the NO_INIT error.
144 //
145 // Note that while calling this method causes all the buffers to be freed
146 // from the perspective of the the SurfaceTexture, if there are additional
147 // references on the buffers (e.g. if a buffer is referenced by a client or
148 // by OpenGL ES as a texture) then those buffer will remain allocated.
149 void abandon();
150
Jamie Gennisfa28c352011-09-16 17:30:26 -0700151 // set the name of the SurfaceTexture that will be used to identify it in
152 // log messages.
153 void setName(const String8& name);
154
Mathias Agopian68c77942011-05-09 19:08:33 -0700155 // dump our state in a String
Daniel Lameae59d22012-01-22 15:26:27 -0800156 virtual void dump(String8& result) const;
157 virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
Mathias Agopian68c77942011-05-09 19:08:33 -0700158
Mathias Agopian7a042bf2011-04-11 21:19:55 -0700159protected:
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800160
Mathias Agopian7a042bf2011-04-11 21:19:55 -0700161 static bool isExternalFormat(uint32_t format);
Mathias Agopian7a042bf2011-04-11 21:19:55 -0700162
163private:
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800164
165 // createImage creates a new EGLImage from a GraphicBuffer.
166 EGLImageKHR createImage(EGLDisplay dpy,
167 const sp<GraphicBuffer>& graphicBuffer);
168
Jamie Gennis736aa952011-06-12 17:03:06 -0700169 // computeCurrentTransformMatrix computes the transform matrix for the
170 // current texture. It uses mCurrentTransform and the current GraphicBuffer
171 // to compute this matrix and stores it in mCurrentTransformMatrix.
172 void computeCurrentTransformMatrix();
173
Jamie Gennis9a78c902011-01-12 18:30:40 -0800174 // mCurrentTextureBuf is the graphic buffer of the current texture. It's
175 // possible that this buffer is not associated with any buffer slot, so we
Jamie Gennis29c87022011-07-19 12:11:52 -0700176 // must track it separately in order to support the getCurrentBuffer method.
Jamie Gennis9a78c902011-01-12 18:30:40 -0800177 sp<GraphicBuffer> mCurrentTextureBuf;
178
Jamie Gennisf238e282011-01-09 16:33:17 -0800179 // mCurrentCrop is the crop rectangle that applies to the current texture.
Mathias Agopian7734ebf2011-07-13 15:24:42 -0700180 // It gets set each time updateTexImage is called.
Jamie Gennisf238e282011-01-09 16:33:17 -0800181 Rect mCurrentCrop;
182
183 // mCurrentTransform is the transform identifier for the current texture. It
Mathias Agopian7734ebf2011-07-13 15:24:42 -0700184 // gets set each time updateTexImage is called.
Jamie Gennisf238e282011-01-09 16:33:17 -0800185 uint32_t mCurrentTransform;
186
Mathias Agopian7734ebf2011-07-13 15:24:42 -0700187 // mCurrentScalingMode is the scaling mode for the current texture. It gets
188 // set to each time updateTexImage is called.
189 uint32_t mCurrentScalingMode;
190
Jamie Gennis736aa952011-06-12 17:03:06 -0700191 // mCurrentTransformMatrix is the transform matrix for the current texture.
192 // It gets computed by computeTransformMatrix each time updateTexImage is
193 // called.
194 float mCurrentTransformMatrix[16];
195
Eino-Ville Talvala1d01a122011-02-18 11:02:42 -0800196 // mCurrentTimestamp is the timestamp for the current texture. It
Mathias Agopian7734ebf2011-07-13 15:24:42 -0700197 // gets set each time updateTexImage is called.
Eino-Ville Talvala1d01a122011-02-18 11:02:42 -0800198 int64_t mCurrentTimestamp;
199
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800200 // mTexName is the name of the OpenGL texture to which streamed images will
Pannag Sanketi292a31a2011-06-24 09:56:27 -0700201 // be bound when updateTexImage is called. It is set at construction time
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800202 // changed with a call to setTexName.
203 const GLuint mTexName;
204
Jamie Gennis86edf4f2011-11-14 14:51:01 -0800205 // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync
206 // extension should be used to prevent buffers from being dequeued before
207 // it's safe for them to be written. It gets set at construction time and
208 // never changes.
209 const bool mUseFenceSync;
210
Jamie Gennisfb1b5a22011-09-28 12:13:31 -0700211 // mTexTarget is the GL texture target with which the GL texture object is
212 // associated. It is set in the constructor and never changed. It is
213 // almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android
214 // Browser. In that case it is set to GL_TEXTURE_2D to allow
215 // glCopyTexSubImage to read from the texture. This is a hack to work
216 // around a GL driver limitation on the number of FBO attachments, which the
217 // browser's tile cache exceeds.
218 const GLenum mTexTarget;
Sunita Nadampallia9297482011-11-09 18:23:41 -0600219
Daniel Lameae59d22012-01-22 15:26:27 -0800220 // SurfaceTexture maintains EGL information about GraphicBuffers that corresponds
221 // directly with BufferQueue's buffers
222 struct EGLSlot {
223 EGLSlot()
224 : mEglImage(EGL_NO_IMAGE_KHR),
225 mEglDisplay(EGL_NO_DISPLAY),
226 mFence(EGL_NO_SYNC_KHR) {
227 }
228
229 sp<GraphicBuffer> mGraphicBuffer;
230
231 // mEglImage is the EGLImage created from mGraphicBuffer.
232 EGLImageKHR mEglImage;
233
234 // mEglDisplay is the EGLDisplay used to create mEglImage.
235 EGLDisplay mEglDisplay;
236
237 // mFence is the EGL sync object that must signal before the buffer
238 // associated with this buffer slot may be dequeued. It is initialized
239 // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
240 // on a compile-time option) set to a new sync object in updateTexImage.
241 EGLSyncKHR mFence;
242 };
243
244 EGLSlot mEGLSlots[NUM_BUFFER_SLOTS];
245
246 // mAbandoned indicates that the BufferQueue will no longer be used to
247 // consume images buffers pushed to it using the ISurfaceTexture interface.
248 // It is initialized to false, and set to true in the abandon method. A
249 // BufferQueue that has been abandoned will return the NO_INIT error from
250 // all ISurfaceTexture methods capable of returning an error.
251 bool mAbandoned;
252
253 // mName is a string used to identify the SurfaceTexture in log messages.
254 // It can be set by the setName method.
255 String8 mName;
256
257 // mMutex is the mutex used to prevent concurrent access to the member
258 // variables of SurfaceTexture objects. It must be locked whenever the
259 // member variables are accessed.
260 mutable Mutex mMutex;
261
262 // mCurrentTexture is the buffer slot index of the buffer that is currently
263 // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
264 // indicating that no buffer slot is currently bound to the texture. Note,
265 // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
266 // that no buffer is bound to the texture. A call to setBufferCount will
267 // reset mCurrentTexture to INVALID_BUFFER_SLOT.
268 int mCurrentTexture;
269
Jamie Gennis8ba32fa2010-12-20 11:27:26 -0800270};
271
272// ----------------------------------------------------------------------------
273}; // namespace android
274
275#endif // ANDROID_GUI_SURFACETEXTURE_H