1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /*
4 * Copyright (C) 2013 Red Hat
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * Written by:
22 * Jasper St. Pierre <jstpierre@mecheye.net>
23 */
24
25 #include "config.h"
26
27 #include "compositor/meta-surface-actor-wayland.h"
28
29 #include <math.h>
30
31 #include "backends/meta-backend-private.h"
32 #include "backends/meta-logical-monitor.h"
33 #include "cogl/cogl-wayland-server.h"
34 #include "compositor/meta-shaped-texture-private.h"
35 #include "compositor/region-utils.h"
36 #include "wayland/meta-wayland-buffer.h"
37 #include "wayland/meta-wayland-private.h"
38 #include "wayland/meta-window-wayland.h"
39
40 struct _MetaSurfaceActorWayland
41 {
42 MetaSurfaceActor parent;
43
44 MetaWaylandSurface *surface;
45 };
46
G_DEFINE_TYPE(MetaSurfaceActorWayland,meta_surface_actor_wayland,META_TYPE_SURFACE_ACTOR)47 G_DEFINE_TYPE (MetaSurfaceActorWayland,
48 meta_surface_actor_wayland,
49 META_TYPE_SURFACE_ACTOR)
50
51 static void
52 meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
53 int x,
54 int y,
55 int width,
56 int height)
57 {
58 meta_surface_actor_update_area (actor, x, y, width, height);
59 }
60
61 static gboolean
meta_surface_actor_wayland_is_opaque(MetaSurfaceActor * actor)62 meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
63 {
64 MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
65
66 return meta_shaped_texture_is_opaque (stex);
67 }
68
69 CoglScanout *
meta_surface_actor_wayland_try_acquire_scanout(MetaSurfaceActorWayland * self,CoglOnscreen * onscreen)70 meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
71 CoglOnscreen *onscreen)
72 {
73 MetaWaylandSurface *surface;
74 CoglScanout *scanout;
75
76 surface = meta_surface_actor_wayland_get_surface (self);
77 if (!surface)
78 return NULL;
79
80 scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
81 if (!scanout)
82 return NULL;
83
84 return scanout;
85 }
86
87 #define UNOBSCURED_TRESHOLD 0.1
88
89 ClutterStageView *
meta_surface_actor_wayland_get_current_primary_view(MetaSurfaceActor * actor,ClutterStage * stage)90 meta_surface_actor_wayland_get_current_primary_view (MetaSurfaceActor *actor,
91 ClutterStage *stage)
92 {
93 ClutterStageView *current_primary_view = NULL;
94 float highest_refresh_rate = 0.f;
95 float biggest_unobscurred_fraction = 0.f;
96 GList *l;
97
98 for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
99 {
100 ClutterStageView *stage_view = l->data;
101 float refresh_rate;
102 float unobscurred_fraction = 1.f;
103
104 if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
105 {
106 if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
107 stage_view))
108 continue;
109 }
110 else
111 {
112 if (l->next || biggest_unobscurred_fraction > 0.f)
113 {
114 if (meta_surface_actor_is_obscured_on_stage_view (actor,
115 stage_view,
116 &unobscurred_fraction))
117 continue;
118 }
119 else
120 {
121 if (meta_surface_actor_is_obscured (actor))
122 continue;
123 }
124 }
125
126 refresh_rate = clutter_stage_view_get_refresh_rate (stage_view);
127
128 if ((refresh_rate > highest_refresh_rate &&
129 (unobscurred_fraction > UNOBSCURED_TRESHOLD ||
130 biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD)) ||
131 (biggest_unobscurred_fraction < UNOBSCURED_TRESHOLD &&
132 unobscurred_fraction > UNOBSCURED_TRESHOLD))
133 {
134 current_primary_view = stage_view;
135 highest_refresh_rate = refresh_rate;
136 biggest_unobscurred_fraction = unobscurred_fraction;
137 }
138 }
139
140 return current_primary_view;
141 }
142
143 static void
meta_surface_actor_wayland_dispose(GObject * object)144 meta_surface_actor_wayland_dispose (GObject *object)
145 {
146 MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
147 MetaShapedTexture *stex;
148
149 stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
150 if (stex)
151 meta_shaped_texture_set_texture (stex, NULL);
152
153 if (self->surface)
154 {
155 g_object_remove_weak_pointer (G_OBJECT (self->surface),
156 (gpointer *) &self->surface);
157 self->surface = NULL;
158 }
159
160 G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
161 }
162
163 static void
meta_surface_actor_wayland_class_init(MetaSurfaceActorWaylandClass * klass)164 meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
165 {
166 MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
167 GObjectClass *object_class = G_OBJECT_CLASS (klass);
168
169 surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
170 surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
171
172 object_class->dispose = meta_surface_actor_wayland_dispose;
173 }
174
175 static void
meta_surface_actor_wayland_init(MetaSurfaceActorWayland * self)176 meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self)
177 {
178 }
179
180 MetaSurfaceActor *
meta_surface_actor_wayland_new(MetaWaylandSurface * surface)181 meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
182 {
183 MetaSurfaceActorWayland *self = g_object_new (META_TYPE_SURFACE_ACTOR_WAYLAND, NULL);
184
185 g_assert (meta_is_wayland_compositor ());
186
187 self->surface = surface;
188 g_object_add_weak_pointer (G_OBJECT (self->surface),
189 (gpointer *) &self->surface);
190
191 return META_SURFACE_ACTOR (self);
192 }
193
194 MetaWaylandSurface *
meta_surface_actor_wayland_get_surface(MetaSurfaceActorWayland * self)195 meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self)
196 {
197 return self->surface;
198 }
199