1 /* 2 * Copyright (c) 2003, 2012, 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_PBUFFER, 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_PBUFFER sun_java2d_pipe_hw_AccelSurface_RT_PLAIN 222 #define OGLSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE 223 #define OGLSD_FLIP_BACKBUFFER sun_java2d_pipe_hw_AccelSurface_FLIP_BACKBUFFER 224 #define OGLSD_FBOBJECT sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE 225 226 /** 227 * These are shorthand names for the filtering method constants used by 228 * image transform methods. 229 */ 230 #define OGLSD_XFORM_DEFAULT 0 231 #define OGLSD_XFORM_NEAREST_NEIGHBOR \ 232 java_awt_image_AffineTransformOp_TYPE_NEAREST_NEIGHBOR 233 #define OGLSD_XFORM_BILINEAR \ 234 java_awt_image_AffineTransformOp_TYPE_BILINEAR 235 236 /** 237 * Helper macros that update the current texture filter state only when 238 * it needs to be changed, which helps reduce overhead for small texturing 239 * operations. The filter state is set on a per-texture (not per-context) 240 * basis; for example, it is possible for one texture to be using GL_NEAREST 241 * while another texture uses GL_LINEAR under the same context. 242 */ 243 #define OGLSD_INIT_TEXTURE_FILTER(oglSDOps, filter) \ 244 do { \ 245 j2d_glTexParameteri((oglSDOps)->textureTarget, \ 246 GL_TEXTURE_MAG_FILTER, (filter)); \ 247 j2d_glTexParameteri((oglSDOps)->textureTarget, \ 248 GL_TEXTURE_MIN_FILTER, (filter)); \ 249 (oglSDOps)->textureFilter = (filter); \ 250 } while (0) 251 252 #define OGLSD_UPDATE_TEXTURE_FILTER(oglSDOps, filter) \ 253 do { \ 254 if ((oglSDOps)->textureFilter != (filter)) { \ 255 OGLSD_INIT_TEXTURE_FILTER(oglSDOps, filter); \ 256 } \ 257 } while (0) 258 259 /** 260 * Convenience macros for setting the texture wrap mode for a given target. 261 * The texture wrap mode should be reset to our default value of 262 * GL_CLAMP_TO_EDGE by calling OGLSD_RESET_TEXTURE_WRAP() when a texture 263 * is first created. If another mode is needed (e.g. GL_REPEAT in the case 264 * of TexturePaint acceleration), one can call the OGLSD_UPDATE_TEXTURE_WRAP() 265 * macro to easily set up the new wrap mode. However, it is important to 266 * restore the wrap mode back to its default value (by calling the 267 * OGLSD_RESET_TEXTURE_WRAP() macro) when the operation is finished. 268 */ 269 #define OGLSD_UPDATE_TEXTURE_WRAP(target, wrap) \ 270 do { \ 271 j2d_glTexParameteri((target), GL_TEXTURE_WRAP_S, (wrap)); \ 272 j2d_glTexParameteri((target), GL_TEXTURE_WRAP_T, (wrap)); \ 273 } while (0) 274 275 #define OGLSD_RESET_TEXTURE_WRAP(target) \ 276 OGLSD_UPDATE_TEXTURE_WRAP(target, GL_CLAMP_TO_EDGE) 277 278 /** 279 * Exported methods. 280 */ 281 jint OGLSD_Lock(JNIEnv *env, 282 SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo, 283 jint lockflags); 284 void OGLSD_GetRasInfo(JNIEnv *env, 285 SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo); 286 void OGLSD_Unlock(JNIEnv *env, 287 SurfaceDataOps *ops, SurfaceDataRasInfo *pRasInfo); 288 void OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops); 289 void OGLSD_Delete(JNIEnv *env, OGLSDOps *oglsdo); 290 jint OGLSD_NextPowerOfTwo(jint val, jint max); 291 jboolean OGLSD_InitFBObject(GLuint *fbobjectID, GLuint *depthID, 292 GLuint textureID, GLenum textureTarget, 293 jint textureWidth, jint textureHeight); 294 295 #endif /* OGLSurfaceData_h_Included */