1 /*
2  * Cogl
3  *
4  * A Low Level GPU Graphics and Utilities API
5  *
6  * Copyright (C) 2011 Collabora Ltd.
7  * Copyright (C) 2012 Intel Corporation.
8  *
9  * Permission is hereby granted, free of charge, to any person
10  * obtaining a copy of this software and associated documentation
11  * files (the "Software"), to deal in the Software without
12  * restriction, including without limitation the rights to use, copy,
13  * modify, merge, publish, distribute, sublicense, and/or sell copies
14  * of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  *
29  * Authors:
30  *  Tomeu Vizoso <tomeu.vizoso@collabora.com>
31  *  Robert Bragg <robert@linux.intel.com>
32  *
33  */
34 
35 #ifndef __COGL_GLES2_CONTEXT_PRIVATE_H
36 #define __COGL_GLES2_CONTEXT_PRIVATE_H
37 
38 #include <glib.h>
39 
40 #include "cogl-object-private.h"
41 #include "cogl-framebuffer-private.h"
42 #include "cogl-list.h"
43 
44 typedef struct _CoglGLES2Offscreen
45 {
46   CoglList link;
47   CoglOffscreen *original_offscreen;
48   CoglGLFramebuffer gl_framebuffer;
49 } CoglGLES2Offscreen;
50 
51 typedef struct
52 {
53   /* GL's ID for the shader */
54   GLuint object_id;
55   /* Shader type */
56   GLenum type;
57 
58   /* Number of references to this shader. The shader will have one
59    * reference when it is created. This reference will be removed when
60    * glDeleteShader is called. An additional reference will be taken
61    * whenever the shader is attached to a program. This is necessary
62    * to correctly detect when a shader is destroyed because
63    * glDeleteShader doesn't actually delete the object if it is
64    * attached to a program */
65   int ref_count;
66 
67   /* Set once this object has had glDeleteShader called on it. We need
68    * to keep track of this so we don't deref the data twice if the
69    * application calls glDeleteShader multiple times */
70   CoglBool deleted;
71 } CoglGLES2ShaderData;
72 
73 typedef enum
74 {
75   COGL_GLES2_FLIP_STATE_UNKNOWN,
76   COGL_GLES2_FLIP_STATE_NORMAL,
77   COGL_GLES2_FLIP_STATE_FLIPPED
78 } CoglGLES2FlipState;
79 
80 typedef struct
81 {
82   /* GL's ID for the program */
83   GLuint object_id;
84 
85   /* List of shaders attached to this program */
86   GList *attached_shaders;
87 
88   /* Reference count. There can be up to two references. One of these
89    * will exist between glCreateProgram and glDeleteShader, the other
90    * will exist while the program is made current. This is necessary
91    * to correctly detect when the program is deleted because
92    * glDeleteShader will delay the deletion if the program is
93    * current */
94   int ref_count;
95 
96   /* Set once this object has had glDeleteProgram called on it. We need
97    * to keep track of this so we don't deref the data twice if the
98    * application calls glDeleteProgram multiple times */
99   CoglBool deleted;
100 
101   GLuint flip_vector_location;
102 
103   /* A cache of what value we've put in the flip vector uniform so
104    * that we don't flush unless it's changed */
105   CoglGLES2FlipState flip_vector_state;
106 
107   CoglGLES2Context *context;
108 } CoglGLES2ProgramData;
109 
110 /* State tracked for each texture unit */
111 typedef struct
112 {
113   /* The currently bound texture for the GL_TEXTURE_2D */
114   GLuint current_texture_2d;
115 } CoglGLES2TextureUnitData;
116 
117 /* State tracked for each texture object */
118 typedef struct
119 {
120   /* GL's ID for this object */
121   GLuint object_id;
122 
123   GLenum target;
124 
125   /* The details for texture when it has a 2D target */
126   int width, height;
127   GLenum format;
128 } CoglGLES2TextureObjectData;
129 
130 struct _CoglGLES2Context
131 {
132   CoglObject _parent;
133 
134   CoglContext *context;
135 
136   /* This is set to FALSE until the first time the GLES2 context is
137    * bound to something. We need to keep track of this so we can set
138    * the viewport and scissor the first time it is bound. */
139   CoglBool has_been_bound;
140 
141   CoglFramebuffer *read_buffer;
142   CoglGLES2Offscreen *gles2_read_buffer;
143   CoglFramebuffer *write_buffer;
144   CoglGLES2Offscreen *gles2_write_buffer;
145 
146   GLuint current_fbo_handle;
147 
148   CoglList foreign_offscreens;
149 
150   CoglGLES2Vtable *vtable;
151 
152   /* Hash table mapping GL's IDs for shaders and objects to ShaderData
153    * and ProgramData so that we can maintain extra data for these
154    * objects. Although technically the IDs will end up global across
155    * all GLES2 contexts because they will all be in the same share
156    * list, we don't really want to expose this outside of the Cogl API
157    * so we will assume it is undefined behaviour if an application
158    * relies on this. */
159   GHashTable *shader_map;
160   GHashTable *program_map;
161 
162   /* Currently in use program. We need to keep track of this so that
163    * we can keep a reference to the data for the program while it is
164    * current */
165   CoglGLES2ProgramData *current_program;
166 
167   /* Whether the currently bound framebuffer needs flipping. This is
168    * used to check for changes so that we can dirty the following
169    * state flags */
170   CoglGLES2FlipState current_flip_state;
171 
172   /* The following state is tracked separately from the GL context
173    * because we need to modify it depending on whether we are flipping
174    * the geometry. */
175   CoglBool viewport_dirty;
176   int viewport[4];
177   CoglBool scissor_dirty;
178   int scissor[4];
179   CoglBool front_face_dirty;
180   GLenum front_face;
181 
182   /* We need to keep track of the pack alignment so we can flip the
183    * results of glReadPixels read from a CoglOffscreen */
184   int pack_alignment;
185 
186   /* A hash table of CoglGLES2TextureObjects indexed by the texture
187    * object ID so that we can track some state */
188   GHashTable *texture_object_map;
189 
190   /* Array of CoglGLES2TextureUnits to keep track of state for each
191    * texture unit */
192   GArray *texture_units;
193 
194   /* The currently active texture unit indexed from 0 (not from
195    * GL_TEXTURE0) */
196   int current_texture_unit;
197 
198   void *winsys;
199 };
200 
201 #endif /* __COGL_GLES2_CONTEXT_PRIVATE_H */
202