<div dir="ltr"><div>compositor: Add DirectFB compositor with EGL and Pixman</div><div> support</div><div><br></div><div>Please see <a href="http://www.directfb.org/docs/DirectFB_Foreseeing_2013-">http://www.directfb.org/docs/DirectFB_Foreseeing_2013-</a></div>
<div>10-07.pdf</div><div>and <a href="http://www.directfb.org/docs/DirectFB_EGL_2013-10-07.pdf">http://www.directfb.org/docs/DirectFB_EGL_2013-10-07.pdf</a> for details</div><div>and plans.</div><div><br></div><div>With this version you can run Weston on any DirectFB enabled platform</div>
<div>including OpenGL ES support</div><div>via EGL where available.</div><div>---</div><div> src/Makefile.am | 25 +</div><div> src/compositor-directfb-input.cpp | 214 +++++</div><div> src/compositor-directfb-input.h | 91 +++</div>
<div> src/compositor-directfb.cpp | 1614 +++++++++++++++++++++++++++++++++++++</div><div> src/compositor-directfb.h | 225 ++++++</div><div> src/compositor.c | 13 +</div><div> 6 files changed, 2182 insertions(+)</div>
<div> create mode 100644 src/compositor-directfb-input.cpp</div><div> create mode 100644 src/compositor-directfb-input.h</div><div> create mode 100644 src/compositor-directfb.cpp</div><div> create mode 100644 src/compositor-directfb.h</div>
<div><br></div><div>diff --git a/src/Makefile.am b/src/Makefile.am</div><div>index 4224495..4da3039 100644</div><div>--- a/src/Makefile.am</div><div>+++ b/src/Makefile.am</div><div>@@ -117,6 +117,7 @@ module_LTLIBRARIES =<span class="" style="white-space:pre"> </span>\</div>
<div> <span class="" style="white-space:pre"> </span>$(drm_backend)<span class="" style="white-space:pre"> </span>\</div><div> <span class="" style="white-space:pre"> </span>$(wayland_backend)<span class="" style="white-space:pre"> </span>\</div>
<div> <span class="" style="white-space:pre"> </span>$(headless_backend)<span class="" style="white-space:pre"> </span>\</div><div>+<span class="" style="white-space:pre"> </span>$(directfb_backend)<span class="" style="white-space:pre"> </span>\</div>
<div> <span class="" style="white-space:pre"> </span>$(fbdev_backend)<span class="" style="white-space:pre"> </span>\</div><div> <span class="" style="white-space:pre"> </span>$(rdp_backend)</div><div> </div><div>@@ -237,6 +238,30 @@ headless_backend_la_CFLAGS =<span class="" style="white-space:pre"> </span>\</div>
<div> headless_backend_la_SOURCES = compositor-headless.c</div><div> endif</div><div> </div><div>+if ENABLE_DIRECTFB_COMPOSITOR</div><div>+directfb_backend = <a href="http://directfb-backend.la">directfb-backend.la</a></div>
<div>+directfb_backend_la_LDFLAGS = -module -avoid-version</div><div>+directfb_backend_la_LIBADD = \</div><div>+<span class="" style="white-space:pre"> </span>$(COMPOSITOR_LIBS) \</div><div>+<span class="" style="white-space:pre"> </span>$(DIRECTFB_COMPOSITOR_LIBS) \</div>
<div>+<span class="" style="white-space:pre"> </span>$(DRM_COMPOSITOR_LIBS) \</div><div>+<span class="" style="white-space:pre"> </span>../shared/<a href="http://libshared.la">libshared.la</a></div><div>+directfb_backend_la_CFLAGS = \</div>
<div>+<span class="" style="white-space:pre"> </span>$(COMPOSITOR_CFLAGS) \</div><div>+<span class="" style="white-space:pre"> </span>$(DIRECTFB_COMPOSITOR_CFLAGS) \</div><div>+<span class="" style="white-space:pre"> </span>$(PIXMAN_CFLAGS) \</div>
<div>+<span class="" style="white-space:pre"> </span>$(GCC_CFLAGS)</div><div>+directfb_backend_la_CXXFLAGS = \</div><div>+<span class="" style="white-space:pre"> </span>$(directfb_backend_la_CFLAGS)</div><div>+directfb_backend_la_SOURCES = \</div>
<div>+<span class="" style="white-space:pre"> </span>compositor-directfb.cpp \</div><div>+<span class="" style="white-space:pre"> </span>compositor-directfb-input.cpp \</div><div>+<span class="" style="white-space:pre"> </span>launcher-util.c</div>
<div>+# Replaced by weston-dfb-adapter for now</div><div>+#<span class="" style="white-space:pre"> </span>compositor-directfb-windows.cpp \</div><div>+#</div><div>+endif</div><div>+</div><div> if ENABLE_FBDEV_COMPOSITOR</div>
<div> fbdev_backend = <a href="http://fbdev-backend.la">fbdev-backend.la</a></div><div> fbdev_backend_la_LDFLAGS = -module -avoid-version</div><div>diff --git a/src/compositor-directfb-input.cpp b/src/compositor-directfb-input.cpp</div>
<div>new file mode 100644</div><div>index 0000000..9c08f75</div><div>--- /dev/null</div><div>+++ b/src/compositor-directfb-input.cpp</div><div>@@ -0,0 +1,214 @@</div><div>+/*</div><div>+ * Copyright © 2008-2011 Kristian Høgsberg</div>
<div>+ * Copyright © 2011 Intel Corporation</div><div>+ * Copyright © 2012 Raspberry Pi Foundation</div><div>+ * Copyright © 2013 Philip Withnall</div><div>+ *</div><div>+ * Permission to use, copy, modify, distribute, and sell this software and</div>
<div>+ * its documentation for any purpose is hereby granted without fee, provided</div><div>+ * that the above copyright notice appear in all copies and that both that</div><div>+ * copyright notice and this permission notice appear in supporting</div>
<div>+ * documentation, and that the name of the copyright holders not be used in</div><div>+ * advertising or publicity pertaining to distribution of the software</div><div>+ * without specific, written prior permission. The copyright holders make</div>
<div>+ * no representations about the suitability of this software for any</div><div>+ * purpose. It is provided "as is" without express or implied warranty.</div><div>+ *</div><div>+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS</div>
<div>+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND</div><div>+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY</div><div>+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER</div>
<div>+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF</div><div>+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN</div><div>+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</div>
<div>+ */</div><div>+</div><div>+#include "config.h"</div><div>+</div><div>+#include <++dfb.h></div><div>+</div><div>+#include <++dfb_mangle.h></div><div>+#include <wayland-dfb.h></div><div>+#include <++dfb_unmangle.h></div>
<div>+</div><div>+#include <stdexcept></div><div>+</div><div>+extern "C" {</div><div>+#include <errno.h></div><div>+#include <stdlib.h></div><div>+#include <stdio.h></div><div>+#include <string.h></div>
<div>+#include <math.h></div><div>+#include <sys/mman.h></div><div>+#include <sys/types.h></div><div>+#include <fcntl.h></div><div>+#include <unistd.h></div><div>+#include <linux/fb.h></div>
<div>+#include <linux/input.h></div><div>+}</div><div>+</div><div>+#include "compositor-directfb.h"</div><div>+#include "compositor-directfb-input.h"</div><div>+</div><div>+</div><div>+D_DEBUG_DOMAIN( WestonDFB_Input, "WestonDFB/Input", "Weston DirectFB Input" );</div>
<div>+</div><div>+/**********************************************************************************************************************/</div><div>+</div><div>+InputDeviceManager::InputDeviceManager( directfb_compositor &compositor )</div>
<div>+<span class="" style="white-space:pre"> </span>:</div><div>+<span class="" style="white-space:pre"> </span>compositor( compositor )</div><div>+{</div><div>+}</div><div>+</div><div>+InputDeviceManager::~InputDeviceManager()</div>
<div>+{</div><div>+}</div><div>+</div><div>+void</div><div>+InputDeviceManager::init()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, "InputDeviceManager::%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>struct xkb_keymap *keymap;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_seat_init(&seat, &compositor.base, "default");</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (compositor.param.no_input)</div><div>+<span class="" style="white-space:pre"> </span>return;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_seat_init_pointer(&seat);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>keymap = NULL;//directfb_compositor_get_keymap(c);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (weston_seat_init_keyboard( &seat, keymap ) < 0)</div>
<div>+<span class="" style="white-space:pre"> </span>return;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (keymap)</div><div>+<span class="" style="white-space:pre"> </span>xkb_map_unref(keymap);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>//notify_keyboard_focus_in(&seat, &keys, STATE_UPDATE_AUTOMATIC);</div><div>+</div><div>+//<span class="" style="white-space:pre"> </span>directfb_compositor_setup_xkb(c);</div>
<div>+}</div><div>+</div><div>+void</div><div>+InputDeviceManager::shutdown()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, "InputDeviceManager::%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>devices.clear();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_seat_release(&seat);</div><div>+}</div><div>+</div><div>+void</div>
<div>+InputDeviceManager::AddDevice( DFBInputDeviceID device_id )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, "InputDeviceManager::%s( %u )\n", __FUNCTION__, device_id );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>auto device = devices[device_id];</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (device) {</div><div>+<span class="" style="white-space:pre"> </span>D_WARN( "device %u already added", device_id );</div>
<div>+<span class="" style="white-space:pre"> </span>return;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>device = compositor.dfb.GetInputDevice( device_id );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>devices[device_id] = device;</div><div>+}</div><div>+</div><div>+void</div><div>+InputDeviceManager::RemoveDevice( DFBInputDeviceID device_id )</div><div>+{</div>
<div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, "InputDeviceManager::%s( %u )\n", __FUNCTION__, device_id );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!devices[device_id])</div>
<div>+<span class="" style="white-space:pre"> </span>D_WARN( "device %u not added", device_id );</div><div>+<span class="" style="white-space:pre"> </span>else</div><div>+<span class="" style="white-space:pre"> </span>devices[device_id] = NULL;</div>
<div>+}</div><div>+</div><div>+void</div><div>+InputDeviceManager::HandleInputEvent( const DFBInputEvent &event )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, "InputDeviceManager::%s( %p, event %p ) <- type 0x%04x\n", __FUNCTION__, this, &event, event.type );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>switch (event.type) {</div><div>+<span class="" style="white-space:pre"> </span>//case DIET_DEVICE_ADDED:</div><div>+<span class="" style="white-space:pre"> </span>// AddDevice( event.device_id );</div>
<div>+<span class="" style="white-space:pre"> </span>// break;</div><div>+<span class="" style="white-space:pre"> </span>//</div><div>+<span class="" style="white-space:pre"> </span>//case DIET_DEVICE_REMOVED:</div><div>
+<span class="" style="white-space:pre"> </span>// RemoveDevice( event.device_id );</div><div>+<span class="" style="white-space:pre"> </span>// break;</div><div>+<span class="" style="white-space:pre"> </span></div>
<div>+<span class="" style="white-space:pre"> </span>case DIET_AXISMOTION:</div><div>+<span class="" style="white-space:pre"> </span>switch (event.axis) {</div><div>+<span class="" style="white-space:pre"> </span>case DIAI_X:</div>
<div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, " -> AXIS X %d\n", event.axisabs );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (event.flags & DIEF_AXISABS) {</div>
<div>+<span class="" style="white-space:pre"> </span>px = event.axisabs;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>notify_motion_absolute( &seat, weston_compositor_get_time(),</div><div>
+<span class="" style="white-space:pre"> </span>wl_fixed_from_int( px ),</div><div>+<span class="" style="white-space:pre"> </span>wl_fixed_from_int( py ) );</div><div>+<span class="" style="white-space:pre"> </span>} else</div>
<div>+<span class="" style="white-space:pre"> </span>notify_motion( &seat, weston_compositor_get_time(),</div><div>+<span class="" style="white-space:pre"> </span> wl_fixed_from_int( event.axisrel ), 0 );</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DIAI_Y:</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, " -> AXIS Y %d\n", event.axisabs );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (event.flags & DIEF_AXISABS) {</div><div>+<span class="" style="white-space:pre"> </span>py = event.axisabs;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>notify_motion_absolute( &seat, weston_compositor_get_time(),</div>
<div>+<span class="" style="white-space:pre"> </span>wl_fixed_from_int( px ),</div><div>+<span class="" style="white-space:pre"> </span>wl_fixed_from_int( py ) );</div><div>+<span class="" style="white-space:pre"> </span>} else</div>
<div>+<span class="" style="white-space:pre"> </span>notify_motion( &seat, weston_compositor_get_time(),</div><div>+<span class="" style="white-space:pre"> </span> 0, wl_fixed_from_int( event.axisrel ) );</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DIET_BUTTONPRESS:</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, " -> BUTTON PRESS %d\n", event.button );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>notify_button( &seat, weston_compositor_get_time(), event.button + BTN_LEFT - DIBI_FIRST,</div><div>+<span class="" style="white-space:pre"> </span> WL_POINTER_BUTTON_STATE_PRESSED );</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DIET_BUTTONRELEASE:</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, " -> BUTTON RELEASE %d\n", event.button );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>notify_button( &seat, weston_compositor_get_time(), event.button + BTN_LEFT - DIBI_FIRST,</div><div>+<span class="" style="white-space:pre"> </span> WL_POINTER_BUTTON_STATE_RELEASED );</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DIET_KEYPRESS:</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, " -> KEY PRESS %d\n", event.key_code );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>notify_key( &seat, weston_compositor_get_time(), event.key_code,</div><div>+<span class="" style="white-space:pre"> </span> WL_KEYBOARD_KEY_STATE_PRESSED, STATE_UPDATE_AUTOMATIC );</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DIET_KEYRELEASE:</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Input, " -> KEY RELEASE %d\n", event.key_code );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>notify_key( &seat, weston_compositor_get_time(), event.key_code,</div><div>+<span class="" style="white-space:pre"> </span> WL_KEYBOARD_KEY_STATE_RELEASED, STATE_UPDATE_AUTOMATIC );</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+}</div><div>+</div><div>diff --git a/src/compositor-directfb-input.h b/src/compositor-directfb-input.h</div><div>new file mode 100644</div><div>index 0000000..a8adef3</div><div>--- /dev/null</div><div>+++ b/src/compositor-directfb-input.h</div>
<div>@@ -0,0 +1,91 @@</div><div>+/*</div><div>+ * Copyright © 2008-2011 Kristian Høgsberg</div><div>+ * Copyright © 2011 Intel Corporation</div><div>+ * Copyright © 2012 Raspberry Pi Foundation</div><div>+ * Copyright © 2013 Philip Withnall</div>
<div>+ *</div><div>+ * Permission to use, copy, modify, distribute, and sell this software and</div><div>+ * its documentation for any purpose is hereby granted without fee, provided</div><div>+ * that the above copyright notice appear in all copies and that both that</div>
<div>+ * copyright notice and this permission notice appear in supporting</div><div>+ * documentation, and that the name of the copyright holders not be used in</div><div>+ * advertising or publicity pertaining to distribution of the software</div>
<div>+ * without specific, written prior permission. The copyright holders make</div><div>+ * no representations about the suitability of this software for any</div><div>+ * purpose. It is provided "as is" without express or implied warranty.</div>
<div>+ *</div><div>+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS</div><div>+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND</div><div>+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY</div>
<div>+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER</div><div>+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF</div><div>+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN</div>
<div>+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</div><div>+ */</div><div>+</div><div>+#ifndef __COMPOSITOR_DIRECTFB_INPUT_H__</div><div>+#define __COMPOSITOR_DIRECTFB_INPUT_H__</div><div>+</div><div>+#include <++dfb.h></div>
<div>+</div><div>+#include <++dfb_mangle.h></div><div>+#include <wayland-dfb.h></div><div>+#include <++dfb_unmangle.h></div><div>+</div><div>+#include <stdexcept></div><div>+</div><div>+extern "C" {</div>
<div>+#include <errno.h></div><div>+#include <stdlib.h></div><div>+#include <stdio.h></div><div>+#include <string.h></div><div>+#include <math.h></div><div>+#include <sys/mman.h></div><div>
+#include <sys/types.h></div><div>+#include <fcntl.h></div><div>+#include <unistd.h></div><div>+#include <linux/fb.h></div><div>+#include <linux/input.h></div><div>+</div><div>+#include "launcher-util.h"</div>
<div>+#include "gl-renderer.h"</div><div>+#include "pixman-renderer.h"</div><div>+}</div><div>+</div><div>+class InputDevice {</div><div>+private:</div><div>+</div><div>+public:</div><div>+</div><div>+};</div>
<div>+</div><div>+class directfb_compositor;</div><div>+</div><div>+</div><div>+class InputDeviceManager {</div><div>+private:</div><div>+<span class="" style="white-space:pre"> </span>directfb_compositor &compositor;</div>
<div>+<span class="" style="white-space:pre"> </span>struct weston_seat seat;</div><div>+<span class="" style="white-space:pre"> </span>std::map<DFBInputDeviceID,IDirectFBInputDevice> devices;</div>
<div>+</div><div>+public:</div><div>+<span class="" style="white-space:pre"> </span>InputDeviceManager( directfb_compositor &compositor );</div><div>+<span class="" style="white-space:pre"> </span>~InputDeviceManager();</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>void AddDevice( DFBInputDeviceID device_id );</div><div>+<span class="" style="white-space:pre"> </span>void RemoveDevice( DFBInputDeviceID device_id );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>void HandleInputEvent( const DFBInputEvent &event );</div><div>+</div><div>+private:</div><div>+<span class="" style="white-space:pre"> </span>friend class directfb_compositor;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>int px, py;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>void init();</div><div>+<span class="" style="white-space:pre"> </span>void shutdown();</div>
<div>+};</div><div>+</div><div>+</div><div>+#endif</div><div>+</div><div>diff --git a/src/compositor-directfb.cpp b/src/compositor-directfb.cpp</div><div>new file mode 100644</div><div>index 0000000..cc1e764</div><div>--- /dev/null</div>
<div>+++ b/src/compositor-directfb.cpp</div><div>@@ -0,0 +1,1614 @@</div><div>+/*</div><div>+ * Copyright © 2008-2011 Kristian Høgsberg</div><div>+ * Copyright © 2011 Intel Corporation</div><div>+ * Copyright © 2012 Raspberry Pi Foundation</div>
<div>+ * Copyright © 2013 Philip Withnall</div><div>+ *</div><div>+ * Permission to use, copy, modify, distribute, and sell this software and</div><div>+ * its documentation for any purpose is hereby granted without fee, provided</div>
<div>+ * that the above copyright notice appear in all copies and that both that</div><div>+ * copyright notice and this permission notice appear in supporting</div><div>+ * documentation, and that the name of the copyright holders not be used in</div>
<div>+ * advertising or publicity pertaining to distribution of the software</div><div>+ * without specific, written prior permission. The copyright holders make</div><div>+ * no representations about the suitability of this software for any</div>
<div>+ * purpose. It is provided "as is" without express or implied warranty.</div><div>+ *</div><div>+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS</div><div>+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND</div>
<div>+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY</div><div>+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER</div><div>+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF</div>
<div>+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN</div><div>+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</div><div>+ */</div><div>+</div><div>+#include "config.h"</div>
<div>+</div><div>+#include <++dfb.h></div><div>+</div><div>+#include <++dfb_mangle.h></div><div>+#include <wayland-dfb.h></div><div>+#include <++dfb_unmangle.h></div><div>+</div><div>+#include <stdexcept></div>
<div>+</div><div>+#include <wayland-client.h></div><div>+</div><div>+extern "C" {</div><div>+#include <errno.h></div><div>+#include <stdlib.h></div><div>+#include <stdio.h></div><div>+#include <string.h></div>
<div>+#include <math.h></div><div>+#include <sys/mman.h></div><div>+#include <sys/types.h></div><div>+#include <fcntl.h></div><div>+#include <unistd.h></div><div>+#include <linux/fb.h></div>
<div>+#include <linux/input.h></div><div>+</div><div>+#include "compositor.h"</div><div>+#include "launcher-util.h"</div><div>+#include "gl-renderer.h"</div><div>+#include "pixman-renderer.h"</div>
<div>+}</div><div>+</div><div>+#include "compositor-directfb.h"</div><div>+</div><div>+</div><div>+D_DEBUG_DOMAIN( WestonDFB_Compositor, "WestonDFB/Compositor", "Weston DirectFB Compositor" );</div>
<div>+D_DEBUG_DOMAIN( WestonDFB_Output, "WestonDFB/Output", "Weston DirectFB Output" );</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+static const char default_seat[] = "seat0";</div><div>+</div><div>+static struct gl_renderer_interface *gl_renderer;</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+static void</div><div>+directfb_output_start_repaint_loop(struct weston_output *output)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>uint32_t msec;</div><div>+<span class="" style="white-space:pre"> </span>struct timeval tv;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>gettimeofday(&tv, NULL);</div>
<div>+<span class="" style="white-space:pre"> </span>msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;</div><div>+<span class="" style="white-space:pre"> </span>weston_output_finish_frame(output, msec);</div><div>+}</div><div>
+</div><div>+/**********************************************************************************************************************/</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+static void</div><div>+output_get_buffer_damage(struct weston_output *output,</div><div>+<span class="" style="white-space:pre"> </span> pixman_region32_t *buffer_damage)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *dfboutput = to_directfb_output(output);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>EGLint buffer_age = 0;</div><div>+<span class="" style="white-space:pre"> </span>int i;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (buffer_age == 0 || buffer_age - 1 > BUFFER_DAMAGE_COUNT)</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_copy(buffer_damage, &output->region);</div><div>+<span class="" style="white-space:pre"> </span>else</div><div>+<span class="" style="white-space:pre"> </span>for (i = 0; i < buffer_age - 1; i++)</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_union(buffer_damage, buffer_damage,</div><div>+<span class="" style="white-space:pre"> </span> &dfboutput->buffer_damage[i]);</div><div>
+}</div><div>+</div><div>+static void</div><div>+output_rotate_damage(struct weston_output *output,</div><div>+<span class="" style="white-space:pre"> </span> pixman_region32_t *output_damage)</div><div>+{</div><div>
+<span class="" style="white-space:pre"> </span>struct directfb_output *dfboutput = to_directfb_output(output);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>int i;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>for (i = BUFFER_DAMAGE_COUNT - 1; i >= 1; i--)</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_copy(&dfboutput->buffer_damage[i],</div><div>+<span class="" style="white-space:pre"> </span> &dfboutput->buffer_damage[i - 1]);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_copy(&dfboutput->buffer_damage[0], output_damage);</div><div>+}</div><div>+</div><div>+static void</div><div>+box_scale(pixman_box32_t *dst, int scale)</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>dst->x1 *= scale;</div><div>+<span class="" style="white-space:pre"> </span>dst->x2 *= scale;</div><div>+<span class="" style="white-space:pre"> </span>dst->y1 *= scale;</div>
<div>+<span class="" style="white-space:pre"> </span>dst->y2 *= scale;</div><div>+}</div><div>+</div><div>+static void</div><div>+scale_region (pixman_region32_t *region, int scale)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>pixman_box32_t *rects, *scaled_rects;</div>
<div>+<span class="" style="white-space:pre"> </span>int nrects, i;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (scale != 1) {</div><div>+<span class="" style="white-space:pre"> </span>rects = pixman_region32_rectangles(region, &nrects);</div>
<div>+<span class="" style="white-space:pre"> </span>scaled_rects = (pixman_box32_t*) calloc(nrects, sizeof(pixman_box32_t));</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>for (i = 0; i < nrects; i++) {</div>
<div>+<span class="" style="white-space:pre"> </span>scaled_rects[i] = rects[i];</div><div>+<span class="" style="white-space:pre"> </span>box_scale(&scaled_rects[i], scale);</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_clear(region);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_init_rects (region, scaled_rects, nrects);</div><div>
+<span class="" style="white-space:pre"> </span>free (scaled_rects);</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+}</div><div>+</div><div>+static void</div><div>+transform_region (pixman_region32_t *region, int width, int height, enum wl_output_transform transform)</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>pixman_box32_t *rects, *transformed_rects;</div><div>+<span class="" style="white-space:pre"> </span>int nrects, i;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (transform == WL_OUTPUT_TRANSFORM_NORMAL)</div>
<div>+<span class="" style="white-space:pre"> </span>return;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>rects = pixman_region32_rectangles(region, &nrects);</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects = (pixman_box32_t*) calloc(nrects, sizeof(pixman_box32_t));</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>for (i = 0; i < nrects; i++) {</div><div>+<span class="" style="white-space:pre"> </span>switch (transform) {</div><div>+<span class="" style="white-space:pre"> </span>default:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_NORMAL:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = rects[i].y1;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_90:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = height - rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = rects[i].x1;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = height - rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_180:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = width - rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = height - rects[i].y2;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = width - rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = height - rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_270:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = width - rects[i].x2;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = width - rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = width - rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = rects[i].y1;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = width - rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_90:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = height - rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = width - rects[i].x2;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = height - rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = width - rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_180:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = height - rects[i].y2;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = height - rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_270:</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x1 = rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y1 = rects[i].x1;</div>
<div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].x2 = rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>transformed_rects[i].y2 = rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_clear(region);</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_init_rects (region, transformed_rects, nrects);</div><div>+<span class="" style="white-space:pre"> </span>free (transformed_rects);</div><div>+}</div><div>
+</div><div>+static void</div><div>+region_global_to_output(struct weston_output *output, pixman_region32_t *region)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_translate(region, -output->x, -output->y);</div>
<div>+<span class="" style="white-space:pre"> </span>transform_region (region, output->width, output->height, (wl_output_transform) output->transform);</div><div>+<span class="" style="white-space:pre"> </span>scale_region (region, output->current_scale);</div>
<div>+}</div><div>+</div><div>+#define D2F(v) pixman_double_to_fixed((double)v)</div><div>+</div><div>+static void</div><div>+repaint_region(struct weston_view *ev, struct weston_output *output,</div><div>+<span class="" style="white-space:pre"> </span> pixman_region32_t *region, pixman_region32_t *surf_region,</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_op_t pixman_op)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( weston_surface %p )\n", __FUNCTION__, ev );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_surface_state *state = (directfb_surface_state*) ev->surface->compositor_state;</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface source = state->surface;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!source) {</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, " -> No surface attached!\n" );</div>
<div>+<span class="" style="white-space:pre"> </span>return;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *dfboutput = to_directfb_output(output);</div>
<div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface dest = dfboutput->surface;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_t final_region;</div><div>
+<span class="" style="white-space:pre"> </span>float surface_x, surface_y;</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_t transform;</div><div>+<span class="" style="white-space:pre"> </span>pixman_fixed_t fw, fh;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* The final region to be painted is the intersection of</div><div>+<span class="" style="white-space:pre"> </span> * 'region' and 'surf_region'. However, 'region' is in the global</div>
<div>+<span class="" style="white-space:pre"> </span> * coordinates, and 'surf_region' is in the surface-local</div><div>+<span class="" style="white-space:pre"> </span> * coordinates</div><div>+<span class="" style="white-space:pre"> </span> */</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_init(&final_region);</div><div>+<span class="" style="white-space:pre"> </span>if (surf_region) {</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_copy(&final_region, surf_region);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Convert from surface to global coordinates */</div><div>+<span class="" style="white-space:pre"> </span>if (!ev->transform.enabled) {</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_translate(&final_region, ev->geometry.x, ev->geometry.y);</div>
<div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>weston_view_to_global_float(ev, 0, 0, &surface_x, &surface_y);</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_translate(&final_region, (int)surface_x, (int)surface_y);</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* We need to paint the intersection */</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_intersect(&final_region, &final_region, region);</div>
<div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>/* If there is no surface region, just use the global region */</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_copy(&final_region, region);</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Convert from global to output coord */</div><div>+<span class="" style="white-space:pre"> </span>region_global_to_output(output, &final_region);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBRegion dfbclip( final_region.extents.x1, final_region.extents.y1, final_region.extents.x2-1, final_region.extents.y2-1 );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dest.SetClip( &dfbclip );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Set up the source transformation based on the surface</div><div>+<span class="" style="white-space:pre"> </span> position, the output position/transform/scale and the client</div>
<div>+<span class="" style="white-space:pre"> </span> specified buffer transform/scale */</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_init_identity(&transform);</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_scale(&transform, NULL,</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed ((double)1.0/output->current_scale),</div><div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed ((double)1.0/output->current_scale));</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>fw = pixman_int_to_fixed(output->width);</div><div>+<span class="" style="white-space:pre"> </span>fh = pixman_int_to_fixed(output->height);</div><div>
+<span class="" style="white-space:pre"> </span>switch (output->transform) {</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_NORMAL:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED:</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_90:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_90:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform, NULL, 0, -pixman_fixed_1);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, 0, fh);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_180:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_180:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform, NULL, -pixman_fixed_1, 0);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, fw, fh);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_270:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_270:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform, NULL, 0, pixman_fixed_1);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, fw, 0);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>switch (output->transform) {</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_90:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_180:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_270:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_scale(&transform, NULL,</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed (-1),</div><div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed (1));</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, fw, 0);</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL,</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed (output->x),</div><div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed (output->y));</div><div>+</div><div>
+<span class="" style="white-space:pre"> </span>if (ev->transform.enabled) {</div><div>+<span class="" style="white-space:pre"> </span>/* Pixman supports only 2D transform matrix, but Weston uses 3D,</div><div>+<span class="" style="white-space:pre"> </span> * so we're omitting Z coordinate here</div>
<div>+<span class="" style="white-space:pre"> </span> */</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_t surface_transform = {{</div><div>+<span class="" style="white-space:pre"> </span>{ D2F(ev->transform.matrix.d[0]),</div>
<div>+<span class="" style="white-space:pre"> </span>D2F(ev->transform.matrix.d[4]),</div><div>+<span class="" style="white-space:pre"> </span>D2F(ev->transform.matrix.d[12]),</div><div>+<span class="" style="white-space:pre"> </span>},</div>
<div>+<span class="" style="white-space:pre"> </span>{ D2F(ev->transform.matrix.d[1]),</div><div>+<span class="" style="white-space:pre"> </span>D2F(ev->transform.matrix.d[5]),</div><div>+<span class="" style="white-space:pre"> </span>D2F(ev->transform.matrix.d[13]),</div>
<div>+<span class="" style="white-space:pre"> </span>},</div><div>+<span class="" style="white-space:pre"> </span>{ D2F(ev->transform.matrix.d[3]),</div><div>+<span class="" style="white-space:pre"> </span>D2F(ev->transform.matrix.d[7]),</div>
<div>+<span class="" style="white-space:pre"> </span>D2F(ev->transform.matrix.d[15]),</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}};</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_invert(&surface_transform, &surface_transform);</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_multiply (&transform, &surface_transform, &transform);</div>
<div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL,</div><div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed ((double)-ev->geometry.x),</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed ((double)-ev->geometry.y));</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>fw = pixman_int_to_fixed(ev->geometry.width);</div>
<div>+<span class="" style="white-space:pre"> </span>fh = pixman_int_to_fixed(ev->geometry.height);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>switch (ev->surface->buffer_transform) {</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_90:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_180:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_270:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_scale(&transform, NULL,</div><div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed (-1),</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed (1));</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, fw, 0);</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>switch (ev->surface->buffer_transform) {</div><div>+<span class="" style="white-space:pre"> </span>default:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_NORMAL:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED:</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_90:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_90:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform, NULL, 0, pixman_fixed_1);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, fh, 0);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_180:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_180:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform, NULL, -pixman_fixed_1, 0);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, fw, fh);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_270:</div>
<div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_FLIPPED_270:</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform, NULL, 0, -pixman_fixed_1);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL, 0, fw);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_scale(&transform, NULL,</div><div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed ((double)ev->surface->buffer_scale),</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_double_to_fixed ((double)ev->surface->buffer_scale));</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (pixman_op == PIXMAN_OP_OVER && DFB_PIXELFORMAT_HAS_ALPHA(state->format) && !dfboutput->initial) {</div>
<div>+<span class="" style="white-space:pre"> </span>dest.SetBlittingFlags( DSBLIT_BLEND_ALPHACHANNEL );</div><div>+<span class="" style="white-space:pre"> </span>dest.SetPorterDuff( DSPD_SRC_OVER );</div><div>+<span class="" style="white-space:pre"> </span>} else</div>
<div>+<span class="" style="white-space:pre"> </span>dest.SetBlittingFlags( DSBLIT_NOFX );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dfboutput->initial = false;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dest.Blit( source, NULL, ev->geometry.x, ev->geometry.y );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_image_set_clip_region32 (dfboutput->shadow_surface, NULL);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_fini(&final_region);</div>
<div>+}</div><div>+</div><div>+static void</div><div>+draw_view(struct weston_view *ev, struct weston_output *output,</div><div>+<span class="" style="white-space:pre"> </span> pixman_region32_t *damage)<span class="" style="white-space:pre"> </span>/* in global coordinates */</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>/* repaint bounding region in global coordinates: */</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_t repaint;</div><div>+<span class="" style="white-space:pre"> </span>/* non-opaque region in surface coordinates: */</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_t surface_blend;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_init(&repaint);</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_intersect(&repaint,</div>
<div>+<span class="" style="white-space:pre"> </span> &ev->transform.boundingbox, damage);</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_subtract(&repaint, &repaint, &ev->clip);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!pixman_region32_not_empty(&repaint))</div><div>+<span class="" style="white-space:pre"> </span>goto out;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->zoom.active) {</div>
<div>+<span class="" style="white-space:pre"> </span>weston_log("pixman renderer does not support zoom\n");</div><div>+<span class="" style="white-space:pre"> </span>goto out;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* TODO: Implement repaint_region_complex() using pixman_composite_trapezoids() */</div><div>+<span class="" style="white-space:pre"> </span>if (ev->transform.enabled && ev->transform.matrix.type != WESTON_MATRIX_TRANSFORM_TRANSLATE) {</div>
<div>+<span class="" style="white-space:pre"> </span>repaint_region(ev, output, &repaint, NULL, PIXMAN_OP_OVER);</div><div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>/* blended region is whole surface minus opaque region: */</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_init_rect(&surface_blend, 0, 0,</div><div>+<span class="" style="white-space:pre"> </span> ev->geometry.width, ev->geometry.height);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (pixman_region32_not_empty(&ev->surface->opaque)) {</div>
<div>+<span class="" style="white-space:pre"> </span>repaint_region(ev, output, &repaint, &ev->surface->opaque, PIXMAN_OP_SRC);</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>if (pixman_region32_not_empty(&surface_blend)) {</div><div>+<span class="" style="white-space:pre"> </span>repaint_region(ev, output, &repaint, &surface_blend, PIXMAN_OP_OVER);</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_fini(&surface_blend);</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>out:</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_fini(&repaint);</div><div>+}</div><div>+</div><div>+static void</div>
<div>+repaint_surfaces(struct weston_output *output, pixman_region32_t *damage)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *dfboutput = to_directfb_output(output);</div>
<div>+<span class="" style="white-space:pre"> </span>struct weston_compositor *compositor = output->compositor;</div><div>+<span class="" style="white-space:pre"> </span>struct weston_view *view;</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>dfboutput->initial = true;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>wl_list_for_each_reverse(view, &compositor->view_list, link)</div>
<div>+<span class="" style="white-space:pre"> </span>if (view->plane == &compositor->primary_plane)</div><div>+<span class="" style="white-space:pre"> </span>draw_view(view, output, damage);</div><div>+}</div>
<div>+</div><div>+/**********************************************************************************************************************/</div><div>+</div><div>+static void</div><div>+directfb_output_repaint_2d(struct weston_output *output,</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_region32_t *output_damage)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *dfboutput = to_directfb_output(output);</div>
<div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface surface = dfboutput->surface;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_t buffer_damage, total_damage;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_init(&total_damage);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_init(&buffer_damage);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output_get_buffer_damage(output, &buffer_damage);</div>
<div>+<span class="" style="white-space:pre"> </span>output_rotate_damage(output, output_damage);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_union(&total_damage, &buffer_damage, output_damage);</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>repaint_surfaces(output, &total_damage);</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_box32_t *rects;</div>
<div>+<span class="" style="white-space:pre"> </span>int nrects;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>rects = pixman_region32_rectangles(&total_damage, &nrects);</div><div>+</div><div>
+<span class="" style="white-space:pre"> </span>for (int i = 0; i < nrects; i++) {</div><div>+<span class="" style="white-space:pre"> </span>DFBRegion bounds = { rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2};</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb_updates_add( &dfboutput->flip_updates, &bounds );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_fini(&total_damage);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_fini(&buffer_damage);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_copy(&output->previous_damage, output_damage);</div>
<div>+<span class="" style="white-space:pre"> </span>wl_signal_emit(&output->frame_signal, output);</div><div>+}</div><div>+</div><div>+static int</div><div>+directfb_output_repaint_gl(struct weston_output *base,</div>
<div>+<span class="" style="white-space:pre"> </span> pixman_region32_t *damage)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *output = to_directfb_output(base);</div>
<div>+<span class="" style="white-space:pre"> </span>struct weston_compositor *ec = output->base.compositor;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Schedule the end of the frame. We do not sync this to the frame</div><div>+<span class="" style="white-space:pre"> </span> * buffer clock because users who want that should be using the DRM</div>
<div>+<span class="" style="white-space:pre"> </span> * compositor. FBIO_WAITFORVSYNC blocks and FB_ACTIVATE_VBL requires</div><div>+<span class="" style="white-space:pre"> </span> * panning, which is broken in most kernel drivers.</div>
<div>+<span class="" style="white-space:pre"> </span> *</div><div>+<span class="" style="white-space:pre"> </span> * Finish the frame synchronised to the specified refresh rate. The</div><div>+<span class="" style="white-space:pre"> </span> * refresh rate is given in mHz and the interval in ms. */</div>
<div>+<span class="" style="white-space:pre"> </span>wl_event_source_timer_update(output->finish_frame_timer,</div><div>+<span class="" style="white-space:pre"> </span> 1000 / output->mode.refresh);</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>if (output->param.use_2d) {</div><div>+<span class="" style="white-space:pre"> </span>EGLDisplay display = eglGetCurrentDisplay();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (display != EGL_NO_DISPLAY)</div>
<div>+<span class="" style="white-space:pre"> </span>eglMakeCurrent( display,</div><div>+<span class="" style="white-space:pre"> </span>EGL_NO_SURFACE, EGL_NO_SURFACE,</div><div>+<span class="" style="white-space:pre"> </span>EGL_NO_CONTEXT );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_ASSERT( eglGetCurrentDisplay() == NULL );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_repaint_2d( base, damage );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->flip_updates.num_regions) {</div><div>+<span class="" style="white-space:pre"> </span>DFBRegion region( output->flip_updates.bounding );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>output->surface.Flip( ®ion, DSFLIP_NONE );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb_updates_reset( &output->flip_updates );</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>ec->renderer->repaint_output(base, damage);</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_subtract(&ec->primary_plane.damage,</div><div>+<span class="" style="white-space:pre"> </span> &ec->primary_plane.damage, damage);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>return 0;</div><div>+}</div><div>+</div><div>+static int</div><div>+directfb_output_repaint_pixman(struct weston_output *base, pixman_region32_t *damage)</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *output = to_directfb_output(base);</div><div>+<span class="" style="white-space:pre"> </span>struct weston_compositor *ec = output->base.compositor;</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_box32_t *rects;</div><div>+<span class="" style="white-space:pre"> </span>int nrects, i, src_x, src_y, x1, y1, x2, y2, width, height;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Schedule the end of the frame. We do not sync this to the frame</div><div>+<span class="" style="white-space:pre"> </span> * buffer clock because users who want that should be using the DRM</div>
<div>+<span class="" style="white-space:pre"> </span> * compositor. FBIO_WAITFORVSYNC blocks and FB_ACTIVATE_VBL requires</div><div>+<span class="" style="white-space:pre"> </span> * panning, which is broken in most kernel drivers.</div>
<div>+<span class="" style="white-space:pre"> </span> *</div><div>+<span class="" style="white-space:pre"> </span> * Finish the frame synchronised to the specified refresh rate. The</div><div>+<span class="" style="white-space:pre"> </span> * refresh rate is given in mHz and the interval in ms. */</div>
<div>+<span class="" style="white-space:pre"> </span>wl_event_source_timer_update(output->finish_frame_timer,</div><div>+<span class="" style="white-space:pre"> </span> 1000 / output->mode.refresh);</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>if (output->param.use_2d) {</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_repaint_2d( base, damage );</div><div>+<span class="" style="white-space:pre"> </span>} else {</div>
<div>+<span class="" style="white-space:pre"> </span>/* Repaint the damaged region onto the back buffer. */</div><div>+<span class="" style="white-space:pre"> </span>pixman_renderer_output_set_buffer(base, output->shadow_surface);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>ec->renderer->repaint_output(base, damage);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Transform and composite onto the frame buffer. */</div>
<div>+<span class="" style="white-space:pre"> </span>width = pixman_image_get_width(output->shadow_surface);</div><div>+<span class="" style="white-space:pre"> </span>height = pixman_image_get_height(output->shadow_surface);</div>
<div>+<span class="" style="white-space:pre"> </span>rects = pixman_region32_rectangles(damage, &nrects);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (nrects > 0) {</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface surface = output->surface;</div>
<div>+<span class="" style="white-space:pre"> </span>DFBRegion bounds = { -1, -1, -1, -1};</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>for (i = 0; i < nrects; i++) {</div><div>+<span class="" style="white-space:pre"> </span>switch (base->transform) {</div>
<div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_NORMAL:</div><div>+<span class="" style="white-space:pre"> </span>x1 = rects[i].x1;</div>
<div>+<span class="" style="white-space:pre"> </span>x2 = rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>y1 = rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>y2 = rects[i].y2;</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_180:</div><div>+<span class="" style="white-space:pre"> </span>x1 = width - rects[i].x2;</div>
<div>+<span class="" style="white-space:pre"> </span>x2 = width - rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>y1 = height - rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>y2 = height - rects[i].y1;</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_90:</div><div>+<span class="" style="white-space:pre"> </span>x1 = height - rects[i].y2;</div>
<div>+<span class="" style="white-space:pre"> </span>x2 = height - rects[i].y1;</div><div>+<span class="" style="white-space:pre"> </span>y1 = rects[i].x1;</div><div>+<span class="" style="white-space:pre"> </span>y2 = rects[i].x2;</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_270:</div><div>+<span class="" style="white-space:pre"> </span>x1 = rects[i].y1;</div>
<div>+<span class="" style="white-space:pre"> </span>x2 = rects[i].y2;</div><div>+<span class="" style="white-space:pre"> </span>y1 = width - rects[i].x2;</div><div>+<span class="" style="white-space:pre"> </span>y2 = width - rects[i].x1;</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>src_x = x1;</div><div>+<span class="" style="white-space:pre"> </span>src_y = y1;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (bounds.x1 == -1 || bounds.x1 > x1)</div><div>+<span class="" style="white-space:pre"> </span>bounds.x1 = x1;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (bounds.y1 == -1 || bounds.y1 > y1)</div>
<div>+<span class="" style="white-space:pre"> </span>bounds.y1 = y1;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (bounds.x2 == -1 || bounds.x2 < x2)</div><div>+<span class="" style="white-space:pre"> </span>bounds.x2 = x2;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (bounds.y2 == -1 || bounds.y2 < y2)</div><div>+<span class="" style="white-space:pre"> </span>bounds.y2 = y2;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBRectangle rect = {x1, y1, /* dest_x, dest_y */</div>
<div>+<span class="" style="white-space:pre"> </span>x2 - x1, /* width */</div><div>+<span class="" style="white-space:pre"> </span>y2 - y1<span class="" style="white-space:pre"> </span>/* height */};</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>surface.Write( (char*) output->shadow_buf</div><div>+<span class="" style="white-space:pre"> </span> + src_y * output->fb_info.line_length</div><div>
+<span class="" style="white-space:pre"> </span> + DFB_BYTES_PER_LINE( output->fb_info.format, src_x ),</div><div>+<span class="" style="white-space:pre"> </span> output->fb_info.line_length,</div>
<div>+<span class="" style="white-space:pre"> </span> &rect );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb_updates_add( &output->flip_updates, &bounds );</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->flip_updates.num_regions) {</div>
<div>+<span class="" style="white-space:pre"> </span>DFBRegion region( output->flip_updates.bounding );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->surface.Flip( ®ion, DSFLIP_NONE );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb_updates_reset( &output->flip_updates );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Update the damage region. */</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_region32_subtract(&ec->primary_plane.damage,</div><div>+<span class="" style="white-space:pre"> </span> &ec->primary_plane.damage, damage);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>return 0;</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+static int</div><div>+finish_frame_handler(void *data)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *output = (struct directfb_output *) data;</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_start_repaint_loop(&output->base);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>return 1;</div><div>+}</div><div>+</div><div>+static pixman_format_code_t</div><div>+calculate_pixman_format( DFBSurfacePixelFormat format )</div><div>+{</div>
<div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s( %s )\n", __FUNCTION__, dfb_pixelformat_name( format ) );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>switch (format) {</div>
<div>+<span class="" style="white-space:pre"> </span>case DSPF_ARGB:</div><div>+<span class="" style="white-space:pre"> </span>return PIXMAN_a8r8g8b8;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DSPF_ABGR:</div>
<div>+<span class="" style="white-space:pre"> </span>return PIXMAN_a8b8g8r8;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>case DSPF_RGB32:</div><div>+<span class="" style="white-space:pre"> </span>return PIXMAN_x8r8g8b8;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>return(pixman_format_code_t) 0;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+}</div><div>+</div><div>+static struct directfb_mode *</div><div>+directfb_output_add_mode( struct directfb_output *output, DFBScreenOutputResolution resolution, int width, int height, int refresh )</div><div>+{</div>
<div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_mode *mode;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>mode = (struct directfb_mode *) malloc(sizeof *mode);</div><div>+<span class="" style="white-space:pre"> </span>if (mode == NULL)</div><div>+<span class="" style="white-space:pre"> </span>return NULL;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>mode->base.flags = 0;</div><div>+<span class="" style="white-space:pre"> </span>mode->base.width = width;</div><div>+<span class="" style="white-space:pre"> </span>mode->base.height = height;</div>
<div>+<span class="" style="white-space:pre"> </span>mode->base.refresh = refresh;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>mode->resolution = resolution;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>wl_list_insert(output->base.mode_list.prev, &mode->base.link);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>return mode;</div><div>+}</div><div>+</div><div>+static void directfb_output_destroy(struct weston_output *base);</div><div>+</div><div>+static struct directfb_mode *</div>
<div>+choose_mode (struct directfb_output *output, struct weston_mode *target_mode)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_mode *tmp_mode = NULL, *mode;</div><div>+</div><div>
+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->base.current_mode->width == target_mode->width &&</div>
<div>+<span class="" style="white-space:pre"> </span> output->base.current_mode->height == target_mode->height &&</div><div>+<span class="" style="white-space:pre"> </span> (output->base.current_mode->refresh == target_mode->refresh ||</div>
<div>+<span class="" style="white-space:pre"> </span> target_mode->refresh == 0))</div><div>+<span class="" style="white-space:pre"> </span>return(struct directfb_mode *)output->base.current_mode;</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>wl_list_for_each(mode, &output->base.mode_list, base.link) {</div><div>+<span class="" style="white-space:pre"> </span>if (mode->base.width == target_mode->width &&</div>
<div>+<span class="" style="white-space:pre"> </span> mode->base.height == target_mode->height) {</div><div>+<span class="" style="white-space:pre"> </span>if (mode->base.refresh == target_mode->refresh || target_mode->refresh == 0) {</div>
<div>+<span class="" style="white-space:pre"> </span>return mode;</div><div>+<span class="" style="white-space:pre"> </span>} else if (!tmp_mode)</div><div>+<span class="" style="white-space:pre"> </span>tmp_mode = mode;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>return tmp_mode;</div><div>+}</div>
<div>+</div><div>+static void</div><div>+directfb_output_init_shadow(struct directfb_output *output)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_t transform;</div><div>+<span class="" style="white-space:pre"> </span>int shadow_width, shadow_height;</div>
<div>+<span class="" style="white-space:pre"> </span>int width, height;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>if (output->shadow_buf) {</div><div>+<span class="" style="white-space:pre"> </span>free( output->shadow_buf );</div><div>+<span class="" style="white-space:pre"> </span>output->shadow_buf = NULL;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->shadow_surface) {</div><div>+<span class="" style="white-space:pre"> </span>pixman_image_unref( output->shadow_surface );</div>
<div>+<span class="" style="white-space:pre"> </span>output->shadow_surface = NULL;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>width = output->mode.width;</div>
<div>+<span class="" style="white-space:pre"> </span>height = output->mode.height;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_init_identity(&transform);</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>switch (output->base.transform) {</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_NORMAL:</div>
<div>+<span class="" style="white-space:pre"> </span>shadow_width = width;</div><div>+<span class="" style="white-space:pre"> </span>shadow_height = height;</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform,</div>
<div>+<span class="" style="white-space:pre"> </span>NULL, 0, 0);</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform, NULL,</div><div>+<span class="" style="white-space:pre"> </span> 0, 0);</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_180:</div><div>+<span class="" style="white-space:pre"> </span>shadow_width = width;</div>
<div>+<span class="" style="white-space:pre"> </span>shadow_height = height;</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform,</div><div>+<span class="" style="white-space:pre"> </span>NULL, -pixman_fixed_1, 0);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(NULL, &transform,</div><div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed(shadow_width),</div><div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed(shadow_height));</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_270:</div><div>+<span class="" style="white-space:pre"> </span>shadow_width = height;</div>
<div>+<span class="" style="white-space:pre"> </span>shadow_height = width;</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform,</div><div>+<span class="" style="white-space:pre"> </span>NULL, 0, pixman_fixed_1);</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform,</div><div>+<span class="" style="white-space:pre"> </span> NULL,</div><div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed(shadow_width),</div>
<div>+<span class="" style="white-space:pre"> </span> 0);</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_OUTPUT_TRANSFORM_90:</div>
<div>+<span class="" style="white-space:pre"> </span>shadow_width = height;</div><div>+<span class="" style="white-space:pre"> </span>shadow_height = width;</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_rotate(&transform,</div>
<div>+<span class="" style="white-space:pre"> </span>NULL, 0, -pixman_fixed_1);</div><div>+<span class="" style="white-space:pre"> </span>pixman_transform_translate(&transform,</div><div>+<span class="" style="white-space:pre"> </span> NULL,</div>
<div>+<span class="" style="white-space:pre"> </span> 0,</div><div>+<span class="" style="white-space:pre"> </span> pixman_int_to_fixed(shadow_height));</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->shadow_buf = malloc( output->fb_info.buffer_length );</div><div>+<span class="" style="white-space:pre"> </span>if (!output->shadow_buf)</div>
<div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "malloc failed" );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->shadow_surface = pixman_image_create_bits( output->fb_info.pixel_format,</div>
<div>+<span class="" style="white-space:pre"> </span> shadow_width, shadow_height,</div><div>+<span class="" style="white-space:pre"> </span> (uint32_t*) output->shadow_buf,</div><div>+<span class="" style="white-space:pre"> </span> output->fb_info.line_length );</div>
<div>+<span class="" style="white-space:pre"> </span>if (!output->shadow_surface)</div><div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "pixman_image_create_bits failed" );</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->param.use_pixman) {</div><div>+<span class="" style="white-space:pre"> </span>if (output->base.renderer_state != NULL) {</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_renderer_output_destroy( &output->base );</div><div>+<span class="" style="white-space:pre"> </span>output->base.renderer_state = NULL;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (pixman_renderer_output_create( &output->base ) < 0)</div><div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "failed to init output pixman state with new mode" );</div>
<div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>if (output->base.renderer_state != NULL) {</div><div>+<span class="" style="white-space:pre"> </span>gl_renderer->output_destroy( &output->base );</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.renderer_state = NULL;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface sub;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>sub = output->surface.GetSubSurface( NULL );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (gl_renderer->output_create(&output->base, (EGLNativeWindowType)sub.iface) < 0)</div>
<div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "failed to init output egl state with new mode" );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+}</div><div>
+</div><div>+static int</div><div>+directfb_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *output;</div>
<div>+<span class="" style="white-space:pre"> </span>struct directfb_mode *directfb_mode;</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_compositor *ec;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output_base == NULL) {</div><div>+<span class="" style="white-space:pre"> </span>weston_log("output is NULL.\n");</div><div>+<span class="" style="white-space:pre"> </span>return -1;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (mode == NULL) {</div><div>+<span class="" style="white-space:pre"> </span>weston_log("mode is NULL.\n");</div>
<div>+<span class="" style="white-space:pre"> </span>return -1;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>(void) ec;</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>ec = (struct directfb_compositor *)output_base->compositor;</div><div>+<span class="" style="white-space:pre"> </span>output = (struct directfb_output *)output_base;</div>
<div>+<span class="" style="white-space:pre"> </span>directfb_mode = choose_mode (output, mode);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!directfb_mode) {</div><div>+<span class="" style="white-space:pre"> </span>weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);</div>
<div>+<span class="" style="white-space:pre"> </span>return -1;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (&directfb_mode->base == output->base.current_mode)</div>
<div>+<span class="" style="white-space:pre"> </span>return 0;</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenOutputConfig config;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>config.flags = DSOCONF_RESOLUTION;</div>
<div>+<span class="" style="white-space:pre"> </span>config.resolution = directfb_mode->resolution;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>ec->screen.SetOutputConfiguration( output->index, config );</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBDisplayLayerConfig lconf;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>lconf.flags = (DFBDisplayLayerConfigFlags)( DLCONF_WIDTH | DLCONF_HEIGHT );</div>
<div>+<span class="" style="white-space:pre"> </span>lconf.width = mode->width;</div><div>+<span class="" style="white-space:pre"> </span>lconf.height = mode->height;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->layer.SetConfiguration( lconf );</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->base.current_mode->flags = 0;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->base.current_mode = &directfb_mode->base;</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.current_mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->mode = *mode;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_init_shadow( output );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>return 0;</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+static int</div><div>+directfb_output_create( struct directfb_compositor *compositor,</div><div>+<span class="" style="white-space:pre"> </span>int index,</div><div>
+<span class="" style="white-space:pre"> </span>const DFBScreenDescription *sdesc,</div><div>+<span class="" style="white-space:pre"> </span>const DFBScreenMixerDescription *mdescs,</div><div>+<span class="" style="white-space:pre"> </span>const DFBScreenEncoderDescription *edescs,</div>
<div>+<span class="" style="white-space:pre"> </span>const DFBScreenOutputDescription *odescs )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *output;</div><div>+<span class="" style="white-space:pre"> </span>struct wl_event_loop *loop;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>IDirectFB dfb = compositor->dfb;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_log("Creating directfb output.\n");</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output = new directfb_output();</div>
<div>+<span class="" style="white-space:pre"> </span>if (!output)</div><div>+<span class="" style="white-space:pre"> </span>return -1;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>try {</div><div>
+<span class="" style="white-space:pre"> </span>int i = 0;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->param = compositor->param;</div><div>+<span class="" style="white-space:pre"> </span>output->compositor = compositor;</div>
<div>+<span class="" style="white-space:pre"> </span>output->index = index;</div><div>+<span class="" style="white-space:pre"> </span>output->odesc = odescs[index];</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor->screen.GetOutputConfiguration( index, &output->oconf );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>output->encoder = -1;</div><div>+<span class="" style="white-space:pre"> </span>output->mixer = -1;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->oconf.flags & DSOCONF_ENCODER) {</div>
<div>+<span class="" style="white-space:pre"> </span>output->encoder = output->oconf.encoder;</div><div>+<span class="" style="white-space:pre"> </span>output->edesc = edescs[output->encoder];</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor->screen.GetEncoderConfiguration( output->encoder, &output->econf );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->econf.flags & DSECONF_MIXER) {</div>
<div>+<span class="" style="white-space:pre"> </span>output->mixer = output->econf.mixer;</div><div>+<span class="" style="white-space:pre"> </span>output->mdesc = mdescs[output->mixer];</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>compositor->screen.GetMixerConfiguration( output->mixer, &output->mconf );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>for (i=0; i<32; i++) {</div>
<div>+<span class="" style="white-space:pre"> </span>if (output->mconf.layers & (1 << i)) {</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (i == 32)</div><div>+<span class="" style="white-space:pre"> </span>i = 0;</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>output->mconf.layers = (1 << i);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor->screen.SetMixerConfiguration( output->mixer, output->mconf );</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_INFO( "Weston/DirectFB: Output %d, Encoder %d, Mixer %d (layers 0x%04x)\n", index, output->encoder, output->mixer, output->mconf.layers );</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->layer = dfb.GetDisplayLayer( i );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->layer.GetConfiguration( &output->lconf );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (output->param.headless) {</div><div>+<span class="" style="white-space:pre"> </span>DFBSurfaceDescription desc;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>desc.flags = (DFBSurfaceDescriptionFlags)( DSDESC_WIDTH | DSDESC_HEIGHT );</div>
<div>+<span class="" style="white-space:pre"> </span>desc.width = output->lconf.width;</div><div>+<span class="" style="white-space:pre"> </span>desc.height = output->lconf.height;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->surface = compositor->dfb.CreateSurface( desc );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_INFO( "WestonDFB/Output: Headless surface ID %u\n", output->surface.GetID() );</div><div>+<span class="" style="white-space:pre"> </span>} else {</div>
<div>+<span class="" style="white-space:pre"> </span>output->layer.SetCooperativeLevel( DLSCL_EXCLUSIVE );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->layer.GetConfiguration( &output->lconf );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>output->lconf.pixelformat = DSPF_RGB32;</div><div>+<span class="" style="white-space:pre"> </span>output->lconf.buffermode = DLBM_TRIPLE;</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>try {</div><div>+<span class="" style="white-space:pre"> </span>output->layer.SetConfiguration( output->lconf );</div><div>+<span class="" style="white-space:pre"> </span>} catch (DFBException *e) {</div>
<div>+<span class="" style="white-space:pre"> </span>output->lconf.buffermode = DLBM_BACKVIDEO;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>try {</div><div>+<span class="" style="white-space:pre"> </span>output->layer.SetConfiguration( output->lconf );</div>
<div>+<span class="" style="white-space:pre"> </span>} catch (DFBException *e) {</div><div>+<span class="" style="white-space:pre"> </span>output->lconf.buffermode = DLBM_BACKSYSTEM;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>try {</div>
<div>+<span class="" style="white-space:pre"> </span>output->layer.SetConfiguration( output->lconf );</div><div>+<span class="" style="white-space:pre"> </span>} catch (DFBException *e) {</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->surface = output->layer.GetSurface();</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Store the pertinent data. */</div><div>+<span class="" style="white-space:pre"> </span>output->surface.GetSize( &output->fb_info.x_resolution, &output->fb_info.y_resolution );</div>
<div>+<span class="" style="white-space:pre"> </span>output->fb_info.format = output->surface.GetPixelFormat();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->fb_info.width_mm = output->fb_info.x_resolution;</div>
<div>+<span class="" style="white-space:pre"> </span>output->fb_info.height_mm = output->fb_info.y_resolution;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->fb_info.line_length = DFB_BYTES_PER_LINE( output->fb_info.format, output->fb_info.x_resolution );</div>
<div>+<span class="" style="white-space:pre"> </span>output->fb_info.buffer_length = DFB_PLANE_MULTIPLY( output->fb_info.format, output->fb_info.y_resolution )</div><div>+<span class="" style="white-space:pre"> </span>* output->fb_info.line_length;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>output->fb_info.pixel_format = calculate_pixman_format( output->fb_info.format );</div><div>+<span class="" style="white-space:pre"> </span>output->fb_info.refresh_rate = 60;</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->base.start_repaint_loop = directfb_output_start_repaint_loop;</div><div>+<span class="" style="white-space:pre"> </span>if (!output->param.use_pixman)</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.repaint = directfb_output_repaint_gl;</div><div>+<span class="" style="white-space:pre"> </span>else</div><div>+<span class="" style="white-space:pre"> </span>output->base.repaint = directfb_output_repaint_pixman;</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.destroy = directfb_output_destroy;</div><div>+<span class="" style="white-space:pre"> </span>output->base.set_backlight = NULL;</div><div>+<span class="" style="white-space:pre"> </span>output->base.set_dpms = NULL;</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.switch_mode = directfb_output_switch_mode;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* only one static mode in list */</div>
<div>+<span class="" style="white-space:pre"> </span>output->mode.flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;</div><div>+<span class="" style="white-space:pre"> </span>output->mode.width = output->fb_info.x_resolution;</div>
<div>+<span class="" style="white-space:pre"> </span>output->mode.height = output->fb_info.y_resolution;</div><div>+<span class="" style="white-space:pre"> </span>output->mode.refresh = output->fb_info.refresh_rate;</div>
<div>+<span class="" style="white-space:pre"> </span>wl_list_init(&output->base.mode_list);</div><div>+<span class="" style="white-space:pre"> </span>wl_list_insert(&output->base.mode_list, &output->mode.link);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_add_mode( output, DSOR_1920_1080, 1920, 1080, 60 );</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_add_mode( output, DSOR_1280_1024, 1280, 1024, 60 );</div>
<div>+<span class="" style="white-space:pre"> </span>directfb_output_add_mode( output, DSOR_1024_768, 1024, 768, 60 );</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_add_mode( output, DSOR_800_600, 800, 600, 60 );</div>
<div>+<span class="" style="white-space:pre"> </span>directfb_output_add_mode( output, DSOR_640_480, 640, 480, 60 );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->base.current_mode = &output->mode;</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.original_mode = &output->mode;</div><div>+<span class="" style="white-space:pre"> </span>output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;</div>
<div>+<span class="" style="white-space:pre"> </span>output->base.make = strdup( "unknown" );</div><div>+<span class="" style="white-space:pre"> </span>output->base.model = strdup( output-><a href="http://odesc.name">odesc.name</a> );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_output_init(&output->base, &compositor->base,</div><div>+<span class="" style="white-space:pre"> </span> 0, 0, output->fb_info.width_mm,</div>
<div>+<span class="" style="white-space:pre"> </span> output->fb_info.height_mm,</div><div>+<span class="" style="white-space:pre"> </span> WL_OUTPUT_TRANSFORM_NORMAL,</div><div>+<span class="" style="white-space:pre"> </span> 1);</div>
<div>+<span class="" style="white-space:pre"> </span>output->base_init = true;</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_output_init_shadow( output );</div><div>+</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>loop = wl_display_get_event_loop(compositor->base.wl_display);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>wl_list_insert( compositor->base.output_list.prev, &output->base.link );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_log( "directfb output %d×%d px\n", output->mode.width, output->mode.height );</div>
<div>+<span class="" style="white-space:pre"> </span>weston_log_continue( STAMP_SPACE "guessing %d Hz and 96 dpi\n", output->mode.refresh / 1000 );</div><div>+<span class="" style="white-space:pre"> </span>} catch (...) {</div>
<div>+<span class="" style="white-space:pre"> </span>delete output;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>throw;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>return 0;</div><div>+}</div><div>+</div><div>+static void</div><div>+directfb_output_destroy(struct weston_output *base)</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_output *output = to_directfb_output(base);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_log("Destroying directfb output.\n");</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_output_destroy(&output->base);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>free(output);</div><div>+}</div><div>+</div>
<div>+/**********************************************************************************************************************/</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+directfb_output::directfb_output()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Output, "directfb_output::%s( %p )\n", __FUNCTION__, this );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>memset( this, 0, sizeof(*this) );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb_updates_init( &flip_updates, flip_regions, D_ARRAY_SIZE(flip_regions) );</div>
<div>+}</div><div>+</div><div>+directfb_output::~directfb_output()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Output, "directfb_output::%s( %p )\n", __FUNCTION__, this );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (base.renderer_state != NULL) {</div><div>+<span class="" style="white-space:pre"> </span>if (param.use_pixman)</div><div>+<span class="" style="white-space:pre"> </span>pixman_renderer_output_destroy(&base);</div>
<div>+<span class="" style="white-space:pre"> </span>else</div><div>+<span class="" style="white-space:pre"> </span>gl_renderer->output_destroy(&base);</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (shadow_surface != NULL) {</div><div>+<span class="" style="white-space:pre"> </span>pixman_image_unref(shadow_surface);</div><div>+<span class="" style="white-space:pre"> </span>shadow_surface = NULL;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (shadow_buf != NULL) {</div><div>+<span class="" style="white-space:pre"> </span>free(shadow_buf);</div>
<div>+<span class="" style="white-space:pre"> </span>shadow_buf = NULL;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb_updates_deinit( &flip_updates );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (base_init) {</div><div>+<span class="" style="white-space:pre"> </span>/* Remove the output. */</div><div>+<span class="" style="white-space:pre"> </span>wl_list_remove(&base.link);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_output_destroy( &base );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+/**********************************************************************************************************************/</div><div>+</div><div>+static int</div><div>+directfb_create_surface( struct weston_surface *surface )</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>int ret;</div><div>+<span class="" style="white-space:pre"> </span>weston_compositor *ec = surface->compositor;</div><div>+<span class="" style="white-space:pre"> </span>directfb_compositor *compositor = to_directfb_compositor( ec );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s( compositor %p, surface %p )\n", __FUNCTION__, compositor, surface );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>ret = compositor->create_surface( surface );</div>
<div>+<span class="" style="white-space:pre"> </span>if (ret)</div><div>+<span class="" style="white-space:pre"> </span>return ret;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_surface_state *state = new directfb_surface_state();</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>surface->compositor_state = state;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>return 0;</div><div>+}</div><div>+</div><div>+static void</div>
<div>+directfb_destroy_surface( struct weston_surface *surface )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>weston_compositor *ec = surface->compositor;</div><div>+<span class="" style="white-space:pre"> </span>directfb_compositor *compositor = to_directfb_compositor( ec );</div>
<div>+<span class="" style="white-space:pre"> </span>directfb_surface_state *state = (directfb_surface_state*) surface->compositor_state;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s( surface %p )\n", __FUNCTION__, surface );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>delete state;</div><div>+<span class="" style="white-space:pre"> </span>surface->compositor_state = NULL;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor->destroy_surface( surface );</div>
<div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div><div>+</div><div>+struct pixman_surface_state {</div><div>+<span class="" style="white-space:pre"> </span>pixman_image_t *image;</div>
<div>+<span class="" style="white-space:pre"> </span>struct weston_buffer_reference buffer_ref;</div><div>+};</div><div>+</div><div>+static void</div><div>+directfb_surface_attach( struct weston_surface *es, struct weston_buffer *buffer )</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>weston_compositor *ec = es->compositor;</div><div>+<span class="" style="white-space:pre"> </span>directfb_compositor *compositor = to_directfb_compositor( ec );</div>
<div>+<span class="" style="white-space:pre"> </span>directfb_surface_state *state = (directfb_surface_state*) es->compositor_state;</div><div>+<span class="" style="white-space:pre"> </span>struct wl_shm_buffer *shm_buffer;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s( surface %p, buffer %p )\n", __FUNCTION__, es, buffer );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!buffer) {</div>
<div>+<span class="" style="white-space:pre"> </span>compositor->attach( es, buffer );</div><div>+<span class="" style="white-space:pre"> </span>return;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>shm_buffer = wl_shm_buffer_get( buffer->resource );</div><div>+<span class="" style="white-space:pre"> </span>if (shm_buffer) {</div><div>+<span class="" style="white-space:pre"> </span>compositor->attach( es, buffer );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!state->window) {</div><div>+<span class="" style="white-space:pre"> </span>DFBWindowDescription desc;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>desc.flags = (DFBWindowDescriptionFlags)( DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_RESOURCE_ID );</div>
<div>+<span class="" style="white-space:pre"> </span>desc.width = buffer->width;</div><div>+<span class="" style="white-space:pre"> </span>desc.height = buffer->height;</div><div>+<span class="" style="white-space:pre"> </span>desc.resource_id = wl_resource_get_id( buffer->resource );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>switch (wl_shm_buffer_get_format(shm_buffer)) {</div><div>+<span class="" style="white-space:pre"> </span>case WL_SHM_FORMAT_XRGB8888:</div><div>+<span class="" style="white-space:pre"> </span>desc.pixelformat = DSPF_RGB32;</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>case WL_SHM_FORMAT_ARGB8888:</div><div>+<span class="" style="white-space:pre"> </span>desc.pixelformat = DSPF_ARGB;</div>
<div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>weston_log("Unsupported SHM buffer format\n");</div>
<div>+<span class="" style="white-space:pre"> </span>return;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>state->window = compositor->layer.CreateWindow( desc );</div>
<div>+<span class="" style="white-space:pre"> </span>state->surface = state->window.GetSurface();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>state->size.w = buffer->width;</div><div>
+<span class="" style="white-space:pre"> </span>state->size.h = buffer->height;</div><div>+<span class="" style="white-space:pre"> </span>state->format = desc.pixelformat;</div><div>+<span class="" style="white-space:pre"> </span>} else if (state->size.w != buffer->width || state->size.h != buffer->height)</div>
<div>+<span class="" style="white-space:pre"> </span>state->window.Resize( buffer->width, buffer->height );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>state->surface.Write( wl_shm_buffer_get_data(shm_buffer),</div>
<div>+<span class="" style="white-space:pre"> </span> wl_shm_buffer_get_stride(shm_buffer) );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>state->surface.Flip();</div><div>+<span class="" style="white-space:pre"> </span>} else {</div>
<div>+<span class="" style="white-space:pre"> </span>WL::Buffer *dfb_buffer = (WL::Buffer *) wl_resource_get_user_data( buffer->resource );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>state->unlock();</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>buffer->width = dfb_buffer->size.w;</div><div>+<span class="" style="white-space:pre"> </span>buffer->height = dfb_buffer->size.h;</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>state->surface = dfb_buffer->surface;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>state->size = dfb_buffer->size;</div>
<div>+<span class="" style="white-space:pre"> </span>state->format = dfb_buffer->format;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (compositor->param.use_pixman) {</div><div>+<span class="" style="white-space:pre"> </span>struct pixman_surface_state *ps = (struct pixman_surface_state *) es->renderer_state;</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_format_code_t pixman_format;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>weston_buffer_reference(&ps->buffer_ref, buffer);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (ps->image) {</div><div>+<span class="" style="white-space:pre"> </span>pixman_image_unref(ps->image);</div><div>+<span class="" style="white-space:pre"> </span>ps->image = NULL;</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_format = calculate_pixman_format( dfb_buffer->format );</div><div>+<span class="" style="white-space:pre"> </span>if (!pixman_format) {</div>
<div>+<span class="" style="white-space:pre"> </span>D_ERROR( "WestonDFB/Surface: Unsupported DirectFB pixel format 0x%08x (%s)\n",</div><div>+<span class="" style="white-space:pre"> </span> dfb_buffer->format, dfb_pixelformat_name(dfb_buffer->format) );</div>
<div>+<span class="" style="white-space:pre"> </span>weston_buffer_reference( &ps->buffer_ref, NULL );</div><div>+<span class="" style="white-space:pre"> </span>return;</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>state->lock();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>ps->image = pixman_image_create_bits( pixman_format,</div><div>
+<span class="" style="white-space:pre"> </span> buffer->width, buffer->height,</div><div>+<span class="" style="white-space:pre"> </span> (u32*) state->data, state->pitch );</div><div>+<span class="" style="white-space:pre"> </span>} else</div>
<div>+<span class="" style="white-space:pre"> </span>compositor->attach( es, buffer );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, " -> size %dx%d\n", buffer->width, buffer->height );</div>
<div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, " -> busy count %u\n", buffer->busy_count );</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+/**********************************************************************************************************************/</div><div>+</div><div>+directfb_compositor::directfb_compositor( struct wl_display *display, int *argc, char *argv[],</div>
<div>+<span class="" style="white-space:pre"> </span> struct weston_config *config,</div><div>+<span class="" style="white-space:pre"> </span> const directfb_parameters ¶m )</div><div>+<span class="" style="white-space:pre"> </span>:</div>
<div>+<span class="" style="white-space:pre"> </span>param( param ),</div><div>+<span class="" style="white-space:pre"> </span>input_manager( *this )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p )\n", __FUNCTION__, this );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (weston_compositor_init(&this->base, display, argc, argv, config) < 0)</div><div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "weston_compositor_init failed" );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenDescription sdesc;</div><div>+<span class="" style="white-space:pre"> </span>int i;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>IDirectFB dfb;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>DirectFB::Init( argc, &argv );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>dfb = DirectFB::Create();</div><div>+</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>this->dfb = dfb;</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>this->events = dfb.CreateInputEventBuffer( DICAPS_ALL, DFB_TRUE );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>this->event_fd = this->events.CreateFileDescriptor();</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>this->screen = dfb.GetScreen( DSCID_PRIMARY );</div>
<div>+<span class="" style="white-space:pre"> </span>this->layer = dfb.GetDisplayLayer( DLID_PRIMARY );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>sdesc = this->screen.GetDescription();</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_INFO( "Weston/DirectFB: %d mixers, %d encoders, %d outputs\n", sdesc.mixers, sdesc.encoders, sdesc.outputs );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenMixerDescription mdescs[sdesc.mixers];</div>
<div>+<span class="" style="white-space:pre"> </span>DFBScreenEncoderDescription edescs[sdesc.encoders];</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenOutputDescription odescs[sdesc.outputs];</div><div>
+</div><div>+<span class="" style="white-space:pre"> </span>if (sdesc.mixers)</div><div>+<span class="" style="white-space:pre"> </span>this->screen.GetMixerDescriptions( mdescs );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (sdesc.encoders)</div>
<div>+<span class="" style="white-space:pre"> </span>this->screen.GetEncoderDescriptions( edescs );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (sdesc.outputs)</div><div>+<span class="" style="white-space:pre"> </span>this->screen.GetOutputDescriptions( odescs );</div>
<div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!param.use_pixman) {</div><div>+<span class="" style="white-space:pre"> </span>if (gl_renderer->create(&this->base, (EGLNativeDisplayType)0, gl_renderer->opaque_attribs, NULL) < 0)</div>
<div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "gl_renderer_create failed" );</div><div>+<span class="" style="white-space:pre"> </span>} else {</div><div>+<span class="" style="white-space:pre"> </span>if (pixman_renderer_init(&this->base) < 0)</div>
<div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "pixman_renderer_init failed" );</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>for (i=0; i<sdesc.outputs && (param.outputs == 0 || param.outputs > i); i++) {</div>
<div>+<span class="" style="white-space:pre"> </span>if (directfb_output_create( this, i, &sdesc, mdescs, edescs, odescs ) < 0)</div><div>+<span class="" style="white-space:pre"> </span>throw std::runtime_error( "directfb_output_create failed" );</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>this->create_surface = this->base.renderer->create_surface;</div><div>+<span class="" style="white-space:pre"> </span>this->destroy_surface = this->base.renderer->destroy_surface;</div>
<div>+<span class="" style="white-space:pre"> </span>this->attach = this->base.renderer->attach;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>this->base.renderer->create_surface = directfb_create_surface;</div>
<div>+<span class="" style="white-space:pre"> </span>this->base.renderer->destroy_surface = directfb_destroy_surface;</div><div>+<span class="" style="white-space:pre"> </span>this->base.renderer->attach = directfb_surface_attach;</div>
<div>+<span class="" style="white-space:pre"> </span>this->base.renderer->create_view = NULL;</div><div>+<span class="" style="white-space:pre"> </span>this->base.renderer->destroy_view = NULL;</div><div>
+</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>this->base.destroy = directfb_compositor::destroy;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>this->wldfb = WL::wayland_dfb_init( display, dfb.iface, client_callback, this, events.iface );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>this->event_source = wl_event_loop_add_fd( this->base.input_loop,</div><div>+<span class="" style="white-space:pre"> </span> this->event_fd,</div>
<div>+<span class="" style="white-space:pre"> </span> WL_EVENT_READABLE,</div><div>+<span class="" style="white-space:pre"> </span> directfb_compositor::handle_event, this );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>wl_event_loop_add_idle( this->base.input_loop, directfb_compositor::idle_init, this );</div>
<div>+}</div><div>+</div><div>+directfb_compositor::~directfb_compositor()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p )\n", __FUNCTION__, this );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>WL::wayland_dfb_uninit( this->wldfb );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>shutdown();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Destroy the output. */</div>
<div>+<span class="" style="white-space:pre"> </span>weston_compositor_shutdown( &base );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Chain up. */</div><div>+<span class="" style="white-space:pre"> </span>base.renderer->destroy( &base );</div>
<div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::HandleInputEvent( const DFBInputEvent *event )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p, event %p ) <- type 0x%04x\n", __FUNCTION__, this, event, event->type );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>input_manager.HandleInputEvent( *event );</div><div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::HandleWindowEvent( const DFBWindowEvent *event )</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p, event %p ) <- type 0x%04x\n", __FUNCTION__, this, event, event->type );</div>
<div>+</div><div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::HandleSurfaceEvent( const DFBSurfaceEvent *event )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p, event %p ) <- type 0x%04x\n", __FUNCTION__, this, event, event->type );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>WL::wayland_dfb_handle_surface_event( wldfb, event );</div><div>+}</div><div>+</div><div>+int</div><div>+directfb_compositor::handle_event( int fd, uint32_t mask, void *data )</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_compositor *compositor = (struct directfb_compositor *) data;</div><div>+<span class="" style="white-space:pre"> </span>DFBEvent events[200];</div>
<div>+<span class="" style="white-space:pre"> </span>ssize_t ret;</div><div>+<span class="" style="white-space:pre"> </span>int count = 0;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p, fd %d, mask 0x%08x )\n", __FUNCTION__, compositor, fd, mask );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, " -> reading...\n" );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if ((ret = read( fd, events, sizeof(events) )) >= sizeof(events[0])) {</div>
<div>+<span class="" style="white-space:pre"> </span>size_t num = ret / sizeof(events[0]);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, " -> got %zd (%zu events)\n", ret, num );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>count += num;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>for (size_t i=0; i<num; i++) {</div><div>+<span class="" style="white-space:pre"> </span>switch (events[i].clazz) {</div>
<div>+<span class="" style="white-space:pre"> </span>case DFEC_INPUT:</div><div>+<span class="" style="white-space:pre"> </span>compositor->HandleInputEvent( &events[i].input );</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>case DFEC_WINDOW:</div><div>+<span class="" style="white-space:pre"> </span>compositor->HandleWindowEvent( &events[i].window );</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>case DFEC_SURFACE:</div><div>+<span class="" style="white-space:pre"> </span>compositor->HandleSurfaceEvent( &events[i].surface );</div><div>+<span class="" style="white-space:pre"> </span>break;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>default:</div><div>+<span class="" style="white-space:pre"> </span>break;</div><div>+<span class="" style="white-space:pre"> </span>}</div><div>+<span class="" style="white-space:pre"> </span>}</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (ret < 0)</div><div>+<span class="" style="white-space:pre"> </span>D_PERROR( "WestonDFB/Compositor: Reading from event file descriptor failed!\n" );</div>
<div>+<span class="" style="white-space:pre"> </span>else if (count == 0)</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, " -> GOT NO EVENT!\n" );</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>return count;</div><div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::idle_init( void *data )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_compositor *compositor = (struct directfb_compositor *) data;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "directfb_compositor::%s( %p )\n", __FUNCTION__, compositor );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor->init();</div>
<div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::client_callback( void *context,</div><div>+<span class="" style="white-space:pre"> </span> struct wl_client *client )</div><div>+{</div>
<div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::init()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>input_manager.init();</div><div>+</div><div>+}</div><div>+</div><div>+void</div>
<div>+directfb_compositor::shutdown()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>input_manager.shutdown();</div><div>+}</div><div>+</div><div>+void</div><div>+directfb_compositor::destroy(struct weston_compositor *base)</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_compositor *compositor = to_directfb_compositor(base);</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor->shutdown();</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>delete compositor;</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+/**********************************************************************************************************************/</div><div>+</div><div>+directfb_surface_state::directfb_surface_state()</div><div>+<span class="" style="white-space:pre"> </span>:</div>
<div>+<span class="" style="white-space:pre"> </span>data( NULL ),</div><div>+<span class="" style="white-space:pre"> </span>pitch( 0 )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+}</div><div>+</div><div>+directfb_surface_state::~directfb_surface_state()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (data)</div><div>+<span class="" style="white-space:pre"> </span>surface.Unlock();</div><div>+}</div><div>+</div><div>+void</div><div>+directfb_surface_state::lock()</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>if (!data)</div>
<div>+<span class="" style="white-space:pre"> </span>surface.Lock( DSLF_READ, &data, &pitch );</div><div>+}</div><div>+</div><div>+void</div><div>+directfb_surface_state::unlock()</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>if (data) {</div><div>+<span class="" style="white-space:pre"> </span>data = NULL;</div><div>+<span class="" style="white-space:pre"> </span>surface.Unlock();</div>
<div>+<span class="" style="white-space:pre"> </span>}</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div><div>
+/**********************************************************************************************************************/</div><div>+</div><div>+struct weston_compositor *</div><div>+directfb_compositor::create( struct wl_display *display, int *argc, char *argv[],</div>
<div>+<span class="" style="white-space:pre"> </span> struct weston_config *config,</div><div>+<span class="" style="white-space:pre"> </span> struct directfb_parameters *param )</div><div>+{</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_compositor *compositor;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>D_INFO( "WestonDFB/Compositor: Initialising...\n" );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>gl_renderer = (struct gl_renderer_interface*) weston_load_module("gl-renderer.so",</div><div>+<span class="" style="white-space:pre"> </span> "gl_renderer_interface");</div>
<div>+<span class="" style="white-space:pre"> </span>if (!gl_renderer)</div><div>+<span class="" style="white-space:pre"> </span>return NULL;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>compositor = new directfb_compositor( display, argc, argv, config, *param );</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>return &compositor->base;</div><div>+}</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+WL_EXPORT struct weston_compositor *</div><div>+backend_init(struct wl_display *display, int *argc, char *argv[],</div><div>+<span class="" style="white-space:pre"> </span> struct weston_config *config)</div>
<div>+{</div><div>+<span class="" style="white-space:pre"> </span>D_DEBUG_AT( WestonDFB_Compositor, "%s()\n", __FUNCTION__ );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* TODO: Ideally, available frame buffers should be enumerated using</div>
<div>+<span class="" style="white-space:pre"> </span> * udev, rather than passing a device node in as a parameter. */</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_parameters param;</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>memset( ¶m, 0, sizeof(param) );</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>const struct weston_option directfb_options[] = {</div><div>
+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_INTEGER, "width", 0, ¶m.width},</div><div>+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_INTEGER, "height", 0, ¶m.height},</div>
<div>+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_INTEGER, "outputs", 0, ¶m.outputs},</div><div>+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_BOOLEAN, "no-input", 0, ¶m.no_input},</div>
<div>+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_BOOLEAN, "use-2d", 0, ¶m.use_2d},</div><div>+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, ¶m.use_pixman},</div>
<div>+<span class="" style="white-space:pre"> </span>{ WESTON_OPTION_BOOLEAN, "headless", 0, ¶m.headless},</div><div>+<span class="" style="white-space:pre"> </span>};</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>parse_options(directfb_options, ARRAY_LENGTH(directfb_options), argc, argv);</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>return directfb_compositor::create(display, argc, argv, config, ¶m);</div><div>+}</div><div>+</div><div>diff --git a/src/compositor-directfb.h b/src/compositor-directfb.h</div>
<div>new file mode 100644</div><div>index 0000000..fb53d48</div><div>--- /dev/null</div><div>+++ b/src/compositor-directfb.h</div><div>@@ -0,0 +1,225 @@</div><div>+/*</div><div>+ * Copyright © 2008-2011 Kristian Høgsberg</div>
<div>+ * Copyright © 2011 Intel Corporation</div><div>+ * Copyright © 2012 Raspberry Pi Foundation</div><div>+ * Copyright © 2013 Philip Withnall</div><div>+ *</div><div>+ * Permission to use, copy, modify, distribute, and sell this software and</div>
<div>+ * its documentation for any purpose is hereby granted without fee, provided</div><div>+ * that the above copyright notice appear in all copies and that both that</div><div>+ * copyright notice and this permission notice appear in supporting</div>
<div>+ * documentation, and that the name of the copyright holders not be used in</div><div>+ * advertising or publicity pertaining to distribution of the software</div><div>+ * without specific, written prior permission. The copyright holders make</div>
<div>+ * no representations about the suitability of this software for any</div><div>+ * purpose. It is provided "as is" without express or implied warranty.</div><div>+ *</div><div>+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS</div>
<div>+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND</div><div>+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY</div><div>+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER</div>
<div>+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF</div><div>+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN</div><div>+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</div>
<div>+ */</div><div>+</div><div>+#ifndef __COMPOSITOR_DIRECTFB_H__</div><div>+#define __COMPOSITOR_DIRECTFB_H__</div><div>+</div><div>+#include <++dfb.h></div><div>+</div><div>+#include <++dfb_mangle.h></div><div>
+#include <wayland-dfb.h></div><div>+#include <++dfb_unmangle.h></div><div>+</div><div>+#include <stdexcept></div><div>+</div><div>+extern "C" {</div><div>+#include <errno.h></div><div>+#include <stdlib.h></div>
<div>+#include <stdio.h></div><div>+#include <string.h></div><div>+#include <math.h></div><div>+#include <sys/mman.h></div><div>+#include <sys/types.h></div><div>+#include <fcntl.h></div>
<div>+#include <unistd.h></div><div>+#include <linux/fb.h></div><div>+#include <linux/input.h></div><div>+</div><div>+#include "compositor.h"</div><div>+#include "launcher-util.h"</div>
<div>+#include "gl-renderer.h"</div><div>+#include "pixman-renderer.h"</div><div>+}</div><div>+</div><div>+#include "compositor-directfb-input.h"</div><div>+//#include "compositor-directfb-windows.h"</div>
<div>+</div><div>+</div><div>+struct directfb_parameters {</div><div>+<span class="" style="white-space:pre"> </span>int width;</div><div>+<span class="" style="white-space:pre"> </span>int height;</div><div>+<span class="" style="white-space:pre"> </span>int fullscreen;</div>
<div>+<span class="" style="white-space:pre"> </span>int outputs;</div><div>+<span class="" style="white-space:pre"> </span>int no_input;</div><div>+<span class="" style="white-space:pre"> </span>int use_2d;</div><div>+<span class="" style="white-space:pre"> </span>int use_pixman;</div>
<div>+<span class="" style="white-space:pre"> </span>int headless;</div><div>+};</div><div>+</div><div>+struct directfb_compositor {</div><div>+// friend class WindowAdapter;</div><div>+</div><div>+public:</div><div>+<span class="" style="white-space:pre"> </span>static struct weston_compositor *create( struct wl_display *display, int *argc, char *argv[],</div>
<div>+<span class="" style="white-space:pre"> </span> struct weston_config *config,</div><div>+<span class="" style="white-space:pre"> </span> struct directfb_parameters *param );</div><div>+</div><div>+</div><div>
+<span class="" style="white-space:pre"> </span>directfb_compositor( struct wl_display *display, int *argc, char *argv[],</div><div>+<span class="" style="white-space:pre"> </span> struct weston_config *config,</div>
<div>+<span class="" style="white-space:pre"> </span> const directfb_parameters ¶m );</div><div>+<span class="" style="white-space:pre"> </span>~directfb_compositor();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>struct weston_compositor base;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_parameters param;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>InputDeviceManager input_manager;</div><div>
+// WindowAdapter window_adapter;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>IDirectFB dfb;</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBEventBuffer events;</div>
<div>+<span class="" style="white-space:pre"> </span>IDirectFBScreen screen;</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBDisplayLayer layer;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>int event_fd;</div>
<div>+<span class="" style="white-space:pre"> </span>struct wl_event_source *event_source;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>WL::wl_dfb *wldfb;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Backup original function pointers */</div>
<div>+<span class="" style="white-space:pre"> </span>int (*create_surface)(struct weston_surface *surface);</div><div>+<span class="" style="white-space:pre"> </span>void (*destroy_surface)(struct weston_surface *surface);</div>
<div>+<span class="" style="white-space:pre"> </span>void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);</div><div>+</div><div>+public:</div><div>+<span class="" style="white-space:pre"> </span>void HandleInputEvent ( const DFBInputEvent *event );</div>
<div>+<span class="" style="white-space:pre"> </span>void HandleWindowEvent ( const DFBWindowEvent *event );</div><div>+<span class="" style="white-space:pre"> </span>void HandleSurfaceEvent( const DFBSurfaceEvent *event );</div>
<div>+</div><div>+private:</div><div>+<span class="" style="white-space:pre"> </span>void init();</div><div>+<span class="" style="white-space:pre"> </span>void shutdown();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>static void destroy( struct weston_compositor *base );</div>
<div>+<span class="" style="white-space:pre"> </span>static int handle_event( int fd, uint32_t mask, void *data );</div><div>+<span class="" style="white-space:pre"> </span>static void idle_init( void *data );</div><div>+</div>
<div>+<span class="" style="white-space:pre"> </span>static void client_callback( void *context,</div><div>+<span class="" style="white-space:pre"> </span> struct wl_client *client );</div><div>+};</div>
<div>+</div><div>+struct directfb_mode {</div><div>+<span class="" style="white-space:pre"> </span>struct weston_mode base;</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenOutputResolution resolution;</div>
<div>+};</div><div>+</div><div>+struct directfb_screeninfo {</div><div>+<span class="" style="white-space:pre"> </span>int x_resolution; /* pixels, visible area */</div><div>+<span class="" style="white-space:pre"> </span>int y_resolution; /* pixels, visible area */</div>
<div>+<span class="" style="white-space:pre"> </span>unsigned int width_mm; /* visible screen width in mm */</div><div>+<span class="" style="white-space:pre"> </span>unsigned int height_mm;<span class="" style="white-space:pre"> </span>/* visible screen height in mm */</div>
<div>+<span class="" style="white-space:pre"> </span>DFBSurfacePixelFormat format;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>size_t buffer_length; /* length of frame buffer memory in bytes */</div>
<div>+<span class="" style="white-space:pre"> </span>size_t line_length; /* length of a line in bytes */</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_format_code_t pixel_format; /* frame buffer pixel format */</div>
<div>+<span class="" style="white-space:pre"> </span>unsigned int refresh_rate; /* Hertz */</div><div>+};</div><div>+</div><div>+#define BUFFER_DAMAGE_COUNT 3</div><div>+</div><div>+struct directfb_output {</div><div>+public:</div>
<div>+<span class="" style="white-space:pre"> </span>directfb_output();</div><div>+<span class="" style="white-space:pre"> </span>~directfb_output();</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_compositor *compositor;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>struct weston_output base;</div><div>+<span class="" style="white-space:pre"> </span>bool base_init;</div><div>+</div><div>
+<span class="" style="white-space:pre"> </span>struct directfb_parameters param;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>int index;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface surface;</div>
<div>+<span class="" style="white-space:pre"> </span>IDirectFBDisplayLayer layer;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBDisplayLayerConfig lconf;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>int mixer;</div>
<div>+<span class="" style="white-space:pre"> </span>int encoder;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenMixerDescription mdesc;</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenEncoderDescription edesc;</div>
<div>+<span class="" style="white-space:pre"> </span>DFBScreenOutputDescription odesc;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenMixerConfig mconf;</div><div>+<span class="" style="white-space:pre"> </span>DFBScreenEncoderConfig econf;</div>
<div>+<span class="" style="white-space:pre"> </span>DFBScreenOutputConfig oconf;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>struct weston_mode mode;</div><div>+<span class="" style="white-space:pre"> </span>struct wl_event_source *finish_frame_timer;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>/* Frame buffer details. */</div><div>+<span class="" style="white-space:pre"> </span>struct directfb_screeninfo fb_info;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>/* pixman details. */</div>
<div>+<span class="" style="white-space:pre"> </span>pixman_image_t *shadow_surface;</div><div>+<span class="" style="white-space:pre"> </span>void *shadow_buf;</div><div>+<span class="" style="white-space:pre"> </span>uint8_t depth;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>pixman_region32_t buffer_damage[BUFFER_DAMAGE_COUNT];</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBRegion flip_regions[8];</div>
<div>+<span class="" style="white-space:pre"> </span>DFBUpdates flip_updates;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>bool initial;</div><div>+};</div>
<div>+</div><div>+struct directfb_surface_state {</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBWindow window;</div><div>+<span class="" style="white-space:pre"> </span>IDirectFBSurface surface;</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>DFBDimension size;</div><div>+<span class="" style="white-space:pre"> </span>DFBSurfacePixelFormat format;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>void *data;</div>
<div>+<span class="" style="white-space:pre"> </span>int pitch;</div><div>+</div><div>+<span class="" style="white-space:pre"> </span>directfb_surface_state();</div><div>+<span class="" style="white-space:pre"> </span>~directfb_surface_state();</div>
<div>+</div><div>+<span class="" style="white-space:pre"> </span>void lock();</div><div>+<span class="" style="white-space:pre"> </span>void unlock();</div><div>+};</div><div>+</div><div>+/**********************************************************************************************************************/</div>
<div>+</div><div>+static inline struct directfb_output *</div><div>+to_directfb_output(struct weston_output *base) {</div><div>+<span class="" style="white-space:pre"> </span>return container_of(base, struct directfb_output, base);</div>
<div>+}</div><div>+</div><div>+static inline struct directfb_compositor *</div><div>+to_directfb_compositor(struct weston_compositor *base) {</div><div>+<span class="" style="white-space:pre"> </span>return container_of(base, struct directfb_compositor, base);</div>
<div>+}</div><div>+</div><div>+</div><div>+#endif</div><div>+</div><div>diff --git a/src/compositor.c b/src/compositor.c</div><div>index 632bbe7..10a2ce0 100644</div><div>--- a/src/compositor.c</div><div>+++ b/src/compositor.c</div>
<div>@@ -3603,6 +3603,19 @@ usage(int error_code)</div><div> <span class="" style="white-space:pre"> </span>" --log==FILE\t\tLog to the given file\n"</div><div> <span class="" style="white-space:pre"> </span>" -h, --help\t\tThis help message\n\n");</div>
<div> </div><div>+#if defined(BUILD_DIRECTFB_COMPOSITOR)</div><div>+<span class="" style="white-space:pre"> </span>fprintf(stderr,</div><div>+<span class="" style="white-space:pre"> </span>"Options for directfb-backend.so:\n\n"</div>
<div>+<span class="" style="white-space:pre"> </span>" --width=WIDTH\t\tWidth of output window/layer\n"</div><div>+<span class="" style="white-space:pre"> </span>" --height=HEIGHT\tHeight of output window/layer\n"</div>
<div>+<span class="" style="white-space:pre"> </span>" --fullscreen\t\tRun in fullscreen mode\n"</div><div>+<span class="" style="white-space:pre"> </span>" --outputs=COUNT\tCreate not more than COUNT outputs\n"</div>
<div>+<span class="" style="white-space:pre"> </span>" --no-input\t\tDont create input devices\n"</div><div>+<span class="" style="white-space:pre"> </span>" --use-2d\t\tUse the 2D (GPU) renderer (DirectFB API)\n"</div>
<div>+<span class="" style="white-space:pre"> </span>" --use-pixman\t\tUse the pixman (CPU) renderer\n\n"</div><div>+<span class="" style="white-space:pre"> </span>" --headless\t\tRun weston in the background (no compositing)\n\n");</div>
<div>+#endif</div><div>+</div><div> <span class="" style="white-space:pre"> </span>fprintf(stderr,</div><div> <span class="" style="white-space:pre"> </span>"Options for drm-backend.so:\n\n"</div><div> <span class="" style="white-space:pre"> </span>" --connector=ID\tBring up only this connector\n"</div>
</div>