1 /*
2  * Copyright (C) 2011 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_FILTERFW_CORE_GL_FRAME_H
18 #define ANDROID_FILTERFW_CORE_GL_FRAME_H
19 
20 #include <map>
21 
22 #include <GLES2/gl2.h>
23 
24 #include "core/gl_buffer_interface.h"
25 
26 namespace android {
27 namespace filterfw {
28 
29 class GLEnv;
30 class ShaderProgram;
31 
32 // A GLFrame stores pixel data on the GPU. While pixel data may be uploaded to
33 // a GLFrame and also read out of a GLFrame (access in place is not supported),
34 // it is strongly recommended to use ShaderProgram objects for any kind of
35 // processing from one GLFrame to another.
36 class GLFrame : public GLBufferHandle {
37   public:
38     // Create an empty GL frame in the specified GL environment. Note, that the GLFrame does NOT
39     // take ownership. The caller must make sure the GLEnv stays valid as long as the GLFrame is
40     // alive.
41     explicit GLFrame(GLEnv* gl_env);
42 
43     // Deallocate a GL frame.
44     ~GLFrame();
45 
46     // Initialize a GL frame to the given width, height, format. Also specify
47     // whether this is a read-only GL frame or not.
48     bool Init(int width, int height);
49 
50     // Initialize as using an external texture.
51     bool InitWithExternalTexture();
52 
53     // Initialize using an existing texture.
54     bool InitWithTexture(GLint texture_id, int width, int height);
55 
56     // Initialize using an existing FBO.
57     bool InitWithFbo(GLint fbo_id, int width, int height);
58 
59     // Write the data with the given size in bytes to the frame. The frame size must match the
60     // size of the data.
61     bool WriteData(const uint8_t* data, int size);
62 
63     // Copies the frame data to the given buffer.
64     bool CopyDataTo(uint8_t* buffer, int size);
65 
66     // Copies the pixels from another GL frame to this frame.
67     bool CopyPixelsFrom(const GLFrame* frame);
68 
69     // Returns the size of the buffer in bytes.
70     int Size() const;
71 
72     // Clone the current frame by creating a new GL frame and copying all data to it.
73     GLFrame* Clone() const;
74 
75     // Returns the held texture id. Only call this if the GLFrame holds a
76     // texture. You can check this by calling HoldsTexture().
77     // Note, that a texture is created only when needed. If you are creating a
78     // new GLFrame, and you need it to be bound to a texture, upload (zeroed)
79     // data to it first, before calling this method.
80     GLuint GetTextureId() const;
81 
82     // Returns the held FBO id. Only call this if the GLFrame holds an FBO. You
83     // can check this by calling HoldsFbo().
84     GLuint GetFboId() const;
85 
86     // Returns the texture target: GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES.
GetTextureTarget()87     GLuint GetTextureTarget() const {
88       return texture_target_;
89     }
90 
91     // Set the viewport that will be used when focusing this frame for rendering. Defaults to
92     // the dimensions of the frame.
93     bool SetViewport(int x, int y, int width, int height);
94 
95     // Binds the held texture. This may result in creating the texture if it
96     // is not yet available.
97     bool FocusTexture();
98 
99     // Binds the held FBO. This may result in creating the FBO if it
100     // is not yet available.
101     bool FocusFrameBuffer();
102 
103     // Generates the mipmap chain of the held texture. Returns true, iff
104     // generating was successful.
105     bool GenerateMipMap();
106 
107     // Set a texture parameter (see glTextureParameter documentation). Returns
108     // true iff the parameter was set successfully.
109     bool SetTextureParameter(GLenum pname, GLint value);
110 
111     // Reset any modifed texture parameters.
112     bool ResetTexParameters();
113 
114     // Detaches the internal texture from the FBO.
115     bool DetachTextureFromFbo();
116 
117     // Reattaches the internal texture to the FBO after detachment.
118     bool ReattachTextureToFbo();
119 
120   private:
121     // Type to keep track of texture and FBO states
122     enum GLObjectState {
123       kStateUnmanaged,      // We do not manage this object (externally managed)
124       kStateUninitialized,  // Not yet initialized
125       kStateGenerated,      // Tex/FBO id is generated
126       kStateComplete        // FBO has valid attachment / Tex has valid pixel data
127     };
128 
129     // Sets the frame and viewport dimensions.
130     void InitDimensions(int width, int height);
131 
132     // Generates the internal texture name.
133     bool GenerateTextureName();
134 
135     // Allocates the internal texture.
136     bool AllocateTexture();
137 
138     // Creates the internal FBO.
139     bool GenerateFboName();
140 
141     // Copies pixels from texture or FBO to the specified buffer.
142     bool CopyPixelsTo(uint8_t* buffer);
143 
144     // Reads the pixels from the internal texture to the given buffer.
145     bool ReadTexturePixels(uint8_t* pixels) const;
146 
147     // Reads the pixels from the internal FBO to the given buffer.
148     bool ReadFboPixels(uint8_t* pixels) const;
149 
150     // Writes the specified pixels to the internal texture.
151     bool UploadTexturePixels(const uint8_t* pixels);
152 
153     // Binds the internal texture.
154     bool BindTexture() const;
155 
156     // Binds the internal FBO.
157     bool BindFrameBuffer() const;
158 
159     // Attaches the internal texture to the internal FBO.
160     bool AttachTextureToFbo();
161 
162     // Update the texture parameters to the user specified parameters
163     bool UpdateTexParameters();
164 
165     // Returns true if the current texture parameters are not the GLES2
166     // default parameters.
167     bool TexParametersModifed();
168 
169     // Sets the current texture parameters to the GLES2 default
170     // parameters. This still requires a call to UpdateTexParameters()
171     // for the changes to take effect.
172     void SetDefaultTexParameters();
173 
174     // Returns true if the texture we assume to be allocated has been
175     // deleted externally. In this case we assume the texture name is
176     // still valid (otherwise we were provided with a bad texture id).
177     bool TextureWasDeleted() const;
178 
179     // Get the (cached) identity shader.
180     ShaderProgram* GetIdentity() const;
181 
182     // The GL environment this frame belongs to
183     GLEnv* gl_env_;
184 
185     // The width, height and format of the frame
186     int width_;
187     int height_;
188 
189     // The viewport dimensions
190     int vp_x_;
191     int vp_y_;
192     int vp_width_;
193     int vp_height_;
194 
195     // The texture and FBO ids
196     GLuint texture_id_;
197     GLuint fbo_id_;
198 
199     // The texture target: GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES
200     GLuint texture_target_;
201 
202     // Flags whether or not frame holds a texture and FBO
203     GLObjectState texture_state_;
204     GLObjectState fbo_state_;
205 
206     // Set of current texture parameters
207     std::map<GLenum, GLint> tex_params_;
208 
209     // Flag whether frame owns the texture and FBO
210     bool owns_texture_;
211     bool owns_fbo_;
212 };
213 
214 } // namespace filterfw
215 } // namespace android
216 
217 #endif  // ANDROID_FILTERFW_CORE_GL_FRAME_H
218