+static void
+tex_parameters (Display *d, GLuint texture)
+{
+ // TODO: Check for (ARB|EXT|NV)_texture_rectangle. (All three are alike.)
+ // Rectangle textures should be present on OS X with the following exceptions:
+ // - Generic renderer on PowerPC OS X 10.4 and earlier
+ // - ATI Rage 128
+ glBindTexture (d->gl_texture_target, texture);
+ // TODO: This is all somewhere else. Refactor.
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ // This might be redundant for rectangular textures.
+# ifndef HAVE_JWZGLES
+ const GLint wrap = GL_CLAMP;
+# else // HAVE_JWZGLES
+ const GLint wrap = GL_CLAMP_TO_EDGE;
+# endif // HAVE_JWZGLES
+
+ // In OpenGL, CLAMP_TO_EDGE is OpenGL 1.2 or GL_SGIS_texture_edge_clamp.
+ // This is always present with OpenGL ES.
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_WRAP_S, wrap);
+ glTexParameteri (d->gl_texture_target, GL_TEXTURE_WRAP_T, wrap);
+}
+
+static void
+tex_size (Display *dpy, unsigned *tex_w, unsigned *tex_h)
+{
+ if (!dpy->gl_texture_npot_p) {
+ *tex_w = to_pow2(*tex_w);
+ *tex_h = to_pow2(*tex_h);
+ }
+}
+
+static void
+tex_image (Display *dpy, GLenum internalformat,
+ unsigned *tex_w, unsigned *tex_h, GLenum format, GLenum type,
+ const void *data)
+{
+ unsigned w = *tex_w, h = *tex_h;
+ tex_size (dpy, tex_w, tex_h);
+
+ // TODO: Would using glTexSubImage2D exclusively be faster?
+ if (*tex_w == w && *tex_h == h) {
+ glTexImage2D (dpy->gl_texture_target, 0, internalformat, *tex_w, *tex_h,
+ 0, format, type, data);
+ } else {
+ // TODO: Sampling the last row might be a problem if src_x != 0.
+ glTexImage2D (dpy->gl_texture_target, 0, internalformat, *tex_w, *tex_h,
+ 0, format, type, NULL);
+ glTexSubImage2D (dpy->gl_texture_target, 0, 0, 0, w, h,
+ format, type, data);
+ }
+}
+
+