mutter/clutter/clutter/clutter-stage-private.h

177 lines
9.6 KiB
C
Raw Normal View History

2010-10-21 13:13:00 +01:00
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2010 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 __CLUTTER_STAGE_PRIVATE_H__
#define __CLUTTER_STAGE_PRIVATE_H__
#include <clutter/clutter-grab.h>
#include <clutter/clutter-stage-window.h>
#include <clutter/clutter-stage.h>
#include <clutter/clutter-input-device.h>
#include <clutter/clutter-private.h>
#include <cogl/cogl.h>
G_BEGIN_DECLS
typedef enum
{
CLUTTER_DEVICE_UPDATE_NONE = 0,
CLUTTER_DEVICE_UPDATE_EMIT_CROSSING = 1 << 0,
CLUTTER_DEVICE_UPDATE_IGNORE_CACHE = 1 << 1,
} ClutterDeviceUpdateFlags;
/* stage */
ClutterStageWindow *_clutter_stage_get_default_window (void);
CLUTTER_EXPORT
void clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterFrame *frame);
void clutter_stage_emit_before_update (ClutterStage *stage,
ClutterStageView *view,
ClutterFrame *frame);
void clutter_stage_emit_prepare_frame (ClutterStage *stage,
ClutterStageView *view,
ClutterFrame *frame);
void clutter_stage_emit_before_paint (ClutterStage *stage,
ClutterStageView *view,
ClutterFrame *frame);
void clutter_stage_emit_after_paint (ClutterStage *stage,
ClutterStageView *view,
ClutterFrame *frame);
void clutter_stage_emit_after_update (ClutterStage *stage,
ClutterStageView *view,
ClutterFrame *frame);
CLUTTER_EXPORT
void _clutter_stage_set_window (ClutterStage *stage,
ClutterStageWindow *stage_window);
CLUTTER_EXPORT
ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage);
void _clutter_stage_get_projection_matrix (ClutterStage *stage,
graphene_matrix_t *projection);
void _clutter_stage_dirty_projection (ClutterStage *stage);
void _clutter_stage_get_viewport (ClutterStage *stage,
float *x,
float *y,
float *width,
float *height);
void _clutter_stage_dirty_viewport (ClutterStage *stage);
CLUTTER_EXPORT
Introduce regional stage rendering Add support for drawing a stage using multiple framebuffers each making up one part of the stage. This works by the stage backend (ClutterStageWindow) providing a list of views which will be for splitting up the stage in different regions. A view layout, for now, is a set of rectangles. The stage window (i.e. stage "backend" will use this information when drawing a frame, using one framebuffer for each view. The scene graph is adapted to explictly take a view when painting the stage. It will use this view, its assigned framebuffer and layout to offset and clip the drawing accordingly. This effectively removes any notion of "stage framebuffer", since each stage now may consist of multiple framebuffers. Therefore, API involving this has been deprecated and made no-ops; namely clutter_stage_ensure_context(). Callers are now assumed to either always use a framebuffer reference explicitly, or push/pop the framebuffer of a given view where the code has not yet changed to use the explicit-buffer-using cogl API. Currently only the nested X11 backend supports this mode fully, and the per view framebuffers are all offscreen. Upon frame completion, it'll blit each view's framebuffer onto the onscreen framebuffer before swapping. Other backends (X11 CM and native/KMS) are adapted to manage a full-stage view. The X11 CM backend will continue to use this method, while the native/KMS backend will be adopted to use multiple view drawing. https://bugzilla.gnome.org/show_bug.cgi?id=768976
2016-05-27 11:09:24 +08:00
void _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
ClutterStageView *view);
void clutter_stage_maybe_relayout (ClutterActor *stage);
void clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage);
GSList * clutter_stage_find_updated_devices (ClutterStage *stage,
ClutterStageView *view);
void clutter_stage_update_devices (ClutterStage *stage,
GSList *devices);
void clutter_stage_finish_layout (ClutterStage *stage);
CLUTTER_EXPORT
void _clutter_stage_queue_event (ClutterStage *stage,
ClutterEvent *event,
gboolean copy_event);
gboolean _clutter_stage_has_queued_events (ClutterStage *stage);
void _clutter_stage_process_queued_events (ClutterStage *stage);
void _clutter_stage_update_input_devices (ClutterStage *stage);
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
ClutterPaintVolume *_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage);
void _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage);
void clutter_stage_queue_actor_redraw (ClutterStage *stage,
ClutterActor *actor,
const ClutterPaintVolume *clip);
void clutter_stage_dequeue_actor_redraw (ClutterStage *stage,
ClutterActor *actor);
void _clutter_stage_add_pointer_drag_actor (ClutterStage *stage,
ClutterInputDevice *device,
ClutterActor *actor);
ClutterActor * _clutter_stage_get_pointer_drag_actor (ClutterStage *stage,
ClutterInputDevice *device);
void _clutter_stage_remove_pointer_drag_actor (ClutterStage *stage,
ClutterInputDevice *device);
void _clutter_stage_add_touch_drag_actor (ClutterStage *stage,
ClutterEventSequence *sequence,
ClutterActor *actor);
ClutterActor * _clutter_stage_get_touch_drag_actor (ClutterStage *stage,
ClutterEventSequence *sequence);
void _clutter_stage_remove_touch_drag_actor (ClutterStage *stage,
ClutterEventSequence *sequence);
void _clutter_stage_set_scale_factor (ClutterStage *stage,
int factor);
void clutter_stage_presented (ClutterStage *stage,
ClutterStageView *view,
ClutterFrameInfo *frame_info);
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
ClutterActor *actor);
clutter/actor: Remove actors from shallow relayout list when unrealizing With the introduction of the shallow relayout mechanism another small but severe regression sneaked into our layout machinery: We might allocate an actor twice during the same allocation cycle, with one allocation happening using the wrong parent. This issue happens when reparenting an actor from a NO_LAYOUT parent to a non-NO_LAYOUT parent, in particular it triggered a bug in gnome-shell when DND reparents a child from the NO_LAYOUT uiGroup to the overviews Workspace actor after a drag ended. The reason the issue happens is the following chain of events: 1. child of a NO_LAYOUT parent queues a relayout, this child is added to the priv->pending_relayouts list maintained by ClutterStage 2. child is reparented to a different parent which doesn't have the NO_LAYOUT flag set, another relayout is queued, this time a different actor is added to the priv->pending_relayouts list 3. the relayout happens and we go through the pending_relayouts list backwards, that means the correct relayout queued during 2. happens first, then the old one happens and we simply call clutter_actor_allocate_preferred_size() on the actor, that allocation overrides the other, correct one. So fix that issue by adding a method to ClutterStage which removes actors from the pending_relayouts list again and call this method as soon as an actor with a NO_LAYOUT parent is detached from the stage. With that in place, we can also remove the check whether an actor is still on stage while looping through pending_relayouts. In case something else is going wrong and the actor is not on stage, clutter_actor_allocate() will warn anyway. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1356
2020-07-06 15:35:14 +02:00
void clutter_stage_dequeue_actor_relayout (ClutterStage *stage,
ClutterActor *actor);
GList * clutter_stage_get_views_for_rect (ClutterStage *stage,
const graphene_rect_t *rect);
clutter: Add private API to support resource scale affecting layout For ClutterText, the resource scale the text is drawn with affects the size of the allocation: ClutterText will choose a font scale based on the resource scale, and that font scale can lead to a slight difference in size compared to the unscaled font. We currently handle that by queuing a relayout inside the "resource-scale-changed" signal handler. This solution is a bit problematic though since it will take one more allocation cycle until the allocation is actually updated after a scale-change, so the actor is painted using the wrong allocation for one frame. Also the current solution can lead to relayout loops in a few cases, for example if a ClutterText is located near the edge on a 1x scaled monitor and is moved to intersect a 2x scaled monitor: Now the resource scale will change to 2 and a new allocation box is calculated; if this allocation box is slightly smaller than the old one because of the new font scale, the allocation won't intersect the 2x scaled monitor again and the resource scale switches back to 1. Now the allocation gets larger again and intersects the 2x scaled monitor again. This commit introduces a way to properly support those actors: In case an actors resource scale might affect its allocation, it should call the private function clutter_actor_queue_immediate_relayout(). This will make sure the actor gets a relayout before the upcoming paint happens afte every resource scale change. Also potential relayout loops can be handled by the actors themselves using a "phase" argument that's passed to implementations of the calculate_resource_scale() vfunc. The new API is private because resource scales are not meant to be used in a way where the scale affects the allocation. With ClutterText and the current behavior of Pango, that can't be avoid though, so we need it anyway. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1276
2020-04-10 14:54:11 +02:00
void clutter_stage_set_actor_needs_immediate_relayout (ClutterStage *stage);
void clutter_stage_update_device_entry (ClutterStage *self,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
graphene_point_t coords,
ClutterActor *actor,
cairo_region_t *clear_area);
void clutter_stage_remove_device_entry (ClutterStage *self,
ClutterInputDevice *device,
ClutterEventSequence *sequence);
ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *stage,
ClutterInputDevice *device,
ClutterEventSequence *sequence,
ClutterDeviceUpdateFlags flags,
graphene_point_t point,
uint32_t time_ms);
void clutter_stage_unlink_grab (ClutterStage *self,
ClutterGrab *grab);
void clutter_stage_invalidate_focus (ClutterStage *self,
ClutterActor *actor);
void clutter_stage_maybe_invalidate_focus (ClutterStage *self,
ClutterActor *actor);
void clutter_stage_emit_event (ClutterStage *self,
const ClutterEvent *event);
G_END_DECLS
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */