/* If we should be rendering red zones over fallback nodes */
guint debug_fallback : 1;
+
+ /* Format we want to use for intermediate textures, determined by
+ * looking at the format of the framebuffer we are rendering on.
+ */
+ int target_format;
};
typedef struct _GskNglRenderOffscreen
const GskRenderNode *node,
GskNglRenderOffscreen *offscreen);
+static inline int
+get_target_format (GskNglRenderJob *job,
+ const GskRenderNode *node)
+{
+ if (gsk_render_node_prefers_high_depth (node))
+ return job->target_format;
+
+ return GL_RGBA8;
+}
+
static inline void
init_full_texture_region (GskNglRenderOffscreen *offscreen)
{
if (!gsk_ngl_driver_create_render_target (job->driver,
MAX (texture_to_blur_width, 1),
MAX (texture_to_blur_height, 1),
- GL_RGBA8,
+ job->target_format,
GL_NEAREST, GL_NEAREST,
&pass1))
return 0;
if (!gsk_ngl_driver_create_render_target (job->driver,
texture_to_blur_width,
texture_to_blur_height,
- GL_RGBA8,
+ job->target_format,
GL_NEAREST, GL_NEAREST,
&pass2))
return gsk_ngl_driver_release_render_target (job->driver, pass1, FALSE);
if (!gsk_ngl_driver_create_render_target (job->driver,
texture_width, texture_height,
- GL_RGBA8,
+ get_target_format (job, node),
GL_NEAREST, GL_NEAREST,
&render_target))
g_assert_not_reached ();
gsk_ngl_driver_create_render_target (job->driver,
texture_width, texture_height,
- GL_RGBA8,
+ get_target_format (job, node),
GL_NEAREST, GL_NEAREST,
&render_target);
if (!gsk_ngl_driver_create_render_target (job->driver,
scaled_width, scaled_height,
- GL_RGBA8,
+ get_target_format (job, node),
filter, filter,
&render_target))
g_assert_not_reached ();
if (!gsk_ngl_command_queue_create_render_target (job->command_queue,
MAX (1, job->viewport.size.width),
MAX (1, job->viewport.size.height),
- GL_RGBA8,
+ job->target_format,
GL_NEAREST, GL_NEAREST,
&framebuffer_id, &texture_id))
return;
job->debug_fallback = !!debug_fallback;
}
+static int
+get_framebuffer_format (guint framebuffer)
+{
+ int size;
+
+ glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+ glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size);
+
+ if (size >= 32)
+ return GL_RGBA32F;
+ else if (size >= 16)
+ return GL_RGBA16F;
+ else
+ return GL_RGBA8;
+}
+
GskNglRenderJob *
gsk_ngl_render_job_new (GskNglDriver *driver,
const graphene_rect_t *viewport,
job->scale_x = scale_factor;
job->scale_y = scale_factor;
job->viewport = *viewport;
+ job->target_format = get_framebuffer_format (framebuffer);
gsk_ngl_render_job_set_alpha (job, 1.0f);
gsk_ngl_render_job_set_projection_from_rect (job, viewport, NULL);