mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 20:12:06 +00:00
x11/nested: Always draw to an offscreen framebuffer
Always draw the stage to an offscreen framebuffer when using the nested backend, so that we more emulate things more similarly to how it works real-world, i.e. it'll work the way whether stage views are enabled or not. https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
parent
9d914091f5
commit
93c6a869ec
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/meta-renderer.h"
|
#include "backends/meta-renderer.h"
|
||||||
|
#include "backends/x11/nested/meta-renderer-x11-nested.h"
|
||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
|
|
||||||
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
||||||
@ -53,6 +54,25 @@ typedef struct _ClutterStageX11View
|
|||||||
ClutterStageViewCogl *view;
|
ClutterStageViewCogl *view;
|
||||||
} MetaStageX11NestedView;
|
} MetaStageX11NestedView;
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_stage_x11_nested_resize (ClutterStageWindow *stage_window,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
if (!meta_is_stage_views_enabled ())
|
||||||
|
{
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||||
|
MetaRendererX11Nested *renderer_x11_nested =
|
||||||
|
META_RENDERER_X11_NESTED (renderer);
|
||||||
|
|
||||||
|
meta_renderer_x11_nested_ensure_legacy_view (renderer_x11_nested,
|
||||||
|
width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_stage_window_parent_iface->resize (stage_window, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window)
|
meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||||
{
|
{
|
||||||
@ -65,10 +85,7 @@ meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window)
|
|||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||||
|
|
||||||
if (meta_is_stage_views_enabled ())
|
return meta_renderer_get_views (renderer);
|
||||||
return meta_renderer_get_views (renderer);
|
|
||||||
else
|
|
||||||
return clutter_stage_window_parent_iface->get_views (stage_window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -82,12 +99,6 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window)
|
|||||||
CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen);
|
CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen);
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
/*
|
|
||||||
* If we are in legacy mode, the stage is already on the onscreen.
|
|
||||||
*/
|
|
||||||
if (!meta_is_stage_views_enabled ())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!stage_nested->pipeline)
|
if (!stage_nested->pipeline)
|
||||||
stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context);
|
stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context);
|
||||||
|
|
||||||
@ -177,9 +188,9 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
|||||||
{
|
{
|
||||||
clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
|
clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
|
||||||
|
|
||||||
|
iface->resize = meta_stage_x11_nested_resize;
|
||||||
iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws;
|
iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws;
|
||||||
iface->unrealize = meta_stage_x11_nested_unrealize;
|
iface->unrealize = meta_stage_x11_nested_unrealize;
|
||||||
iface->get_views = meta_stage_x11_nested_get_views;
|
iface->get_views = meta_stage_x11_nested_get_views;
|
||||||
iface->finish_frame = meta_stage_x11_nested_finish_frame;
|
iface->finish_frame = meta_stage_x11_nested_finish_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,104 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
|||||||
return logical_monitor->transform;
|
return logical_monitor->transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaRendererView *
|
||||||
|
get_legacy_view (MetaRenderer *renderer)
|
||||||
|
{
|
||||||
|
GList *views;
|
||||||
|
|
||||||
|
views = meta_renderer_get_views (renderer);
|
||||||
|
if (views)
|
||||||
|
return META_RENDERER_VIEW (views->data);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglOffscreen *
|
||||||
|
create_offscreen (CoglContext *cogl_context,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
CoglTexture2D *texture_2d;
|
||||||
|
CoglOffscreen *offscreen;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
|
||||||
|
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
|
||||||
|
|
||||||
|
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error))
|
||||||
|
meta_fatal ("Couldn't allocate framebuffer: %s", error->message);
|
||||||
|
|
||||||
|
return offscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_renderer_x11_nested_resize_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
MetaRenderer *renderer = META_RENDERER (renderer_x11_nested);
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||||
|
MetaRendererView *legacy_view;
|
||||||
|
cairo_rectangle_int_t view_layout;
|
||||||
|
CoglOffscreen *fake_onscreen;
|
||||||
|
|
||||||
|
legacy_view = get_legacy_view (renderer);
|
||||||
|
|
||||||
|
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (legacy_view),
|
||||||
|
&view_layout);
|
||||||
|
if (view_layout.width == width &&
|
||||||
|
view_layout.height == height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
view_layout = (cairo_rectangle_int_t) {
|
||||||
|
.width = width,
|
||||||
|
.height = height
|
||||||
|
};
|
||||||
|
|
||||||
|
fake_onscreen = create_offscreen (cogl_context, width, height);
|
||||||
|
|
||||||
|
g_object_set (G_OBJECT (legacy_view),
|
||||||
|
"layout", &view_layout,
|
||||||
|
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
MetaRenderer *renderer = META_RENDERER (renderer_x11_nested);
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
|
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||||
|
cairo_rectangle_int_t view_layout;
|
||||||
|
CoglOffscreen *fake_onscreen;
|
||||||
|
MetaRendererView *legacy_view;
|
||||||
|
|
||||||
|
if (get_legacy_view (renderer))
|
||||||
|
{
|
||||||
|
meta_renderer_x11_nested_resize_legacy_view (renderer_x11_nested,
|
||||||
|
width, height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fake_onscreen = create_offscreen (cogl_context, width, height);
|
||||||
|
|
||||||
|
view_layout = (cairo_rectangle_int_t) {
|
||||||
|
.width = width,
|
||||||
|
.height = height
|
||||||
|
};
|
||||||
|
legacy_view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||||
|
"layout", &view_layout,
|
||||||
|
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
meta_renderer_set_legacy_view (renderer, legacy_view);
|
||||||
|
}
|
||||||
|
|
||||||
static MetaRendererView *
|
static MetaRendererView *
|
||||||
meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
||||||
MetaLogicalMonitor *logical_monitor)
|
MetaLogicalMonitor *logical_monitor)
|
||||||
@ -77,10 +175,8 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
|||||||
MetaMonitorTransform view_transform;
|
MetaMonitorTransform view_transform;
|
||||||
int view_scale;
|
int view_scale;
|
||||||
int width, height;
|
int width, height;
|
||||||
CoglTexture2D *texture_2d;
|
|
||||||
CoglOffscreen *fake_onscreen;
|
CoglOffscreen *fake_onscreen;
|
||||||
CoglOffscreen *offscreen;
|
CoglOffscreen *offscreen;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
|
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
|
||||||
|
|
||||||
@ -89,26 +185,25 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
|||||||
else
|
else
|
||||||
view_scale = 1;
|
view_scale = 1;
|
||||||
|
|
||||||
width = logical_monitor->rect.width * view_scale;
|
if (meta_monitor_transform_is_rotated (view_transform))
|
||||||
height = logical_monitor->rect.height * view_scale;
|
|
||||||
|
|
||||||
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
|
|
||||||
fake_onscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
|
|
||||||
|
|
||||||
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (fake_onscreen), &error))
|
|
||||||
meta_fatal ("Couldn't allocate framebuffer: %s", error->message);
|
|
||||||
|
|
||||||
if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
|
|
||||||
{
|
{
|
||||||
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
|
width = logical_monitor->rect.height;
|
||||||
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
|
height = logical_monitor->rect.width;
|
||||||
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error))
|
|
||||||
meta_fatal ("Couldn't allocate offscreen framebuffer: %s", error->message);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offscreen = NULL;
|
width = logical_monitor->rect.width;
|
||||||
|
height = logical_monitor->rect.height;
|
||||||
}
|
}
|
||||||
|
width *= view_scale;
|
||||||
|
height *= view_scale;
|
||||||
|
|
||||||
|
fake_onscreen = create_offscreen (cogl_context, width, height);
|
||||||
|
|
||||||
|
if (view_transform != META_MONITOR_TRANSFORM_NORMAL)
|
||||||
|
offscreen = create_offscreen (cogl_context, width, height);
|
||||||
|
else
|
||||||
|
offscreen = NULL;
|
||||||
|
|
||||||
return g_object_new (META_TYPE_RENDERER_VIEW,
|
return g_object_new (META_TYPE_RENDERER_VIEW,
|
||||||
"layout", &logical_monitor->rect,
|
"layout", &logical_monitor->rect,
|
||||||
|
@ -30,4 +30,8 @@ G_DECLARE_FINAL_TYPE (MetaRendererX11Nested, meta_renderer_x11_nested,
|
|||||||
META, RENDERER_X11_NESTED,
|
META, RENDERER_X11_NESTED,
|
||||||
MetaRendererX11)
|
MetaRendererX11)
|
||||||
|
|
||||||
|
void meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11_nested,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
#endif /* META_RENDERER_X11_NESTED_H */
|
#endif /* META_RENDERER_X11_NESTED_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user