mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 13:22:15 +00:00
kms: defer setting crtc modes until first swap buffers
Instead of creating a dummy framebuffer allocation just so we can setup crtc modes during display_setup we now wait until the first swap_buffers request before setting up the crtc modes. This patch also adds a cogl_kms_display_queue_modes_reset() function that allows developers to explicitly queue a reset of the crtc modes. The idea is that applications that handle VT switching can use this for VT enter events to explicitly ensure their mode is restored since modes are often not automatically restored correctly. Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
parent
125c31a70b
commit
bdb645e7f5
@ -416,7 +416,8 @@ cogl_sources_c += \
|
||||
endif
|
||||
if SUPPORT_EGL_PLATFORM_KMS
|
||||
cogl_experimental_h += \
|
||||
$(srcdir)/cogl-kms-renderer.h
|
||||
$(srcdir)/cogl-kms-renderer.h \
|
||||
$(srcdir)/cogl-kms-display.h
|
||||
cogl_sources_c += \
|
||||
$(srcdir)/winsys/cogl-winsys-egl-kms.c \
|
||||
$(srcdir)/winsys/cogl-winsys-egl-kms-private.h
|
||||
|
58
cogl/cogl-kms-display.h
Normal file
58
cogl/cogl-kms-display.h
Normal file
@ -0,0 +1,58 @@
|
||||
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2012 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cogl/cogl.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __COGL_KMS_DISPLAY_H__
|
||||
#define __COGL_KMS_DISPLAY_H__
|
||||
|
||||
#include <cogl/cogl-types.h>
|
||||
#include <cogl/cogl-display.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* cogl_kms_display_queue_modes_reset:
|
||||
* @display: A #CoglDisplay
|
||||
*
|
||||
* Asks Cogl to explicitly reset the crtc output modes at the next
|
||||
* #CoglOnscreen swap_buffers request. For applications that support
|
||||
* VT switching they may want to re-assert the output modes when
|
||||
* switching back to the applications VT since the modes are often not
|
||||
* correctly restored automatically.
|
||||
*
|
||||
* <note>The @display must have been either explicitly setup via
|
||||
* cogl_display_setup() or implicitily setup by having created a
|
||||
* context using the @display</note>
|
||||
*
|
||||
* Since: 2.0
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_kms_display_queue_modes_reset (CoglDisplay *display);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __COGL_KMS_DISPLAY_H__ */
|
@ -105,6 +105,7 @@
|
||||
#include <cogl/cogl-poll.h>
|
||||
#if defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||
#include <cogl/cogl-kms-renderer.h>
|
||||
#include <cogl/cogl-kms-display.h>
|
||||
#endif
|
||||
#if COGL_HAS_WIN32_SUPPORT
|
||||
#include <cogl/cogl-win32-renderer.h>
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-onscreen-private.h"
|
||||
#include "cogl-kms-renderer.h"
|
||||
#include "cogl-kms-display.h"
|
||||
|
||||
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
||||
|
||||
@ -76,6 +77,7 @@ typedef struct _CoglDisplayKMS
|
||||
{
|
||||
GList *outputs;
|
||||
int width, height;
|
||||
gboolean pending_set_crtc;
|
||||
gboolean pending_swap_notify;
|
||||
} CoglDisplayKMS;
|
||||
|
||||
@ -356,23 +358,26 @@ find_output (int _index,
|
||||
return output;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_crtc (int fd, uint32_t fb_id, CoglOutputKMS *output, GError **error)
|
||||
static void
|
||||
setup_crtc_modes (CoglDisplay *display, int fb_id)
|
||||
{
|
||||
int ret = drmModeSetCrtc (fd,
|
||||
output->encoder->crtc_id,
|
||||
fb_id, 0, 0,
|
||||
&output->connector->connector_id, 1,
|
||||
&output->mode);
|
||||
if (ret)
|
||||
{
|
||||
g_set_error (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_INIT,
|
||||
"Failed to set mode %s: %m", output->mode.name);
|
||||
return FALSE;
|
||||
}
|
||||
CoglDisplayEGL *egl_display = display->winsys;
|
||||
CoglDisplayKMS *kms_display = egl_display->platform;
|
||||
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||
GList *l;
|
||||
|
||||
return TRUE;
|
||||
for (l = kms_display->outputs; l; l = l->next)
|
||||
{
|
||||
CoglOutputKMS *output = l->data;
|
||||
int ret = drmModeSetCrtc (kms_renderer->fd,
|
||||
output->encoder->crtc_id,
|
||||
fb_id, 0, 0,
|
||||
&output->connector->connector_id, 1,
|
||||
&output->mode);
|
||||
if (ret)
|
||||
g_warning ("Failed to set crtc mode %s: %m", output->mode.name);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -388,10 +393,6 @@ _cogl_winsys_egl_display_setup (CoglDisplay *display,
|
||||
drmModeRes *resources;
|
||||
CoglOutputKMS *output0, *output1;
|
||||
gboolean mirror;
|
||||
struct gbm_bo *bo;
|
||||
uint32_t handle, pitch, fb_id;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
kms_display = g_slice_new0 (CoglDisplayKMS);
|
||||
egl_display->platform = kms_display;
|
||||
@ -475,37 +476,12 @@ _cogl_winsys_egl_display_setup (CoglDisplay *display,
|
||||
else
|
||||
output0->mode = output0->modes[0];
|
||||
|
||||
width = output0->mode.hdisplay;
|
||||
height = output0->mode.vdisplay;
|
||||
kms_display->width = output0->mode.hdisplay;
|
||||
kms_display->height = output0->mode.vdisplay;
|
||||
|
||||
bo = gbm_bo_create (kms_renderer->gbm,
|
||||
width, height, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT);
|
||||
pitch = gbm_bo_get_pitch (bo);
|
||||
handle = gbm_bo_get_handle (bo).u32;
|
||||
if (drmModeAddFB (kms_renderer->fd,
|
||||
width,
|
||||
height,
|
||||
24, /* depth */
|
||||
32, /* bpp */
|
||||
pitch,
|
||||
handle,
|
||||
&fb_id) != 0)
|
||||
{
|
||||
g_set_error (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_INIT,
|
||||
"Failed to create initial framebuffer");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!set_crtc (kms_renderer->fd, fb_id, output0, error))
|
||||
return FALSE;
|
||||
|
||||
if (mirror)
|
||||
if (!set_crtc (kms_renderer->fd, fb_id, output1, error))
|
||||
return FALSE;
|
||||
|
||||
kms_display->width = width;
|
||||
kms_display->height = height;
|
||||
/* We defer setting the crtc modes until the first swap_buffers request of a
|
||||
* CoglOnscreen framebuffer. */
|
||||
kms_display->pending_set_crtc = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -705,6 +681,14 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is the first framebuffer to be presented then we now setup the
|
||||
* crtc modes... */
|
||||
if (kms_display->pending_set_crtc)
|
||||
{
|
||||
setup_crtc_modes (context->display, kms_onscreen->next_fb_id);
|
||||
kms_display->pending_set_crtc = FALSE;
|
||||
}
|
||||
|
||||
flip = g_slice_new0 (CoglFlipKMS);
|
||||
flip->onscreen = onscreen;
|
||||
|
||||
@ -985,3 +969,14 @@ cogl_kms_renderer_get_kms_fd (CoglRenderer *renderer)
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_kms_display_queue_modes_reset (CoglDisplay *display)
|
||||
{
|
||||
if (display->setup)
|
||||
{
|
||||
CoglDisplayEGL *egl_display = display->winsys;
|
||||
CoglDisplayKMS *kms_display = egl_display->platform;
|
||||
kms_display->pending_set_crtc = TRUE;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user