1 | /* |
2 | * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Oracle designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Oracle in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 | * or visit www.oracle.com if you need additional information or have any |
23 | * questions. |
24 | */ |
25 | |
26 | #ifndef OGLSurfaceData_h_Included |
27 | #define OGLSurfaceData_h_Included |
28 | |
29 | #include "java_awt_image_AffineTransformOp.h" |
30 | #include "sun_java2d_opengl_OGLSurfaceData.h" |
31 | #include "sun_java2d_pipe_hw_AccelSurface.h" |
32 | |
33 | #include "J2D_GL/gl.h" |
34 | #include "SurfaceData.h" |
35 | #include "Trace.h" |
36 | #include "OGLFuncs.h" |
37 | |
38 | typedef struct _OGLSDOps OGLSDOps; |
39 | |
40 | /** |
41 | * The OGLPixelFormat structure contains all the information OpenGL needs to |
42 | * know when copying from or into a particular system memory image buffer (via |
43 | * glDrawPixels(), glReadPixels, glTexSubImage2D(), etc). |
44 | * |
45 | * GLenum format; |
46 | * The pixel format parameter used in glDrawPixels() and other similar calls. |
47 | * Indicates the component ordering for each pixel (e.g. GL_BGRA). |
48 | * |
49 | * GLenum type; |
50 | * The pixel data type parameter used in glDrawPixels() and other similar |
51 | * calls. Indicates the data type for an entire pixel or for each component |
52 | * in a pixel (e.g. GL_UNSIGNED_BYTE with GL_BGR means a pixel consists of |
53 | * 3 unsigned byte components, blue first, then green, then red; |
54 | * GL_UNSIGNED_INT_8_8_8_8_REV with GL_BGRA means a pixel consists of 1 |
55 | * unsigned integer comprised of four byte components, alpha first, then red, |
56 | * then green, then blue). |
57 | * |
58 | * jint alignment; |
59 | * The byte alignment parameter used in glPixelStorei(GL_UNPACK_ALIGNMENT). A |
60 | * value of 4 indicates that each pixel starts on a 4-byte aligned region in |
61 | * memory, and so on. This alignment parameter helps OpenGL speed up pixel |
62 | * transfer operations by transferring memory in aligned blocks. |
63 | * |
64 | * jboolean hasAlpha; |
65 | * If true, indicates that this pixel format contains an alpha component. |
66 | * |
67 | * jboolean isPremult; |
68 | * If true, indicates that this pixel format contains color components that |
69 | * have been pre-multiplied by their corresponding alpha component. |
70 | */ |
71 | typedef struct { |
72 | GLenum format; |
73 | GLenum type; |
74 | jint alignment; |
75 | jboolean hasAlpha; |
76 | jboolean isPremult; |
77 | } OGLPixelFormat; |
78 | |
79 | /** |
80 | * The OGLSDOps structure describes a native OpenGL surface and contains all |
81 | * information pertaining to the native surface. Some information about |
82 | * the more important/different fields: |
83 | * |
84 | * void *privOps; |
85 | * Pointer to native-specific (GLX, WGL, etc.) SurfaceData info, such as the |
86 | * native Drawable handle and GraphicsConfig data. |
87 | * |
88 | * jint drawableType; |
89 | * The surface type; can be any one of the surface type constants defined |
90 | * below (OGLSD_WINDOW, OGLSD_TEXTURE, etc). |
91 | * |
92 | * GLenum activeBuffer; |
93 | * Can be either GL_FRONT if this is the front buffer surface of an onscreen |
94 | * window or a pbuffer surface, or GL_BACK if this is the backbuffer surface |
95 | * of an onscreen window. |
96 | * |
97 | * jboolean isOpaque; |
98 | * If true, the surface should be treated as being fully opaque. If |
99 | * the underlying surface (e.g. pbuffer) has an alpha channel and isOpaque |
100 | * is true, then we should take appropriate action (i.e. call glColorMask() |
101 | * to disable writes into the alpha channel) to ensure that the surface |
102 | * remains fully opaque. |
103 | * |
104 | * jboolean needsInit; |
105 | * If true, the surface requires some one-time initialization, which should |
106 | * be performed after a context has been made current to the surface for |
107 | * the first time. |
108 | * |
109 | * jint x/yOffset |
110 | * The offset in pixels of the OpenGL viewport origin from the lower-left |
111 | * corner of the heavyweight drawable. For example, a top-level frame on |
112 | * Windows XP has lower-left insets of (4,4). The OpenGL viewport origin |
113 | * would typically begin at the lower-left corner of the client region (inside |
114 | * the frame decorations), but AWT/Swing will take the insets into account |
115 | * when rendering into that window. So in order to account for this, we |
116 | * need to adjust the OpenGL viewport origin by an x/yOffset of (-4,-4). On |
117 | * X11, top-level frames typically don't have this insets issue, so their |
118 | * x/yOffset would be (0,0) (the same applies to pbuffers). |
119 | * |
120 | * jint width/height; |
121 | * The cached surface bounds. For offscreen surface types (OGLSD_FBOBJECT, |
122 | * OGLSD_TEXTURE, etc.) these values must remain constant. Onscreen window |
123 | * surfaces (OGLSD_WINDOW, OGLSD_FLIP_BACKBUFFER, etc.) may have their |
124 | * bounds changed in response to a programmatic or user-initiated event, so |
125 | * these values represent the last known dimensions. To determine the true |
126 | * current bounds of this surface, query the native Drawable through the |
127 | * privOps field. |
128 | * |
129 | * GLuint textureID; |
130 | * The texture object handle, as generated by glGenTextures(). If this value |
131 | * is zero, the texture has not yet been initialized. |
132 | * |
133 | * jint textureWidth/Height; |
134 | * The actual bounds of the texture object for this surface. If the |
135 | * GL_ARB_texture_non_power_of_two extension is not present, the dimensions |
136 | * of an OpenGL texture object must be a power-of-two (e.g. 64x32 or 128x512). |
137 | * The texture image that we care about has dimensions specified by the width |
138 | * and height fields in this OGLSDOps structure. For example, if the image |
139 | * to be stored in the texture has dimensions 115x47, the actual OpenGL |
140 | * texture we allocate will have dimensions 128x64 to meet the pow2 |
141 | * restriction. The image bounds within the texture can be accessed using |
142 | * floating point texture coordinates in the range [0.0,1.0]. |
143 | * |
144 | * GLenum textureTarget; |
145 | * The texture target of the texture object for this surface. If this |
146 | * surface is not backed by a texture, this value is set to zero. Otherwise, |
147 | * this value is GL_TEXTURE_RECTANGLE_ARB when the GL_ARB_texture_rectangle |
148 | * extension is in use; if not, it is set to GL_TEXTURE_2D. |
149 | * |
150 | * GLint textureFilter; |
151 | * The current filter state for this texture object (can be either GL_NEAREST |
152 | * or GL_LINEAR). We cache this value here and check it before updating |
153 | * the filter state to avoid redundant calls to glTexParameteri() when the |
154 | * filter state remains constant (see the OGLSD_UPDATE_TEXTURE_FILTER() |
155 | * macro below). |
156 | * |
157 | * GLuint fbobjectID, depthID; |
158 | * The object handles for the framebuffer object and depth renderbuffer |
159 | * associated with this surface. These fields are only used when |
160 | * drawableType is OGLSD_FBOBJECT, otherwise they are zero. |
161 | */ |
162 | struct _OGLSDOps { |
163 | SurfaceDataOps sdOps; |
164 | void *privOps; |
165 | jint drawableType; |
166 | GLenum activeBuffer; |
167 | jboolean isOpaque; |
168 | jboolean needsInit; |
169 | jint xOffset; |
170 | jint yOffset; |
171 | jint width; |
172 | jint height; |
173 | GLuint textureID; |
174 | jint textureWidth; |
175 | jint textureHeight; |
176 | GLenum textureTarget; |
177 | GLint textureFilter; |
178 | GLuint fbobjectID; |
179 | GLuint depthID; |
180 | }; |
181 | |
182 | /** |
183 | * The following convenience macros are used when rendering rectangles (either |
184 | * a single rectangle, or a whole series of them). To render a single |
185 | * rectangle, simply invoke the GLRECT() macro. To render a whole series of |
186 | * rectangles, such as spans in a complex shape, first invoke GLRECT_BEGIN(), |
187 | * then invoke the appropriate inner loop macro (either XYXY or XYWH) for |
188 | * each rectangle, and finally invoke GLRECT_END() to notify OpenGL that the |
189 | * vertex list is complete. Care should be taken to avoid calling OpenGL |
190 | * commands (besides GLRECT_BODY_*()) inside the BEGIN/END pair. |
191 | */ |
192 | |
193 | #define GLRECT_BEGIN j2d_glBegin(GL_QUADS) |
194 | |
195 | #define GLRECT_BODY_XYXY(x1, y1, x2, y2) \ |
196 | do { \ |
197 | j2d_glVertex2i(x1, y1); \ |
198 | j2d_glVertex2i(x2, y1); \ |
199 | j2d_glVertex2i(x2, y2); \ |
200 | j2d_glVertex2i(x1, y2); \ |
201 | } while (0) |
202 | |
203 | #define GLRECT_BODY_XYWH(x, y, w, h) \ |
204 | GLRECT_BODY_XYXY(x, y, (x) + (w), (y) + (h)) |
205 | |
206 | #define GLRECT_END j2d_glEnd() |
207 | |
208 | #define GLRECT(x, y, w, h) \ |
209 | do { \ |
210 | GLRECT_BEGIN; \ |
211 | GLRECT_BODY_XYWH(x, y, w, h); \ |
212 | GLRECT_END; \ |
213 | } while (0) |
214 | |
215 | /** |
216 | * These are shorthand names for the surface type constants defined in |
217 | * OGLSurfaceData.java. |
218 | */ |
219 | #define OGLSD_UNDEFINED sun_java2d_pipe_hw_AccelSurface_UNDEFINED |
220 | #define OGLSD_WINDOW sun_java2d_pipe_hw_AccelSurface_WINDOW |
221 | #define OGLSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE |
222 | #define OGLSD_FLIP_BACKBUFFER sun_java2d_pipe_hw_AccelSurface_FLIP_BACKBUFFER |
223 | #define OGLSD_FBOBJECT sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE |
224 | |
225 | /** |
226 | * These are shorthand names for the filtering method constants used by |
227 | * image transform methods. |
228 | */ |
229 | #define OGLSD_XFORM_DEFAULT 0 |
230 | #define OGLSD_XFORM_NEAREST_NEIGHBOR \ |
231 | java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR |
232 | #define OGLSD_XFORM_BILINEAR \ |
233 | java_awt_image_AffineTransformOp_TYPE_BILINEAR |
234 | |
235 | /** |
236 | * Helper macros that update the current texture filter state only when |
237 | * it needs to be changed, which helps reduce overhead for small texturing |
238 | * operations. The filter state is set on a per-texture (not per-context) |
239 | * basis; for example, it is possible for one texture to be using GL_NEAREST |
240 | * while another texture uses GL_LINEAR under the same context. |
241 | */ |
242 | #define OGLSD_INIT_TEXTURE_FILTER(oglSDOps, filter) \ |
243 | do { \ |
244 | j2d_glTexParameteri((oglSDOps)->textureTarget, \ |
245 | GL_TEXTURE_MAG_FILTER, (filter)); \ |
246 | j2d_glTexParameteri((oglSDOps)->textureTarget, \ |
247 | GL_TEXTURE_MIN_FILTER, (filter)); \ |
248 | (oglSDOps)->textureFilter = (filter); \ |
249 | } while (0) |
250 | |
251 | #define OGLSD_UPDATE_TEXTURE_FILTER(oglSDOps, filter) \ |
252 | do { \ |
253 | if ((oglSDOps)->textureFilter != (filter)) { \ |
254 | OGLSD_INIT_TEXTURE_FILTER(oglSDOps, filter); \ |
255 | } \ |
256 | } while (0) |
257 | |
258 | /** |
259 | * Convenience macros for setting the texture wrap mode for a given target. |
260 | * The texture wrap mode should be reset to our default value of |
261 | * GL_CLAMP_TO_EDGE by calling OGLSD_RESET_TEXTURE_WRAP() when a texture |
262 | * is first created. If another mode is needed (e.g. GL_REPEAT in the case |
263 | * of TexturePaint acceleration), one can call the OGLSD_UPDATE_TEXTURE_WRAP() |
264 | * macro to easily set up the new wrap mode. However, it is important to |
265 | * restore the wrap mode back to its default value (by calling the |
266 | * OGLSD_RESET_TEXTURE_WRAP() macro) when the operation is finished. |
267 | */ |
268 | #define OGLSD_UPDATE_TEXTURE_WRAP(target, wrap) \ |
269 | do { \ |
270 | j2d_glTexParameteri((target), GL_TEXTURE_WRAP_S, (wrap)); \ |
271 | j2d_glTexParameteri((target), GL_TEXTURE_WRAP_T, (wrap)); \ |
272 | } while (0) |
273 | |
274 | #define OGLSD_RESET_TEXTURE_WRAP(target) \ |
275 | OGLSD_UPDATE_TEXTURE_WRAP(target, GL_CLAMP_TO_EDGE) |
276 | |
277 | /** |
278 | * Exported methods. |
279 | */ |
280 | jint OGLSD_Lock(JNIEnv *env, |
281 | SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo, |
282 | jint lockflags); |
283 | void OGLSD_GetRasInfo(JNIEnv *env, |
284 | SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo); |
285 | void OGLSD_Unlock(JNIEnv *env, |
286 | SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo); |
287 | void OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops); |
288 | void OGLSD_Delete(JNIEnv *env, OGLSDOps *oglsdo); |
289 | jint OGLSD_NextPowerOfTwo(jint val, jint max); |
290 | jboolean OGLSD_InitFBObject(GLuint *fbobjectID, GLuint *depthID, |
291 | GLuint textureID, GLenum textureTarget, |
292 | jint textureWidth, jint textureHeight); |
293 | |
294 | #endif /* OGLSurfaceData_h_Included */ |
295 | |