mutter/cogl/cogl-journal-private.h
Robert Bragg a8d6c3f686 cogl: Implements a software only read-pixel fast-path
This adds a transparent optimization to cogl_read_pixels for when a
single pixel is being read back and it happens that all the geometry of
the current frame is still available in the framebuffer's associated
journal.

The intention is to indirectly optimize Clutter's render based picking
mechanism in such a way that the 99% of cases where scenes are comprised
of trivial quad primitives that can easily be intersected we can avoid
the latency of kicking a GPU render and blocking for the result when we
know we can calculate the result manually on the CPU probably faster
than we could even kick a render.

A nice property of this solution is that it maintains all the
flexibility of the render based picking provided by Clutter and it can
gracefully fall back to GPU rendering if actors are drawn using anything
more complex than a quad for their geometry.

It seems worth noting that there is a limitation to the extensibility of
this approach in that it can only optimize picking a against geometry
that passes through Cogl's journal which isn't something Clutter
directly controls.  For now though this really doesn't matter since
basically all apps should end up hitting this fast-path. The current
idea to address this longer term would be a pick2 vfunc for ClutterActor
that can support geometry and render based input regions of actors and
move this optimization up into Clutter instead.

Note: currently we don't have a primitive count threshold to consider
that there could be scenes with enough geometry for us to compensate for
the cost of kicking a render and determine a result more efficiently by
utilizing the GPU. We don't currently expect this to be common though.

Note: in the future it could still be interesting to revive something
like the wip/async-pbo-picking branch to provide an asynchronous
read-pixels based optimization for Clutter picking in cases where more
complex input regions that necessitate rendering are in use or if we do
add a threshold for rendering as mentioned above.
2011-01-21 16:18:11 +00:00

93 lines
2.9 KiB
C

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2007,2008,2009 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_JOURNAL_PRIVATE_H
#define __COGL_JOURNAL_PRIVATE_H
#include "cogl-handle.h"
#include "cogl-clip-stack.h"
typedef struct _CoglJournal
{
CoglObject _parent;
GArray *entries;
GArray *vertices;
size_t needed_vbo_len;
int fast_read_pixel_count;
} CoglJournal;
/* To improve batching of geometry when submitting vertices to OpenGL we
* log the texture rectangles we want to draw to a journal, so when we
* later flush the journal we aim to batch data, and gl draw calls. */
typedef struct _CoglJournalEntry
{
CoglPipeline *pipeline;
int n_layers;
CoglMatrix model_view;
CoglClipStack *clip_stack;
/* Offset into ctx->logged_vertices */
size_t array_offset;
/* XXX: These entries are pretty big now considering the padding in
* CoglPipelineFlushOptions and CoglMatrix, so we might need to optimize this
* later. */
} CoglJournalEntry;
CoglJournal *
_cogl_journal_new (void);
void
_cogl_journal_log_quad (CoglJournal *journal,
const float *position,
CoglPipeline *pipeline,
int n_layers,
CoglHandle layer0_override_texture,
const float *tex_coords,
unsigned int tex_coords_len);
void
_cogl_journal_flush (CoglJournal *journal,
CoglFramebuffer *framebuffer);
void
_cogl_journal_discard (CoglJournal *journal);
gboolean
_cogl_journal_all_entries_within_bounds (CoglJournal *journal,
float clip_x0,
float clip_y0,
float clip_x1,
float clip_y1);
gboolean
_cogl_journal_try_read_pixel (CoglJournal *journal,
int x,
int y,
CoglPixelFormat format,
guint8 *pixel,
gboolean *found_intersection);
#endif /* __COGL_JOURNAL_PRIVATE_H */