Esempio n. 1
0
cairo_t *
MoonEGLContext::Push (Cairo extents)
{
	Target *target = Top ()->GetTarget ();
	Target *cairo = target->GetCairoTarget ();
	Rect   box;

	Top ()->GetClip (&box);

	box = box.Intersection (extents.r);

	if (box.IsEmpty ())
		return Context::Push (extents);

	if (cairo) {
		Rect   r = cairo->GetData (NULL);
		Region *region = new Region (r);

		if (region->RectIn (box) != CAIRO_REGION_OVERLAP_IN) {
			ForceCurrent ();
			SyncDrawable ();
		}

		delete region;
	}

	if (!target->GetCairoTarget ()) {
		MoonSurface *ms;
		Rect        r = target->GetData (&ms);

		if (HasDrawable ()) {
			MoonEGLSurface *surface = new MoonEGLSurface (box.width,
							      box.height);
			Target     *cairo = new Target (surface, box);

			target->SetCairoTarget (cairo);

			cairo->unref ();
			surface->unref ();
		}
		else {
			// mark target contents as initialized
			target->SetInit (ms);
		}

		ms->unref ();
	}

	return Context::Push (extents);
}
Esempio n. 2
0
gboolean
MoonWindowGtk::ExposeEvent (GtkWidget *w, GdkEventExpose *event)
{
	SetCurrentDeployment ();

	if (!surface)
		return true;

#ifdef USE_GLX
	Display   *dpy = gdk_x11_drawable_get_xdisplay (w->window);
	XID       win = gdk_x11_drawable_get_xid (w->window);
	_XxVisual *visual = GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (w->window));
	int       width, height;

	gdk_drawable_get_size (w->window, &width, &height);

	if (!glxtarget && (moonlight_flags & RUNTIME_INIT_HW_ACCELERATION)) {
		GLXContext  ctx = (GLXContext) 0;
		XVisualInfo templ, *visinfo;
		int         n;

		templ.visualid = XVisualIDFromVisual (visual);
		visinfo = XGetVisualInfo (dpy, VisualIDMask, &templ, &n);
		g_assert (visinfo);

		ctx = glXCreateContext (dpy, visinfo, 0, True);
		if (ctx) {
			gdk_error_trap_push ();
			glXMakeCurrent (dpy, win, ctx);
			gdk_flush ();
			if (gdk_error_trap_pop ()) {
				g_warning ("Failed to make GLX context current for window: "
					   "0x%x", (int) win);
				glXDestroyContext (dpy, ctx);
				ctx = (GLXContext) 0;
			}
		}
		else {
			g_warning ("Failed to create GLX context for VisualID: 0x%x",
				   (int) XVisualIDFromVisual (visual));
		}

		glxtarget = new MoonGLXSurface ();

		if (ctx) {
			OpenGLContext *context = new MoonGLXContext (glxtarget, dpy, ctx);

			if (context->Initialize ()) {
				const char *extensions = (const char *)
					glXGetClientString (dpy, GLX_EXTENSIONS);

				if (strstr (extensions, "GLX_MESA_copy_sub_buffer"))
					glxcopysubbuffer = glxtarget->GetProcAddress
						("glXCopySubBufferMESA");

				glxctx = context;
			}
			else {
				glXDestroyContext (dpy, ctx);
				delete context;
			}
		}
	}

	if (glxtarget && glxctx) {
		Rect r0 = Rect (0, 0, width, height);
		Rect r = Rect (event->area.x,
			       event->area.y,
			       event->area.width,
			       event->area.height);
		Region *region = new Region (r);
		int    y = height - (event->area.y + event->area.height);

		glXMakeCurrent (dpy,
				win,
				static_cast<MoonGLXContext *> (glxctx)->GetGLXContext ());

		glxtarget->Reshape (width, height);

		glxctx->Push (Context::Clip (r));
		surface->Paint (glxctx, region, GetTransparent (), true);
		glxctx->Pop ();

		glxctx->Flush ();

		if (region->RectIn (r0) == CAIRO_REGION_OVERLAP_IN) {
			glXSwapBuffers (dpy, win);
		}
		else if (glxcopysubbuffer) {
			PFNGLXCOPYSUBBUFFERPROC glXCopySubBufferMESA =
				(PFNGLXCOPYSUBBUFFERPROC) glxcopysubbuffer;

			glXCopySubBufferMESA (dpy,
					      win,
					      event->area.x,
					      y,
					      event->area.width,
					      event->area.height);
		}
		else {
			glDrawBuffer (GL_FRONT);
			glViewport (-1, -1, 2, 2);
			glRasterPos2f (0, 0);
			glViewport (0, 0, width, height);

			glBitmap (0, 0, 0, 0,
				  event->area.x,
				  y,
				  NULL);

			glCopyPixels (event->area.x, y,
				      event->area.width,
				      event->area.height,
				      GL_COLOR);

			glDrawBuffer (GL_BACK);
			glFlush ();
		}

		return true;
	}
#endif

	// we draw to a backbuffer pixmap, then transfer the contents
	// to the widget's window.
	if (backing_store == NULL ||
	    backing_store_width < (event->area.x + event->area.width) ||
	    backing_store_height < (event->area.y + event->area.height)) {
		if (backing_store)
			g_object_unref (backing_store);
		if (backing_store_gc)
			g_object_unref (backing_store_gc);
		if (backing_image_data) {
			g_free (backing_image_data);
			backing_image_data = NULL;
		}
#if FULLSCREEN_BACKING_STORE_SOPTIMIZATION
		if (IsFullScreen ()) {
			backing_store_width = MAX (event->area.x + event->area.width, 1);
			backing_store_height = MAX (event->area.y + event->area.height, 1);
		}
		else
#endif
		{
			backing_store_width = MAX (GetWidth(), 1);
			backing_store_height = MAX (GetHeight(), 1);
		}

		backing_store = gdk_pixmap_new (w->window,
						backing_store_width, backing_store_height, -1);

		backing_store_gc = gdk_gc_new (backing_store);
	}

	PaintToDrawable (backing_store,
			 gdk_drawable_get_visual (w->window),
			 event,
			 - event->area.x,
			 - event->area.y,
			 GetTransparent (),
			 true);

	gdk_gc_set_clip_region (backing_store_gc, event->region);

	gdk_draw_drawable (w->window, backing_store_gc, backing_store,
			   0, 0,
			   event->area.x, event->area.y,
			   event->area.width, event->area.height);

#if FULLSCREEN_BACKING_STORE_SOPTIMIZATION
	if (IsFullScreen ()) {
		g_object_unref (backing_store); backing_store = NULL;
		g_object_unref (backing_store_gc); backing_store_gc = NULL;
		backing_store_width = backing_store_height = 0;
	}
#endif

	return true;
}
Esempio n. 3
0
/**
* @fn	   gboolean ExposeEvent (GtkWidget *w, cairo_t *cr)
* @brief   event handler for expose event
* @param   w		GtkWidget *
* @param   cr		cairo_t *
* @return  gboolean
*/
gboolean
MoonWindowGtk::ExposeEvent (GtkWidget *w, cairo_t *cr)
{
	SetCurrentDeployment ();

	if (!surface)
		return true;

	GtkAllocation allocation;
	gtk_widget_get_allocation (widget, &allocation);

#ifdef USE_GLX
	Display *dpy = GDK_WINDOW_XDISPLAY (gtk_widget_get_window(w));
	XID       win = gdk_x11_window_get_xid (gtk_widget_get_window(w));
	_XxVisual *visual = GDK_VISUAL_XVISUAL (gdk_window_get_visual (gtk_widget_get_window(w)));
	int       width, height;

	width=gdk_window_get_width (gtk_widget_get_window(w));
	height=gdk_window_get_height (gtk_widget_get_window(w));

	if (!glxtarget && (moonlight_flags & RUNTIME_INIT_HW_ACCELERATION)) {
		GLXContext  ctx = (GLXContext) 0;
		XVisualInfo templ, *visinfo;
		int         n;

		templ.visualid = XVisualIDFromVisual (visual);
		visinfo = XGetVisualInfo (dpy, VisualIDMask, &templ, &n);
		g_assert (visinfo);

		ctx = glXCreateContext (dpy, visinfo, 0, True);
		if (ctx) {
			gdk_error_trap_push ();
			glXMakeCurrent (dpy, win, ctx);
			gdk_flush ();
			if (gdk_error_trap_pop ()) {
				g_warning ("Failed to make GLX context current for window: "
					   "0x%x", (int) win);
				glXDestroyContext (dpy, ctx);
				ctx = (GLXContext) 0;
			}
		}
		else {
			g_warning ("Failed to create GLX context for VisualID: 0x%x",
				   (int) XVisualIDFromVisual (visual));
		}

		glxtarget = new MoonGLXSurface ();

		if (ctx) {
			OpenGLContext *context = new MoonGLXContext (glxtarget, dpy, ctx);

			if (context->Initialize ()) {
				const char *extensions = (const char *)
					glXGetClientString (dpy, GLX_EXTENSIONS);

				if (strstr (extensions, "GLX_MESA_copy_sub_buffer"))
					glxcopysubbuffer = glxtarget->GetProcAddress
						("glXCopySubBufferMESA");

				glxctx = context;
			}
			else {
				glXDestroyContext (dpy, ctx);
				delete context;
			}
		}
	}

	if (glxtarget && glxctx) {
		cairo_rectangle_int_t area;
		Rect r0 = Rect (0, 0, width, height);
		Rect r = Rect (area.x,
					   area.y,
					   area.width,
					   area.height);
		Region *region = new Region (r);
		int    y = height - (area.y + area.height);

		glXMakeCurrent (dpy,
				win,
				static_cast<MoonGLXContext *> (glxctx)->GetGLXContext ());

		glxtarget->Reshape (width, height);

		glxctx->Push (Context::Clip (r));
		surface->Paint (glxctx, region, GetTransparent (), true);
		glxctx->Pop ();

		glxctx->Flush ();

		if (region->RectIn (r0) == CAIRO_REGION_OVERLAP_IN) {
			glXSwapBuffers (dpy, win);
		}
		else if (glxcopysubbuffer) {
			PFNGLXCOPYSUBBUFFERPROC glXCopySubBufferMESA =
				(PFNGLXCOPYSUBBUFFERPROC) glxcopysubbuffer;

			glXCopySubBufferMESA (dpy,
								  win,
								  area.x,
								  y,
								  area.width,
								  area.height);
		}
		else {
			glDrawBuffer (GL_FRONT);
			glViewport (-1, -1, 2, 2);
			glRasterPos2f (0, 0);
			glViewport (0, 0, width, height);

			glBitmap (0, 0, 0, 0,
					area.x,
					y,
					NULL);

			glCopyPixels (area.x, y,
					area.width,
					area.height,
					GL_COLOR);

			glDrawBuffer (GL_BACK);
			glFlush ();
		}

		return true;
	}
#endif

	PaintToDrawable (gdk_window_get_visual (gtk_widget_get_window(w)),
					 cr,
					 allocation,
					 GetTransparent (),
					 true);

	return true;
}