summaryrefslogtreecommitdiff
path: root/cogl/cogl/cogl-framebuffer-private.h
diff options
context:
space:
mode:
Diffstat (limited to 'cogl/cogl/cogl-framebuffer-private.h')
-rw-r--r--cogl/cogl/cogl-framebuffer-private.h514
1 files changed, 514 insertions, 0 deletions
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
new file mode 100644
index 000000000..99ac2fba9
--- /dev/null
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -0,0 +1,514 @@
+/*
+ * Cogl
+ *
+ * A Low Level GPU Graphics and Utilities API
+ *
+ * Copyright (C) 2007,2008,2009 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ */
+
+#ifndef __COGL_FRAMEBUFFER_PRIVATE_H
+#define __COGL_FRAMEBUFFER_PRIVATE_H
+
+#include "cogl-object-private.h"
+#include "cogl-matrix-stack-private.h"
+#include "cogl-journal-private.h"
+#include "cogl-winsys-private.h"
+#include "cogl-attribute-private.h"
+#include "cogl-offscreen.h"
+#include "cogl-gl-header.h"
+#include "cogl-clip-stack.h"
+
+#ifdef COGL_HAS_XLIB_SUPPORT
+#include <X11/Xlib.h>
+#endif
+
+#ifdef COGL_HAS_GLX_SUPPORT
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#endif
+
+typedef enum _CoglFramebufferType {
+ COGL_FRAMEBUFFER_TYPE_ONSCREEN,
+ COGL_FRAMEBUFFER_TYPE_OFFSCREEN
+} CoglFramebufferType;
+
+typedef struct
+{
+ CoglSwapChain *swap_chain;
+ CoglBool need_stencil;
+ int samples_per_pixel;
+ CoglBool swap_throttled;
+ CoglBool depth_texture_enabled;
+ CoglBool stereo_enabled;
+} CoglFramebufferConfig;
+
+/* Flags to pass to _cogl_offscreen_new_with_texture_full */
+typedef enum
+{
+ COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL = 1
+} CoglOffscreenFlags;
+
+/* XXX: The order of these indices determines the order they are
+ * flushed.
+ *
+ * Flushing clip state may trash the modelview and projection matrices
+ * so we must do it before flushing the matrices.
+ */
+typedef enum _CoglFramebufferStateIndex
+{
+ COGL_FRAMEBUFFER_STATE_INDEX_BIND = 0,
+ COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT = 1,
+ COGL_FRAMEBUFFER_STATE_INDEX_CLIP = 2,
+ COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3,
+ COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4,
+ COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5,
+ COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
+ COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
+ COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8,
+ COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 9,
+ COGL_FRAMEBUFFER_STATE_INDEX_MAX = 10
+} CoglFramebufferStateIndex;
+
+typedef enum _CoglFramebufferState
+{
+ COGL_FRAMEBUFFER_STATE_BIND = 1<<0,
+ COGL_FRAMEBUFFER_STATE_VIEWPORT = 1<<1,
+ COGL_FRAMEBUFFER_STATE_CLIP = 1<<2,
+ COGL_FRAMEBUFFER_STATE_DITHER = 1<<3,
+ COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4,
+ COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
+ COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
+ COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
+ COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8,
+ COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<9
+} CoglFramebufferState;
+
+#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
+
+/* Private flags that can internally be added to CoglReadPixelsFlags */
+typedef enum
+{
+ /* If this is set then the data will not be flipped to compensate
+ for GL's upside-down coordinate system but instead will be left
+ in whatever order GL gives us (which will depend on whether the
+ framebuffer is offscreen or not) */
+ COGL_READ_PIXELS_NO_FLIP = 1L << 30
+} CoglPrivateReadPixelsFlags;
+
+typedef struct
+{
+ int red;
+ int blue;
+ int green;
+ int alpha;
+ int depth;
+ int stencil;
+} CoglFramebufferBits;
+
+struct _CoglFramebuffer
+{
+ CoglObject _parent;
+ CoglContext *context;
+ CoglFramebufferType type;
+
+ /* The user configuration before allocation... */
+ CoglFramebufferConfig config;
+
+ int width;
+ int height;
+ /* Format of the pixels in the framebuffer (including the expected
+ premult state) */
+ CoglPixelFormat internal_format;
+ CoglBool allocated;
+
+ CoglMatrixStack *modelview_stack;
+ CoglMatrixStack *projection_stack;
+ float viewport_x;
+ float viewport_y;
+ float viewport_width;
+ float viewport_height;
+ int viewport_age;
+ int viewport_age_for_scissor_workaround;
+
+ CoglClipStack *clip_stack;
+
+ CoglBool dither_enabled;
+ CoglBool depth_writing_enabled;
+ CoglColorMask color_mask;
+ CoglStereoMode stereo_mode;
+
+ /* We journal the textured rectangles we want to submit to OpenGL so
+ * we have an oppertunity to batch them together into less draw
+ * calls. */
+ CoglJournal *journal;
+
+ /* The scene of a given framebuffer may depend on images in other
+ * framebuffers... */
+ GList *deps;
+
+ /* As part of an optimization for reading-back single pixels from a
+ * framebuffer in some simple cases where the geometry is still
+ * available in the journal we need to track the bounds of the last
+ * region cleared, its color and we need to track when something
+ * does in fact draw to that region so it is no longer clear.
+ */
+ float clear_color_red;
+ float clear_color_green;
+ float clear_color_blue;
+ float clear_color_alpha;
+ int clear_clip_x0;
+ int clear_clip_y0;
+ int clear_clip_x1;
+ int clear_clip_y1;
+ CoglBool clear_clip_dirty;
+
+ /* Whether something has been drawn to the buffer since the last
+ * swap buffers or swap region. */
+ CoglBool mid_scene;
+
+ /* driver specific */
+ CoglBool dirty_bitmasks;
+ CoglFramebufferBits bits;
+
+ int samples_per_pixel;
+};
+
+typedef enum {
+ COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL = 1L<<0,
+ COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH = 1L<<1,
+ COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL = 1L<<2
+} CoglOffscreenAllocateFlags;
+
+typedef struct _CoglGLFramebuffer
+{
+ GLuint fbo_handle;
+ GList *renderbuffers;
+ int samples_per_pixel;
+} CoglGLFramebuffer;
+
+struct _CoglOffscreen
+{
+ CoglFramebuffer _parent;
+
+ CoglGLFramebuffer gl_framebuffer;
+
+ CoglTexture *texture;
+ int texture_level;
+
+ CoglTexture *depth_texture;
+
+ CoglOffscreenAllocateFlags allocation_flags;
+
+ /* FIXME: _cogl_offscreen_new_with_texture_full should be made to use
+ * fb->config to configure if we want a depth or stencil buffer so
+ * we can get rid of these flags */
+ CoglOffscreenFlags create_flags;
+};
+
+void
+_cogl_framebuffer_init (CoglFramebuffer *framebuffer,
+ CoglContext *ctx,
+ CoglFramebufferType type,
+ int width,
+ int height);
+
+/* XXX: For a public api we might instead want a way to explicitly
+ * set the _premult status of a framebuffer or what components we
+ * care about instead of exposing the CoglPixelFormat
+ * internal_format.
+ *
+ * The current use case for this api is where we create an offscreen
+ * framebuffer for a shared atlas texture that has a format of
+ * RGBA_8888 disregarding the premultiplied alpha status for
+ * individual atlased textures or whether the alpha component is being
+ * discarded. We want to overried the internal_format that will be
+ * derived from the texture.
+ */
+void
+_cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer,
+ CoglPixelFormat internal_format);
+
+void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
+
+const CoglWinsysVtable *
+_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
+ unsigned long buffers,
+ float red,
+ float green,
+ float blue,
+ float alpha);
+
+void
+_cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_mark_mid_scene (CoglFramebuffer *framebuffer);
+
+/*
+ * _cogl_framebuffer_get_clip_stack:
+ * @framebuffer: A #CoglFramebuffer
+ *
+ * Gets a pointer to the current clip stack. This can be used to later
+ * return to the same clip stack state with
+ * _cogl_framebuffer_set_clip_stack(). A reference is not taken on the
+ * stack so if you want to keep it you should call
+ * _cogl_clip_stack_ref().
+ *
+ * Return value: a pointer to the @framebuffer clip stack.
+ */
+CoglClipStack *
+_cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer);
+
+/*
+ * _cogl_framebuffer_set_clip_stack:
+ * @framebuffer: A #CoglFramebuffer
+ * @stack: a pointer to the replacement clip stack
+ *
+ * Replaces the @framebuffer clip stack with @stack.
+ */
+void
+_cogl_framebuffer_set_clip_stack (CoglFramebuffer *framebuffer,
+ CoglClipStack *stack);
+
+CoglMatrixStack *
+_cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer);
+
+CoglMatrixStack *
+_cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer,
+ CoglFramebuffer *dependency);
+
+void
+_cogl_framebuffer_remove_all_dependencies (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
+ CoglFramebuffer *read_buffer,
+ CoglFramebufferState state);
+
+CoglFramebuffer *
+_cogl_get_read_framebuffer (void);
+
+GSList *
+_cogl_create_framebuffer_stack (void);
+
+void
+_cogl_free_framebuffer_stack (GSList *stack);
+
+/*
+ * _cogl_offscreen_new_with_texture_full:
+ * @texture: A #CoglTexture pointer
+ * @create_flags: Flags specifying how to create the FBO
+ * @level: The mipmap level within the texture to target
+ *
+ * Creates a new offscreen buffer which will target the given
+ * texture. By default the buffer will have a depth and stencil
+ * buffer. This can be disabled by passing
+ * %COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL in @create_flags.
+ *
+ * Return value: the new CoglOffscreen object.
+ */
+CoglOffscreen *
+_cogl_offscreen_new_with_texture_full (CoglTexture *texture,
+ CoglOffscreenFlags create_flags,
+ int level);
+
+/*
+ * _cogl_push_framebuffers:
+ * @draw_buffer: A pointer to the buffer used for drawing
+ * @read_buffer: A pointer to the buffer used for reading back pixels
+ *
+ * Redirects drawing and reading to the specified framebuffers as in
+ * cogl_push_framebuffer() except that it allows the draw and read
+ * buffer to be different. The buffers are pushed as a pair so that
+ * they can later both be restored with a single call to
+ * cogl_pop_framebuffer().
+ */
+void
+_cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
+ CoglFramebuffer *read_buffer);
+
+/*
+ * _cogl_blit_framebuffer:
+ * @src: The source #CoglFramebuffer
+ * @dest: The destination #CoglFramebuffer
+ * @src_x: Source x position
+ * @src_y: Source y position
+ * @dst_x: Destination x position
+ * @dst_y: Destination y position
+ * @width: Width of region to copy
+ * @height: Height of region to copy
+ *
+ * This blits a region of the color buffer of the current draw buffer
+ * to the current read buffer. The draw and read buffers can be set up
+ * using _cogl_push_framebuffers(). This function should only be
+ * called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
+ * advertised. The two buffers must both be offscreen and have the
+ * same format.
+ *
+ * Note that this function differs a lot from the glBlitFramebuffer
+ * function provided by the GL_EXT_framebuffer_blit extension. Notably
+ * it doesn't support having different sizes for the source and
+ * destination rectangle. This isn't supported by the corresponding
+ * GL_ANGLE_framebuffer_blit extension on GLES2.0 and it doesn't seem
+ * like a particularly useful feature. If the application wanted to
+ * scale the results it may make more sense to draw a primitive
+ * instead.
+ *
+ * We can only really support blitting between two offscreen buffers
+ * for this function on GLES2.0. This is because we effectively render
+ * upside down to offscreen buffers to maintain Cogl's representation
+ * of the texture coordinate system where 0,0 is the top left of the
+ * texture. If we were to blit from an offscreen to an onscreen buffer
+ * then we would need to mirror the blit along the x-axis but the GLES
+ * extension does not support this.
+ *
+ * The GL function is documented to be affected by the scissor. This
+ * function therefore ensure that an empty clip stack is flushed
+ * before performing the blit which means the scissor is effectively
+ * ignored.
+ *
+ * The function also doesn't support specifying the buffers to copy
+ * and instead only the color buffer is copied. When copying the depth
+ * or stencil buffers the extension on GLES2.0 only supports copying
+ * the full buffer which would be awkward to document with this
+ * API. If we wanted to support that feature it may be better to have
+ * a separate function to copy the entire buffer for a given mask.
+ */
+void
+_cogl_blit_framebuffer (CoglFramebuffer *src,
+ CoglFramebuffer *dest,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height);
+
+void
+_cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_pop_projection (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_save_clip_stack (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer);
+
+void
+_cogl_framebuffer_unref (CoglFramebuffer *framebuffer);
+
+/* This can be called directly by the CoglJournal to draw attributes
+ * skipping the implicit journal flush, the framebuffer flush and
+ * pipeline validation. */
+void
+_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglDrawFlags flags);
+
+void
+_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
+ CoglPipeline *pipeline,
+ CoglVerticesMode mode,
+ int first_vertex,
+ int n_vertices,
+ CoglIndices *indices,
+ CoglAttribute **attributes,
+ int n_attributes,
+ CoglDrawFlags flags);
+
+gboolean
+_cogl_framebuffer_try_creating_gl_fbo (CoglContext *ctx,
+ CoglTexture *texture,
+ int texture_level,
+ int texture_level_width,
+ int texture_level_height,
+ CoglTexture *depth_texture,
+ CoglFramebufferConfig *config,
+ CoglOffscreenAllocateFlags flags,
+ CoglGLFramebuffer *gl_framebuffer);
+
+unsigned long
+_cogl_framebuffer_compare (CoglFramebuffer *a,
+ CoglFramebuffer *b,
+ unsigned long state);
+
+static inline CoglMatrixEntry *
+_cogl_framebuffer_get_modelview_entry (CoglFramebuffer *framebuffer)
+{
+ CoglMatrixStack *modelview_stack =
+ _cogl_framebuffer_get_modelview_stack (framebuffer);
+ return modelview_stack->last_entry;
+}
+
+static inline CoglMatrixEntry *
+_cogl_framebuffer_get_projection_entry (CoglFramebuffer *framebuffer)
+{
+ CoglMatrixStack *projection_stack =
+ _cogl_framebuffer_get_projection_stack (framebuffer);
+ return projection_stack->last_entry;
+}
+
+CoglBool
+_cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
+ int x,
+ int y,
+ CoglReadPixelsFlags source,
+ CoglBitmap *bitmap,
+ CoglError **error);
+
+/*
+ * _cogl_framebuffer_get_stencil_bits:
+ * @framebuffer: a pointer to a #CoglFramebuffer
+ *
+ * Retrieves the number of stencil bits of @framebuffer
+ *
+ * Return value: the number of bits
+ *
+ * Since: 2.0
+ * Stability: unstable
+ */
+int
+_cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer);
+
+#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */