summaryrefslogtreecommitdiff
path: root/glsize.hpp
diff options
context:
space:
mode:
authorJosé Fonseca <jose.r.fonseca@gmail.com>2011-06-03 00:42:25 +0100
committerJosé Fonseca <jose.r.fonseca@gmail.com>2011-06-03 00:51:14 +0100
commit9525989ae9c55ca3ddd8991454ad84d023cb30c3 (patch)
treef0cba6ed3420fd9f5923e075c4d6ae606145c03e /glsize.hpp
parente97bab9680a1f6f35fb48f56ffe94b3048e569e5 (diff)
Consider glPixelStore state in image size computation.
Diffstat (limited to 'glsize.hpp')
-rw-r--r--glsize.hpp55
1 files changed, 51 insertions, 4 deletions
diff --git a/glsize.hpp b/glsize.hpp
index 37e370d2..cff66d24 100644
--- a/glsize.hpp
+++ b/glsize.hpp
@@ -364,6 +364,18 @@ __gl_format_channels(GLenum format) {
}
}
+template<class X>
+static inline bool
+_is_pot(X x) {
+ return (x & (x - 1)) == 0;
+}
+
+template<class X, class Y>
+static inline X
+_align(X x, Y y) {
+ return (x + (y - 1)) & (y - 1);
+}
+
static inline size_t
__gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth) {
size_t num_channels = __gl_format_channels(format);
@@ -421,13 +433,48 @@ __gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsiz
break;
}
- /* FIXME: consider glPixelStore settings */
+ GLint alignment = 4;
+ GLint row_length = 0;
+ GLint image_height = 0;
+ GLint skip_rows = 0;
+ GLint skip_pixels = 0;
+ GLint skip_images = 0;
+
+ __glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
+ __glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
+ __glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &image_height);
+ __glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
+ __glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
+ __glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &skip_images);
+
+ if (row_length <= 0) {
+ row_length = width;
+ }
- size_t row_stride = (width*bits_per_pixel + 7)/8;
+ size_t row_stride = (row_length*bits_per_pixel + 7)/8;
- size_t slice_stride = height*row_stride;
+ if (bits_per_pixel < alignment*8 &&
+ (bits_per_pixel & 7) == 0 &&
+ _is_pot(bits_per_pixel)) {
+ row_stride = _align(row_stride, alignment);
+ }
- return depth*slice_stride;
+ if (image_height <= 0) {
+ image_height = height;
+ }
+
+ /* XXX: GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably
+ * not be considered for pixel rectangles. */
+
+ size_t image_stride = image_height*row_stride;
+
+ size_t size = depth*image_stride;
+
+ size += (skip_pixels*bits_per_pixel + 7)/8;
+ size += skip_rows*row_stride;
+ size += skip_images*image_stride;
+
+ return size;
}
#define __glTexParameterfv_size __gl_param_size