-#include "mtypes.h"
+#include "main/mtypes.h"
+#include "main/formats.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "main/imports.h"
#include "drirenderbuffer.h"
-#include "renderbuffer.h"
-#include "imports.h"
/**
- * This will get called when a window is resized.
+ * This will get called when a window (gl_framebuffer) is resized (probably
+ * via driUpdateFramebufferSize(), below).
* Just update width, height and internal format fields for now.
* There's usually no memory allocation above because the present
- * DRI drivers use statically-allocated full-screen buffers.
+ * DRI drivers use statically-allocated full-screen buffers. If that's not
+ * the case for a DRI driver, a different AllocStorage method should
+ * be used.
*/
static GLboolean
driRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
* Allocate a new driRenderbuffer object.
* Individual drivers are free to implement different versions of
* this function.
+ *
+ * At this time, this function can only be used for window-system
+ * renderbuffers, not user-created RBOs.
+ *
* \param format Either GL_RGBA, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24,
* GL_DEPTH_COMPONENT32, or GL_STENCIL_INDEX8_EXT (for now).
+ * \param addr address in main memory of the buffer. Probably a memory
+ * mapped region.
* \param cpp chars or bytes per pixel
- * \param offset start of buffer with respect to framebuffer address
+ * \param offset start of renderbuffer with respect to start of framebuffer
* \param pitch pixels per row
*/
driRenderbuffer *
-driNewRenderbuffer(GLenum format, GLint cpp, GLint offset, GLint pitch)
+driNewRenderbuffer(gl_format format, GLvoid *addr,
+ GLint cpp, GLint offset, GLint pitch,
+ __DRIdrawablePrivate *dPriv)
{
driRenderbuffer *drb;
assert(format == GL_RGBA ||
+ format == GL_RGB5 ||
+ format == GL_RGBA8 ||
format == GL_DEPTH_COMPONENT16 ||
format == GL_DEPTH_COMPONENT24 ||
format == GL_DEPTH_COMPONENT32 ||
/* Make sure we're using a null-valued GetPointer routine */
assert(drb->Base.GetPointer(NULL, &drb->Base, 0, 0) == NULL);
- drb->Base.InternalFormat = format;
-
- if (format == GL_RGBA) {
- /* Color */
- drb->Base._BaseFormat = GL_RGBA;
+ switch (format) {
+ case MESA_FORMAT_ARGB8888:
+ if (cpp == 2) {
+ /* override format */
+ format = MESA_FORMAT_RGB565;
+ }
drb->Base.DataType = GL_UNSIGNED_BYTE;
- }
- else if (format == GL_DEPTH_COMPONENT16) {
+ break;
+ case MESA_FORMAT_Z16:
/* Depth */
- drb->Base._BaseFormat = GL_DEPTH_COMPONENT;
/* we always Get/Put 32-bit Z values */
drb->Base.DataType = GL_UNSIGNED_INT;
- }
- else if (format == GL_DEPTH_COMPONENT24) {
+ assert(cpp == 2);
+ break;
+ case MESA_FORMAT_Z32:
/* Depth */
- drb->Base._BaseFormat = GL_DEPTH_COMPONENT;
/* we always Get/Put 32-bit Z values */
drb->Base.DataType = GL_UNSIGNED_INT;
- }
- else {
+ assert(cpp == 4);
+ break;
+ case MESA_FORMAT_Z24_S8:
+ drb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ assert(cpp == 4);
+ break;
+ case MESA_FORMAT_S8_Z24:
+ drb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT;
+ assert(cpp == 4);
+ break;
+ case MESA_FORMAT_S8:
/* Stencil */
- ASSERT(format == GL_STENCIL_INDEX8);
- drb->Base._BaseFormat = GL_STENCIL_INDEX;
drb->Base.DataType = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ _mesa_problem(NULL, "Bad format 0x%x in driNewRenderbuffer", format);
+ return NULL;
}
- /* XXX if we were allocating a user-created renderbuffer, we'd have
- * to fill in the ComponentSizes[] array too.
- */
+ drb->Base.Format = format;
+
+ drb->Base.InternalFormat =
+ drb->Base._BaseFormat = _mesa_get_format_base_format(format);
drb->Base.AllocStorage = driRenderbufferStorage;
drb->Base.Delete = driDeleteRenderbuffer;
+ drb->Base.Data = addr;
+
/* DRI renderbuffer-specific fields: */
+ drb->dPriv = dPriv;
drb->offset = offset;
drb->pitch = pitch;
drb->cpp = cpp;
/* may be changed if page flipping is active: */
drb->flippedOffset = offset;
drb->flippedPitch = pitch;
+ drb->flippedData = addr;
}
return drb;
}
const GLuint count = fb->Visual.stereoMode ? 2 : 1;
GLuint lr; /* left or right */
- ASSERT(fb->Visual.doubleBufferMode);
+ /* we shouldn't really call this function if single-buffered, but
+ * play it safe.
+ */
+ if (!fb->Visual.doubleBufferMode)
+ return;
for (lr = 0; lr < count; lr++) {
GLuint frontBuf = (lr == 0) ? BUFFER_FRONT_LEFT : BUFFER_FRONT_RIGHT;
}
}
}
+
+
+/**
+ * Check that the gl_framebuffer associated with dPriv is the right size.
+ * Resize the gl_framebuffer if needed.
+ * It's expected that the dPriv->driverPrivate member points to a
+ * gl_framebuffer object.
+ */
+void
+driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv)
+{
+ struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
+ if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
+ ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
+ /* if the driver needs the hw lock for ResizeBuffers, the drawable
+ might have changed again by now */
+ assert(fb->Width == dPriv->w);
+ assert(fb->Height == dPriv->h);
+ }
+}