[GtkGLExt] Inconsistent updates/Screenshot problems with GLExt in Windows Vista/7



Hi,

I'm using the GLExtension 1.2.0 and GTK 2.12.10 in an application designed for Windows and Linux.

However, after the switch to Windows Vista/7 some troubles showed up.

First, visible updates of the GL drawing area were not in line with the number of drawn updates (= calls to gdk_gl_drawable_swap_buffers()). The user got the impression of a low framerate, which was not the case. For this problem however, we figured out a fix:

If gdk_gl_window_impl_win32_swap_buffers() in gdkglwindow-win32.c does not release the device context at the end of the function, the perceived performance rises and seems to be in line with the calls to swapbuffer. Maybe someone wants to integrate this change into the current version.


But we have another problem, we were not able to fix: The application allows for taking screenshots of its subwindows. We do this by calling gdk_pixbuf_get_from_drawable() for the associated window and everything worked fine in Windows XP. In Vista/7, however, screenshots of GL widgets only contain memory garbage (and only the screenshots, not the displayed version!). I've attached screenshots taken with gdk_gl_drawable_swap_buffers() and an external tool for comparison. The scatterplot matrix an the left is the GL part of the window.

These shots can also be viewed here:
http://dl.dropbox.com/u/39690/gdk_screenshot.png
http://dl.dropbox.com/u/39690/reference_screenshot.png

The code for initializing/drawing looks like this:

void	MyClass::ItlGtkEventRealize(	GtkWidget	*pWidget,
					gpointer	pData)
{
	assert (pData != NULL);

	// cast to this
	MyClass *pThis = (MyClass *)pData;

	assert(!pThis->m_bRealized);

	// set realized
	pThis->m_bRealized = true;
}

void	MyClass::ItlGtkEventUnrealize(	GtkWidget	*pWidget,
					gpointer	pData)
{
	assert(pData != NULL);

	// cast to this
	MyClass *pThis = (MyClass *)pData;

	// must be realized
	assert(pThis->m_bRealized);

	// the context is going to change
	pThis->ItlOnUnrealized();

	// not realized any longer (and also expose must be called anew)
	pThis->m_bRealized	= false;
	pThis->m_bExposeCalled	= false;
	pThis->m_bGLDrawing	= false;

	pThis->m_pGLDrawable	= NULL;
	pThis->m_pGLContext	= NULL;
}

gboolean MyClass::ItlGtkEventExpose(GtkWidget		*pWidget,
				    GdkEventExpose	*pEvent,
				    gpointer		pData)
{
	assert(pData != NULL);

	MyClass *pThis = (MyClass *)pData;

	// only do something for realized views
	if (pThis->m_bRealized)
	{
		// create context on first call
		if (!pThis->m_bExposeCalled)
		{
			assert((pThis->m_pGLContext == NULL) && (pThis->m_pGLDrawable == NULL));

			BAGLLock::GetInstance()->Lock();

			pThis->m_pGLContext		= gtk_widget_get_gl_context(pThis->m_pDrawingArea);
			pThis->m_pGLDrawable	= gtk_widget_get_gl_drawable(pThis->m_pDrawingArea);

			BAGLLock::GetInstance()->Unlock();

			assert((pThis->m_pGLContext != NULL) && (pThis->m_pGLDrawable != NULL));

			pThis->m_bExposeCalled = true;
		}

		// initiate redraw
		pThis->ItlOnDraw();
	}

	return FALSE;
}

void	MyClass::ItlOnDraw()
{
	// called in expose

	if (!m_bGLDrawing)
	{
		// call gl-begin
		bOk = gdk_gl_drawable_gl_begin(m_pGLDrawable, m_pGLContext) != FALSE;			

		m_bGLDrawing = bOk;
	}
	else
	{		
bOk = gdk_gl_drawable_make_current(m_pGLDrawable, m_pGLContext) != FALSE;
	}

	if (bOk)
	{
		// do GL drawing here
		// ...
		
		gdk_gl_drawable_swap_buffers(m_pGLDrawable);

		glFinish();

		gdk_gl_drawable_wait_gdk(m_pGLDrawable);
		gdk_gl_drawable_gl_end(m_pGLDrawable);
		
		m_bGLDrawing = false;
	}
}

Is there anything I am missing? Thanks in advance!

Attachment: gdk_screenshot.png
Description: PNG image

Attachment: reference_screenshot.png
Description: PNG image



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]