Re: [PATCH weston v4 01/15] Add a fullscreen shell protocol

2014-03-07 Thread Jason Ekstrand
On Mar 7, 2014 1:14 PM, "Bryce W. Harrington" 
wrote:
>
> On Fri, Mar 07, 2014 at 11:31:16AM -0600, Jason Ekstrand wrote:
> > > > + If the size of the presented surface changes, the resulting
output
> > > > + is undefined.  The compositor may attempt to change the output
> > mode
> > > > + to compensate.  However, there is no guarantee that a suitable
> > mode
> > > > + will be found and the client has no way to be notified of
success
> > > > + or failure.
> > >
> > > Probably a stupid question but could the presented surface be locked
to
> > > prevent it from changing size?
> >
> > Not really.  The client simply attaches buffers of some size or another
and
> > the server has to take what the client gives it.  That patagraph is
> > intended expressly to address this by telling the client "Don't do
that!"
> > under threat of undefined results.
>
> Guess I'm thinking more from the user perspective of having downloaded
> some random client app off the internet that ignores this advice.
>
> Presumably at least the damage is limited to the client's window.  I
> guess that's my main concern - that some random app doesn't leave the
> user's system borked up.
>
> > > > + The framerate parameter specifies the target framerate for the
> > > > + output.  The compositor is free to ignore this parameter.  A
value
> > > > + of 0 indicates that the client has no preference.
> > >
> > > This doesn't actually define what the framerate parameter does.  Does
it
> > > do something if the framerate drops too low?  Or does it cap it to not
> > > go above a certain level?
> >
> > The output mode is given by three parameters: width, height, and
> > framerate.  The framerate should be given in mHz (same as in
> > wl_output.mode) but maybe I should specify that.  If the compositor
states
> > that the given output supports, for instance 1024x768@60Hz and
1024x768@50Hz,
> > this lets the client specify which it would like.  In most cases, the
> > client won't care which is why I have the 0 option.  However, providing
a
> > framerate option allows the client more-or-less full control over the
> > output mode.
>
> Ah, that's clearer.  Think I was confused by the word target; 'desired
> framerate' would maybe be clearer.
>
> So for your examples, if 50Hz was desired, then you'd pass
> framerate="5"?
>
> > > > + If the surface has a buffer_scale greater than 1, the
compositor
> > > > + may choose a mode that matches either the buffer size or the
> > > > + surface size.  In either case, the surface will fill the
output.
> > >
> > > This paragraph is a bit confusing.  Is buffer_scale a scaling factor?
> >
> > Wayland provides an integer scale parameter for each output that tells
the
> > client that the given output is actually scaled down.  This is for HiDPI
> > displays where you may want 2 or 3 physical pixels per logical pixel.
 If
> > the output has a scale factor of 3, that means that every surface on
that
> > output will be scaled up by a factor of 3.  The buffer_scale option
allows
> > the client to compensate in the same way as the buffer_transform option
> > allows it to compensate for a rotated output.  If a surface has a
> > buffer_scale of 3 and a 600x900 buffer, then the size of the surface is
> > only 200x300 but it will be pixel-for-pixel exact on the output that's
> > scaled by 3.
> >
> > The problem here is what to do with the buffer_scale factor.  In the
> > example above, the client is providing a 600x900 buffer but the surface
is
> > only 200x300.  Which size should the compositor make the output?  This
gets
> > even stickier because the output modes provided by wl_output are given
in
> > physical pixels without any transform or scale.  As given, I chose to
> > explicitly not solve this problem and let the compositor choose.  In
> > practice, I expect that most compositors won't provide any scale factor
on
> > the output and the client just provides the surface size it wants.
> >
> > Perhaps this isn't the best option.  Would it be better defined if we
just
> > stated that the compositor will try to match the output size to the
surface
> > size?  Then warn clients that the wl_output.scale factor may still get
> > applied.  This may be a better option since the client will have to
handle
> > the tramsform in a similar way.
> >
> > Ultimately, if the client wants to control modesetting it should be
either
> > a) using the same size and transform as the output or b) providing a
> > surface in output-space (after having transformed the mode from the
> > compositor) and letting the compositor transform/scale it.  I'm not
really
> > sure what's best to do here honestly.  Suggestions are appreciated.
 I'll
> > think on it more.
>
> Are the use cases here just HiDPI and fullscreen games?  If there are
> other use cases they might shed light on the scope of the problem.
> Would video players use it?
>
> In particular is there any use case for having 1 physical pixel per N
> logical

Re: [RFCv3 weston 01/15] compositor: refactor more into weston_surface_attach

2014-03-07 Thread Daniel Stone
Hi,

On 7 March 2014 13:03, Pekka Paalanen  wrote:
> Merge more code into a common function. No functional changes.

Quick nitpick: does this not break all the pixman_region32_*() calls
in weston_surface_commit(), which rely on surface->{width,height}?
Should be pretty easy to see this breakage when resizing larger with a
steady-state (as opposed to constantly-attaching) client.

Cheers,
Daniel
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] x11-backend: Add a --scale option

2014-03-07 Thread Jason Ekstrand
From: Jason Ekstrand 

---
 man/weston.man   |  4 
 src/compositor-x11.c | 11 +++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/man/weston.man b/man/weston.man
index f2d1b4c..fd1c7a5 100644
--- a/man/weston.man
+++ b/man/weston.man
@@ -186,6 +186,10 @@ X windows to emulate the same number of outputs.
 Make the default size of each X window
 .IR W x H " pixels."
 .TP
+.B \-\-scale\fR=\fIN\fR
+Give all outputs a scale factor of
+.I N.
+.TP
 .B \-\-use\-pixman
 Use the pixman renderer.  By default weston will try to use EGL and
 GLES2 for rendering.  Passing this option will make weston use the
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 6b5eb64..bb4ac9f 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -56,6 +56,7 @@
 
 static int option_width;
 static int option_height;
+static int option_scale;
 static int option_count;
 
 struct x11_compositor {
@@ -602,8 +603,8 @@ x11_output_wait_for_map(struct x11_compositor *c, struct 
x11_output *output)
if (configure_notify->width % output->scale != 0 ||
configure_notify->height % output->scale != 0)
weston_log("Resolution is not a multiple of 
screen size, rounding\n");
-   output->mode.width = configure_notify->width / 
output->scale;
-   output->mode.height = configure_notify->height / 
output->scale;
+   output->mode.width = configure_notify->width;
+   output->mode.height = configure_notify->height;
configured = 1;
break;
}
@@ -1478,7 +1479,7 @@ x11_compositor_create(struct wl_display *display,
struct weston_config_section *section;
xcb_screen_iterator_t s;
int i, x = 0, output_count = 0;
-   int width, height, count, scale;
+   int width, height, scale, count;
const char *section_name;
char *name, *t, *mode;
uint32_t transform;
@@ -1534,6 +1535,7 @@ x11_compositor_create(struct wl_display *display,
 
width = option_width ? option_width : 1024;
height = option_height ? option_height : 640;
+   scale = option_scale ? option_scale : 1;
count = option_count ? option_count : 1;
 
section = NULL;
@@ -1586,7 +1588,7 @@ x11_compositor_create(struct wl_display *display,
for (i = output_count; i < count; i++) {
output = x11_compositor_create_output(c, x, 0, width, height,
  fullscreen, no_input, 
NULL,
- 
WL_OUTPUT_TRANSFORM_NORMAL, 1);
+ 
WL_OUTPUT_TRANSFORM_NORMAL, scale);
if (output == NULL)
goto err_x11_input;
x = pixman_region32_extents(&output->base.region)->x2;
@@ -1623,6 +1625,7 @@ backend_init(struct wl_display *display, int *argc, char 
*argv[],
const struct weston_option x11_options[] = {
{ WESTON_OPTION_INTEGER, "width", 0, &option_width },
{ WESTON_OPTION_INTEGER, "height", 0, &option_height },
+   { WESTON_OPTION_INTEGER, "scale", 0, &option_scale },
{ WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &fullscreen },
{ WESTON_OPTION_INTEGER, "output-count", 0, &option_count },
{ WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input },
-- 
1.8.5.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston v4 01/15] Add a fullscreen shell protocol

2014-03-07 Thread Bryce W. Harrington
On Fri, Mar 07, 2014 at 11:31:16AM -0600, Jason Ekstrand wrote:
> > > + If the size of the presented surface changes, the resulting output
> > > + is undefined.  The compositor may attempt to change the output
> mode
> > > + to compensate.  However, there is no guarantee that a suitable
> mode
> > > + will be found and the client has no way to be notified of success
> > > + or failure.
> >
> > Probably a stupid question but could the presented surface be locked to
> > prevent it from changing size?
> 
> Not really.  The client simply attaches buffers of some size or another and
> the server has to take what the client gives it.  That patagraph is
> intended expressly to address this by telling the client "Don't do that!"
> under threat of undefined results.

Guess I'm thinking more from the user perspective of having downloaded
some random client app off the internet that ignores this advice.

Presumably at least the damage is limited to the client's window.  I
guess that's my main concern - that some random app doesn't leave the
user's system borked up.

> > > + The framerate parameter specifies the target framerate for the
> > > + output.  The compositor is free to ignore this parameter.  A value
> > > + of 0 indicates that the client has no preference.
> >
> > This doesn't actually define what the framerate parameter does.  Does it
> > do something if the framerate drops too low?  Or does it cap it to not
> > go above a certain level?
> 
> The output mode is given by three parameters: width, height, and
> framerate.  The framerate should be given in mHz (same as in
> wl_output.mode) but maybe I should specify that.  If the compositor states
> that the given output supports, for instance 1024x768@60Hz and 1024x768@50Hz,
> this lets the client specify which it would like.  In most cases, the
> client won't care which is why I have the 0 option.  However, providing a
> framerate option allows the client more-or-less full control over the
> output mode.

Ah, that's clearer.  Think I was confused by the word target; 'desired
framerate' would maybe be clearer.

So for your examples, if 50Hz was desired, then you'd pass
framerate="5"?

> > > + If the surface has a buffer_scale greater than 1, the compositor
> > > + may choose a mode that matches either the buffer size or the
> > > + surface size.  In either case, the surface will fill the output.
> >
> > This paragraph is a bit confusing.  Is buffer_scale a scaling factor?
> 
> Wayland provides an integer scale parameter for each output that tells the
> client that the given output is actually scaled down.  This is for HiDPI
> displays where you may want 2 or 3 physical pixels per logical pixel.  If
> the output has a scale factor of 3, that means that every surface on that
> output will be scaled up by a factor of 3.  The buffer_scale option allows
> the client to compensate in the same way as the buffer_transform option
> allows it to compensate for a rotated output.  If a surface has a
> buffer_scale of 3 and a 600x900 buffer, then the size of the surface is
> only 200x300 but it will be pixel-for-pixel exact on the output that's
> scaled by 3.
> 
> The problem here is what to do with the buffer_scale factor.  In the
> example above, the client is providing a 600x900 buffer but the surface is
> only 200x300.  Which size should the compositor make the output?  This gets
> even stickier because the output modes provided by wl_output are given in
> physical pixels without any transform or scale.  As given, I chose to
> explicitly not solve this problem and let the compositor choose.  In
> practice, I expect that most compositors won't provide any scale factor on
> the output and the client just provides the surface size it wants.
> 
> Perhaps this isn't the best option.  Would it be better defined if we just
> stated that the compositor will try to match the output size to the surface
> size?  Then warn clients that the wl_output.scale factor may still get
> applied.  This may be a better option since the client will have to handle
> the tramsform in a similar way.
> 
> Ultimately, if the client wants to control modesetting it should be either
> a) using the same size and transform as the output or b) providing a
> surface in output-space (after having transformed the mode from the
> compositor) and letting the compositor transform/scale it.  I'm not really
> sure what's best to do here honestly.  Suggestions are appreciated.  I'll
> think on it more.

Are the use cases here just HiDPI and fullscreen games?  If there are
other use cases they might shed light on the scope of the problem.
Would video players use it?

In particular is there any use case for having 1 physical pixel per N
logical pixels?  If there is, then perhaps let buffer_scale just be the
scaling factor, and have a separate parameter for toggling scaling on or
off?  Documentation-wise, having two parameters is going to be easier to
explain I think

[PATCH mesa 1/7] Use the magic behaviour of GL_BACK in GLES 1 and 2 as well as 3

2014-03-07 Thread Neil Roberts
In GLES 3 it is not possible to select rendering to the front buffer and
instead selecting GL_BACK has the magic interpretation that it is either the
front buffer on single-buffered configs or the back buffer on double-buffered.
GLES 1 and 2 have no way of selecting the draw buffer at all. In that case we
were initialising the draw buffer to either GL_FRONT or GL_BACK depending on
the context's config and then leaving it at that. When we switch to having
configless contexts we ideally want Mesa to automatically switch between the
front and back buffer whenever a double- or single-buffered surface is bound.
To make this happen we can just allow the magic behaviour from GLES 3 in GLES
1 and 2 as well. It shouldn't matter what the internal value of the draw
buffer is in GLES 1 and 2 because there is no way to query it from the
external API.
---
 src/mesa/main/buffers.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 6cbce9d..b13a7af 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -101,7 +101,7 @@ draw_buffer_enum_to_bitmask(const struct gl_context *ctx, 
GLenum buffer)
   case GL_FRONT:
  return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
   case GL_BACK:
- if (_mesa_is_gles3(ctx)) {
+ if (_mesa_is_gles(ctx)) {
 /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL
  * ES 3.0.1 specification says:
  *
@@ -111,6 +111,11 @@ draw_buffer_enum_to_bitmask(const struct gl_context *ctx, 
GLenum buffer)
  *
  * Since there is no stereo rendering in ES 3.0, only return the
  * LEFT bits.  This also satisfies the "n must be 1" requirement.
+ *
+ * We also do this for GLES 1 and 2 because those APIs have no
+ * concept of selecting the front and back buffer anyway and it's
+ * convenient to be able to maintain the magic behaviour of
+ * GL_BACK in that case.
  */
 if (ctx->DrawBuffer->Visual.doubleBufferMode)
return BUFFER_BIT_BACK_LEFT;
-- 
1.8.5.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH mesa 2/7] Fix the initial value of glDrawBuffers for GLES

2014-03-07 Thread Neil Roberts
Under GLES 3 it is not valid to pass GL_FRONT to glDrawBuffers. Instead,
GL_BACK has a magic interpretation which means it will render to the front
buffer on single-buffered contexts and the back buffer on double-buffered. We
were incorrectly setting the initial value to GL_FRONT for single-buffered
contexts. This probably doesn't really matter at the moment except that
presumably it would be exposed in the API via glGetIntegerv.

When we switch to configless contexts this is more important because in that
case we always want to rely on the magic interpretation of GL_BACK in order to
automatically switch between the front and back buffer when a new surface with
a different number of buffers is bound. We also do this for GLES 1 and 2
because the internal value doesn't matter in that case and it is convenient to
use the same code to have the magic interpretation of GL_BACK.
---
 src/mesa/main/blend.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index eb4f1d6..c37c0fe 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -911,7 +911,9 @@ void _mesa_init_color( struct gl_context * ctx )
ctx->Color.LogicOp = GL_COPY;
ctx->Color.DitherFlag = GL_TRUE;
 
-   if (ctx->Visual.doubleBufferMode) {
+   /* GL_FRONT is not possible on GLES. Instead GL_BACK will render to either
+* the front or the back buffer depending on the config */
+   if (ctx->Visual.doubleBufferMode || _mesa_is_gles(ctx)) {
   ctx->Color.DrawBuffer[0] = GL_BACK;
}
else {
-- 
1.8.5.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 0/7] EGL_MESA_configless_context

2014-03-07 Thread Neil Roberts
Here is a series of patches to add an extension which makes it
possible to create an EGL context without specifying a config. A
context created in this way can be bound with any surface using the
same EGLDisplay rather than being restricted to those using the same
config. The main use case is that it would then be possible for a
Wayland compositor to drive two displays which may have different
bit-depths without having to wastefully create two contexts.

Mesa seems to mostly cope with this already so the patches are mostly
just to add the extension and remove the restriction.

There is also a patch for Piglit to try and test the extension. I
tried running the branch though the 'all tests' test suite and apart
from this new test now passing there was only one difference which is
that the GLX_OML_sync_control/swapbuffersmsc-divisor-zero test failed.
However if I run piglit-run.py again and set a regexp so it only runs
that one test then it passes so I'm wondering if it might just be an
intermittent failure.

The main thorny issue with the extension is how to handle the initial
value of glDrawBuffer when a configless context is used. If a config
is used then we can just say the default is GL_BACK if the config is
double-buffered and GL_FRONT otherwise. I have taken the approach that
this decision is made the first time the context is bound rather than
when it is first created. There should be no way to query the value of
glDrawBuffer until the context is first bound so it shouldn't cause
any harm that Mesa changes the value at that point. I think this is
worth doing for the convenience to the application which would
otherwise have to remember to explicitly set it to GL_BACK in the
common case that double-buffering is used.

I've also included a couple of patches to take advantage of the
extension in Weston.

Regards,
- Neil
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH weston 7/7] Add support for having different GBM formats for different outputs

2014-03-07 Thread Neil Roberts
The gbm-format configuration option can now be specified per-output as
well as in the core config section. If it is not specified it will
default to the format specified in the core section. The
EGL_MESA_configless_context extension is required for this to work. If
this extension is available it will create a context without an
EGLConfig and then it will potentially use a different EGLConfig for
each output.

The gl-renderer interface has been changed so that it takes the EGL
attributes and visual ID in the create_output function as well as in
the create function.
---
 src/compositor-drm.c |  65 ---
 src/compositor-fbdev.c   |   4 +-
 src/compositor-wayland.c |   4 +-
 src/compositor-x11.c |   4 +-
 src/gl-renderer.c| 134 +--
 src/gl-renderer.h|   4 +-
 6 files changed, 141 insertions(+), 74 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index e45f47d..3f584a6 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -147,6 +147,7 @@ struct drm_output {
drmModeCrtcPtr original_crtc;
struct drm_edid edid;
drmModePropertyPtr dpms_prop;
+   uint32_t format;
 
int vblank_pending;
int page_flip_pending;
@@ -420,8 +421,6 @@ static uint32_t
 drm_output_check_scanout_format(struct drm_output *output,
struct weston_surface *es, struct gbm_bo *bo)
 {
-   struct drm_compositor *c =
-   (struct drm_compositor *) output->base.compositor;
uint32_t format;
pixman_region32_t r;
 
@@ -442,7 +441,7 @@ drm_output_check_scanout_format(struct drm_output *output,
pixman_region32_fini(&r);
}
 
-   if (c->format == format)
+   if (output->format == format)
return format;
 
return 0;
@@ -507,7 +506,7 @@ drm_output_render_gl(struct drm_output *output, 
pixman_region32_t *damage)
return;
}
 
-   output->next = drm_fb_get_from_bo(bo, c, c->format);
+   output->next = drm_fb_get_from_bo(bo, c, output->format);
if (!output->next) {
weston_log("failed to get drm_fb for bo\n");
gbm_surface_release_buffer(output->surface, bo);
@@ -1528,12 +1527,13 @@ find_crtc_for_connector(struct drm_compositor *ec,
 static int
 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
 {
+   EGLint format = output->format;
int i, flags;
 
output->surface = gbm_surface_create(ec->gbm,
 output->base.current_mode->width,
 output->base.current_mode->height,
-ec->format,
+format,
 GBM_BO_USE_SCANOUT |
 GBM_BO_USE_RENDERING);
if (!output->surface) {
@@ -1541,7 +1541,9 @@ drm_output_init_egl(struct drm_output *output, struct 
drm_compositor *ec)
return -1;
}
 
-   if (gl_renderer->output_create(&output->base, output->surface) < 0) {
+   if (gl_renderer->output_create(&output->base, output->surface,
+  gl_renderer->opaque_attribs,
+  &format) < 0) {
weston_log("failed to create gl renderer output state\n");
gbm_surface_destroy(output->surface);
return -1;
@@ -1853,6 +1855,35 @@ setup_output_seat_constraint(struct drm_compositor *ec,
 }
 
 static int
+get_gbm_format_from_section(struct weston_config_section *section,
+   uint32_t default_value,
+   uint32_t *format)
+{
+   char *s;
+   int ret = 0;
+
+   weston_config_section_get_string(section,
+"gbm-format", &s, NULL);
+
+   if (s == NULL)
+   *format = default_value;
+   else if (strcmp(s, "xrgb") == 0)
+   *format = GBM_FORMAT_XRGB;
+   else if (strcmp(s, "rgb565") == 0)
+   *format = GBM_FORMAT_RGB565;
+   else if (strcmp(s, "xrgb2101010") == 0)
+   *format = GBM_FORMAT_XRGB2101010;
+   else {
+   weston_log("fatal: unrecognized pixel format: %s\n", s);
+   ret = -1;
+   }
+
+   free(s);
+
+   return ret;
+}
+
+static int
 create_output_for_connector(struct drm_compositor *ec,
drmModeRes *resources,
drmModeConnector *connector,
@@ -1919,6 +1950,11 @@ create_output_for_connector(struct drm_compositor *ec,
transform = parse_transform(s, output->base.name);
free(s);
 
+   if (get_gbm_format_from_section(section,
+   ec->format,
+   &output->format) == -1)
+  

[PATCH weston 6/7] Split gl_renderer_setup into two functions

2014-03-07 Thread Neil Roberts
Part of the gl_renderer_setup function only deals with checking EGL
extensions and doesn't need to have a current context. This patch
moves these checks so that they are done during gl_renderer_create
instead of waiting until we have an output. We will need this in a
later patch because some of the EGL extensions will affect how we
create the EGLSurface.
---
 src/gl-renderer.c | 90 ---
 1 file changed, 52 insertions(+), 38 deletions(-)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index 76325f4..868fdb7 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -1818,6 +1818,55 @@ out:
return -1;
 }
 
+static int
+gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+{
+   struct gl_renderer *gr = get_renderer(ec);
+   const char *extensions;
+   EGLBoolean ret;
+
+   gr->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
+   gr->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
+   gr->bind_display =
+   (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
+   gr->unbind_display =
+   (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
+   gr->query_buffer =
+   (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
+
+   extensions =
+   (const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
+   if (!extensions) {
+   weston_log("Retrieving EGL extension string failed.\n");
+   return -1;
+   }
+
+   if (strstr(extensions, "EGL_WL_bind_wayland_display"))
+   gr->has_bind_display = 1;
+   if (gr->has_bind_display) {
+   ret = gr->bind_display(gr->egl_display, ec->wl_display);
+   if (!ret)
+   gr->has_bind_display = 0;
+   }
+
+   if (strstr(extensions, "EGL_EXT_buffer_age"))
+   gr->has_egl_buffer_age = 1;
+   else
+   weston_log("warning: EGL_EXT_buffer_age not supported. "
+  "Performance could be affected.\n");
+
+#ifdef EGL_EXT_swap_buffers_with_damage
+   if (strstr(extensions, "EGL_EXT_swap_buffers_with_damage"))
+   gr->swap_buffers_with_damage =
+   (void *) 
eglGetProcAddress("eglSwapBuffersWithDamageEXT");
+   else
+   weston_log("warning: EGL_EXT_swap_buffers_with_damage not "
+  "supported. Performance could be affected.\n");
+#endif
+
+   return 0;
+}
+
 static const EGLint gl_renderer_opaque_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 1,
@@ -1877,6 +1926,9 @@ gl_renderer_create(struct weston_compositor *ec, 
EGLNativeDisplayType display,
ec->capabilities |= WESTON_CAP_ROTATION_ANY;
ec->capabilities |= WESTON_CAP_CAPTURE_YFLIP;
 
+   if (gl_renderer_setup_egl_extensions(ec) < 0)
+   goto err_egl;
+
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
 
wl_signal_init(&gr->destroy_signal);
@@ -2004,14 +2056,6 @@ gl_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
 
gr->image_target_texture_2d =
(void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
-   gr->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
-   gr->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
-   gr->bind_display =
-   (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
-   gr->unbind_display =
-   (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
-   gr->query_buffer =
-   (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
 
extensions = (const char *) glGetString(GL_EXTENSIONS);
if (!extensions) {
@@ -2037,36 +2081,6 @@ gl_renderer_setup(struct weston_compositor *ec, 
EGLSurface egl_surface)
if (strstr(extensions, "GL_OES_EGL_image_external"))
gr->has_egl_image_external = 1;
 
-   extensions =
-   (const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
-   if (!extensions) {
-   weston_log("Retrieving EGL extension string failed.\n");
-   return -1;
-   }
-
-   if (strstr(extensions, "EGL_WL_bind_wayland_display"))
-   gr->has_bind_display = 1;
-   if (gr->has_bind_display) {
-   ret = gr->bind_display(gr->egl_display, ec->wl_display);
-   if (!ret)
-   gr->has_bind_display = 0;
-   }
-
-   if (strstr(extensions, "EGL_EXT_buffer_age"))
-   gr->has_egl_buffer_age = 1;
-   else
-   weston_log("warning: EGL_EXT_buffer_age not supported. "
-  "Performance could be affected.\n");
-
-#ifdef EGL_EXT_swap_buffers_with_damage
-   if (strstr(extensions, "EGL_EXT_swap_buffers_with_damage"))
-   gr->swap_buffers_with_damage =
-   

[PATCH piglit 5/7] Add a test for EGL_MESA_configless_context

2014-03-07 Thread Neil Roberts
This tests creating an EGLContext without an EGLConfig and then
creates three surfaces with different configs and tries rendering to
them. The test is skipped if the extension is not available.
---
 tests/all.py   |   4 +
 tests/egl/CMakeLists.gl.txt|   1 +
 tests/egl/egl-configless-context.c | 380 +
 3 files changed, 385 insertions(+)
 create mode 100644 tests/egl/egl-configless-context.c

diff --git a/tests/all.py b/tests/all.py
index d6daed2..8e6ac8e 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -3765,6 +3765,10 @@ egl_khr_create_context['valid debug flag GL'] = 
plain_test('egl-create-context-v
 for api in ('gles1', 'gles2', 'gles3'):
 egl_khr_create_context['valid debug flag ' + api] = 
plain_test('egl-create-context-valid-flag-debug-gles ' + api)
 
+egl_mesa_configless_context = Group()
+spec['EGL_MESA_configless_context']= egl_mesa_configless_context
+egl_mesa_configless_context['basic'] = plain_test('egl-configless-context')
+
 egl_ext_client_extensions = Group()
 spec['EGL_EXT_client_extensions'] = egl_ext_client_extensions
 for i in [1, 2, 3]:
diff --git a/tests/egl/CMakeLists.gl.txt b/tests/egl/CMakeLists.gl.txt
index d7f17f6..bad6d87 100644
--- a/tests/egl/CMakeLists.gl.txt
+++ b/tests/egl/CMakeLists.gl.txt
@@ -20,6 +20,7 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(egl-create-surface pthread ${X11_X11_LIB})
piglit_add_executable (egl-query-surface egl-util.c egl-query-surface.c)
target_link_libraries(egl-query-surface pthread ${X11_X11_LIB})
+piglit_add_executable (egl-configless-context egl-configless-context.c)
 ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
 # vim: ft=cmake:
diff --git a/tests/egl/egl-configless-context.c 
b/tests/egl/egl-configless-context.c
new file mode 100644
index 000..f088056
--- /dev/null
+++ b/tests/egl/egl-configless-context.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright © 2010, 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors: Neil Roberts 
+ *  Kristian Høgsberg 
+ */
+
+/** @file egl-configless-context.c
+ *
+ * Test the EGL_MESA_configless_context extension
+ */
+
+/* Chunks of code in this file are taken from egl-util.c */
+
+#include 
+
+#include "piglit-util-gl-common.h"
+#include "piglit-util-egl.h"
+
+#ifndef EGL_MESA_configless_context
+#define EGL_MESA_configless_context 1
+#define EGL_NO_CONFIG_MESA ((EGLConfig)0)
+#endif
+
+struct state {
+   Display *dpy;
+   EGLDisplay egl_dpy;
+   EGLint egl_major, egl_minor;
+   EGLContext ctx;
+};
+
+struct window {
+   EGLConfig config;
+   Window win;
+   EGLSurface surface;
+};
+
+static EGLint
+get_config_attrib(EGLDisplay egl_dpy,
+ EGLConfig config,
+ EGLenum attrib)
+{
+   EGLBoolean status;
+   EGLint value;
+
+   status = eglGetConfigAttrib(egl_dpy,
+   config,
+   attrib,
+   &value);
+   if (!status) {
+   fprintf(stderr, "eglGetConfigAttrib failed\n");
+   piglit_report_result(PIGLIT_FAIL);
+   }
+
+   return value;
+}
+
+static EGLConfig
+choose_config(EGLDisplay egl_dpy,
+ int depth,
+ EGLBoolean has_depth_buffer)
+{
+   EGLint attribs[32], *a = attribs;
+   EGLConfig configs[128];
+   EGLBoolean status;
+   EGLint config_count, i;
+   EGLint buffer_size;
+   EGLint depth_size;
+   EGLConfig best_config = 0;
+
+   switch (depth) {
+   case 16:
+   *(a++) = EGL_RED_SIZE;
+   *(a++) = 5;
+   *(a++) = EGL_GREEN_SIZE;
+   *(a++) = 6;
+   *(a++) = EGL_BLUE_SIZE;
+   *(a++) = 5;
+   *(a++) = EGL_ALPHA_SIZE;
+   *(

[PATCH mesa 3/7] eglCreateContext: Remove the check for whether config == 0

2014-03-07 Thread Neil Roberts
In eglCreateContext there is a check for whether the config parameter is zero
and in this case it will avoid reporting an error if the
EGL_KHR_surfacless_context extension is supported. However there is nothing in
that extension which says you can create a context without a config and Mesa
breaks if you try this so it is probably better to leave it reporting an
error.

The original check was added in b90a3e7d8b1bc based on the API-specific
extensions EGL_KHR_surfaceless_opengl/gles1/gles2. This was later changed to
refer to EGL_KHR_surfacless_context in b50703aea5. Perhaps the original
extensions specified a configless context but the new one does not.
---
 src/egl/main/eglapi.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 59e214c..42bcb72 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -431,11 +431,8 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, 
EGLContext share_list,
 
_EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
 
-   if (!config) {
-  /* config may be NULL if surfaceless */
-  if (!disp->Extensions.KHR_surfaceless_context)
- RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
-   }
+   if (!config)
+  RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
 
if (!share && share_list != EGL_NO_CONTEXT)
   RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
-- 
1.8.5.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH mesa 4/7] Add the EGL_MESA_configless_context extension

2014-03-07 Thread Neil Roberts
This extension provides a way for an application to render to multiple
surfaces with different buffer formats without having to use multiple
contexts. An EGLContext can be created without an EGLConfig by passing
EGL_NO_CONFIG_MESA. In that case there are no restrictions on the surfaces
that can be used with the context apart from that they must be using the same
EGLDisplay.

_mesa_initialze_context can now take a NULL gl_config which will mark the
context as ‘configless’. It will memset the visual to zero in that case.
Previously the i965 and i915 drivers were explicitly creating a zeroed visual
whenever 0 is passed for the EGLConfig. Mesa needs to be aware that the
context is configless because it affects the initial value to use for
glDrawBuffer. The first time the context is bound it will set the initial
value for configless contexts depending on whether the framebuffer used is
double-buffered.
---
 docs/specs/MESA_configless_context.spec   | 120 ++
 include/EGL/eglext.h  |   5 ++
 src/egl/drivers/dri2/egl_dri2.c   |   1 +
 src/egl/main/eglapi.c |   2 +-
 src/egl/main/eglcontext.c |  20 -
 src/egl/main/egldisplay.h |   1 +
 src/egl/main/eglmisc.c|   1 +
 src/mesa/drivers/dri/i915/intel_context.c |   6 --
 src/mesa/drivers/dri/i965/brw_context.c   |   6 --
 src/mesa/main/context.c   |  82 +++-
 src/mesa/main/mtypes.h|   6 ++
 11 files changed, 213 insertions(+), 37 deletions(-)
 create mode 100644 docs/specs/MESA_configless_context.spec

diff --git a/docs/specs/MESA_configless_context.spec 
b/docs/specs/MESA_configless_context.spec
new file mode 100644
index 000..8bed90d
--- /dev/null
+++ b/docs/specs/MESA_configless_context.spec
@@ -0,0 +1,120 @@
+Name
+
+MESA_configless_context
+
+Name Strings
+
+EGL_MESA_configless_context
+
+Contact
+
+Neil Roberts 
+
+Status
+
+Proposal
+
+Version
+
+Version 1, February 28, 2014
+
+Number
+
+EGL Extension #not assigned
+
+Dependencies
+
+Requires EGL 1.4 or later.  This extension is written against the
+wording of the EGL 1.4 specification.
+
+Overview
+
+This extension provides a means to use a single context to render to
+multiple surfaces which have different EGLConfigs. Without this extension
+the EGLConfig for every surface used by the context must be compatible
+with the one used by the context. The only way to render to surfaces with
+different formats would be to create multiple contexts but this is
+inefficient with modern GPUs where this restriction is unnecessary.
+
+IP Status
+
+Open-source; freely implementable.
+
+New Procedures and Functions
+
+None.
+
+New Tokens
+
+Accepted as  in eglCreateContext
+
+EGL_NO_CONFIG_MESA  ((EGLConfig)0)
+
+Additions to the EGL Specification section "2.2 Rendering Contexts and Drawing
+Surfaces"
+
+Add the following to the 3rd paragraph:
+
+   "EGLContexts can also optionally be created with respect to an EGLConfig
+depending on the parameters used at creation time. If a config is provided
+then additional restrictions apply on what surfaces can be used with the
+context."
+
+Replace the last sentence of the 6th paragraph with:
+
+   "In order for a context to be compatible with a surface they both must have
+been created with respect to the same EGLDisplay. If the context was
+created without respect to an EGLConfig then there are no further
+constraints. Otherwise they are only compatible if:"
+
+Remove the last bullet point in the list of constraints.
+
+Additions to the EGL Specification section "3.7.1 Creating Rendering Contexts"
+
+Replace the paragraph starting "If config is not a valid EGLConfig..."
+with
+
+   "The config argument can either be a valid EGLConfig or EGL_NO_CONFIG_MESA.
+If it is neither of these then an EGL_BAD_CONFIG error is generated. If a
+valid config is passed then the error will also be generated if the config
+does not support the requested client API (this includes requesting
+creation of an OpenGL ES 1.x context when the EGL_RENDERABLE_TYPE
+attribute of config does not contain EGL_OPENGL_ES_BIT, or creation of an
+OpenGL ES 2.x context when the attribute does not contain
+EGL_OPENGL_ES2_BIT).
+
+Passing EGL_NO_CONFIG_MESA will create a configless context. When a
+configless context is used with the OpenGL API it can be assumed that the
+initial values of the context's state will be decided when the context is
+first made current. In particular this means that the decision of whether
+to use GL_BACK or GL_FRONT for the initial value of the first output in
+glDrawBuffers will be decided based on the config of the draw surface when
+it is first bound. If the context is later bound to another surface with a
+di

Re: [PATCH 00/12] implement per connector clone mode

2014-03-07 Thread Bill Spitzak

Xiong Zhang wrote:

With the help of Ander, this is the new round clone mode patchset.


It seems like there is now two different methods of getting a surface to 
be seen more than once: using this clone of an output, and the "views" 
stuff for putting a surface on more than one output.


I think it would be a lot nicer if these were merged, and the idea of a 
view being placed on multiple outputs is nicer. That provides a clean 
way of handling outputs of different aspect rations (by allowing the 
position/scale of the surfaces to vary) and more importantly gets rid of 
 a lot of annoyances of a true clone in that the mouse cursor and even 
popup menus can selectively not appear on the clone output (for 
presentations this would help a lot).

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston v4 01/15] Add a fullscreen shell protocol

2014-03-07 Thread Jason Ekstrand
Hi Bryce,
Thanks for reviewing!  I'll get the typo changes made and look into
canceled vs. cancelled.  More comments below

On Mar 6, 2014 9:38 PM, "Bryce W. Harrington" 
wrote:
>
> On Tue, Feb 25, 2014 at 07:26:33PM -0600, Jason Ekstrand wrote:
> > Signed-off-by: Jason Ekstrand 
> > ---
> >  protocol/fullscreen-shell.xml | 158
++
> >  1 file changed, 158 insertions(+)
> >  create mode 100644 protocol/fullscreen-shell.xml
> >
> > diff --git a/protocol/fullscreen-shell.xml
b/protocol/fullscreen-shell.xml
> > new file mode 100644
> > index 000..13bdfcf
> > --- /dev/null
> > +++ b/protocol/fullscreen-shell.xml
> > @@ -0,0 +1,158 @@
> > +
> > +  
> > +
> > +  Displays a single surface per output.
> > +
> > +  This interface provides a mechanism for a single client to
display
> > +  simple full-screen surfaces.  While there technically may be
multiple
> > +  clients bound to this interface, only one of those clients
should be
> > +  shown at a time.
> > +
> > +  To present a surface, the client uses either the present_surface
or
> > +  present_surface_for_mode requests.  Presenting a surface takes
effect
> > +  on the next wl_surface.commit.  See the individual requests for
> > +  details about scaling and mode switches.
> > +
> > +  The client can have at most one surface per output at any time.
> > +  Requesting a surface be presented on an output that already has a
> > +  surface replaces the previously presented surface.  Presenting a
null
> > +  surface removes its content and effectively disables the output.
> > +  Exactly what happens when an output is "disabled" is
> > +  compositor-specific.  The same surface may be presented multiple
>
> presented to multiple
>
> > +  outputs simultaneously.
> > +
> > +  Once a surface is presented on an output, it stays on that output
> > +  until either the client removes it or the compositor destroys the
> > +  output.  This way, the client can update the output's contents by
> > +  simply attaching a new buffer.
> > +
> > +
> > +
> > +  
> > + Release the binding from the wl_fullscreen_shell interface
> > +
> > + This destroys the server-side object and frees this binding.  If
> > + the client binds to wl_fullscreen_shell multiple times, it may
wish
> > + to free some of those bindings.
> > +  
> > +
> > +
> > +
> > +  
> > + Hints to indicate to the compositor how to deal with a conflict
> > + between the dimensions of the surface and the dimensions of the
> > + output. The compositor is free to ignore this parameter.
> > +  
> > +  
> > +  
> > +  
> > +  
> > +  
> > +
> > +
> > +
> > +  
> > + Present a surface on the given output.
> > +
> > + If the output is null, the compositor will present the surface on
> > + whatever display (or displays) it thinks best.  In particular,
this
> > + may replace any or all surfaces currently presented so it should
> > + not be used in combination with placing surfaces on specific
> > + outputs.
> > +
> > + The method parameter is a hint to the compositor for how the
surface
> > + is to be presented.  In particular, it tells the compostior how to
> > + handle a size mismatch between the presented surface and the
> > + output.  The compositor is free to ignore this parameter.
> > +
> > + The "zoom", "zoom_crop", and "stretch" methods imply a scaling
> > + operation on the surface.  This will override any kind of output
> > + scaling, so the buffer_scale property of the surface is
effectively
> > + ignored.
> > +  
> > +  
> > +  
> > +  
> > +
> > +
> > +
> > +  
> > + Presents a surface on the given output for a particular mode.
> > +
> > + If the current size of the output differs from that of the
surface,
> > + the compositor will attempt to change the size of the output to
> > + match the surface.  The result of the mode-swith operation will be
>
> mode-switch
>
> > + returned via the provided wl_fullscreen_shell_mode_feedback
object.
> > +
> > + If the current output mode matches the one requested or if the
> > + compositor successfully switches the mode to match the surface,
> > + then the mode_successfull event will be sent and the output will
>
> mode_successful event
>
> > + contain the contents of the given surface.  If the compositor
> > + cannot match the output size to the surface size, the mode_failed
> > + will be sent and the output will contain the contents of the
> > + previously presented surface (if any).  If another surface is
> > + presented on the given output before either of these has a chance
> > + to happen, the present_canceled event will be sent.
>
> present_cancelled
>
> Grepping weston for 'canceled' vs. 'cancelled' seems to indicate 

Re: [PATCH weston-ivi-shell v2 02/15] ivi application protocol:

2014-03-07 Thread Jason Ekstrand
On Mar 7, 2014 7:56 AM, "Nobuhiko Tanibata" <
nobuhiko_tanib...@xddp.denso.co.jp> wrote:
>
> Add interface ivi_application, which creates ivi_surface objects tied
> to a given wl_surface with a given id. The given id can be used in a
> shell to identify which application is assigned to a wl_surface and
> layout the surface wherever the shell wants. ivi_surface objects can
> be used to receive status of wl_surface in the scenegraph of the
> compositor.
>
> Signed-off-by: Nobuhiko Tanibata 
> ---
>
> Changes for v2:
>- Rename "error" to "warning" because meaning of "error" in wayland is
fatal.
>
>  protocol/ivi-application.xml | 88

>  1 file changed, 88 insertions(+)
>  create mode 100755 protocol/ivi-application.xml
>
> diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml
> new file mode 100755
> index 000..8659ec6
> --- /dev/null
> +++ b/protocol/ivi-application.xml
> @@ -0,0 +1,88 @@
> +
> +
> +
> +
> +Copyright (C) 2013 DENSO CORPORATION
> +Copyright (c) 2013 BMW Car IT GmbH
> +
> +Permission is hereby granted, free of charge, to any person
obtaining a copy
> +of this software and associated documentation files (the
"Software"), to deal
> +in the Software without restriction, including without limitation
the rights
> +to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell
> +copies of the Software, and to permit persons to whom the Software is
> +furnished to do so, subject to the following conditions:
> +
> +The above copyright notice and this permission notice shall be
included in
> +all copies or substantial portions of the Software.
> +
> +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
> +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
> +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
> +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER
> +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
> +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN
> +THE SOFTWARE.
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +The new visibility state is provided in argument
visibility.
> +If visibility is 0, the surface has become invisible.
> +If visibility is not 0, the surface has become visible.
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +surface_create will create a new surface with surface_id
in ivi compositor,
> +if it does not yet exists. If the surface with
surface_id already exists in
> +ivi compositor, the application content provided in
argument surface will
> +be used as surface content. If an other ivi application
already registered
> +content for surface with surface_id, an warning event
will indicate the problem.
> +
> +
> +
> +
> +
> +
> +
> +
> +These warning codes define all possible warning codes
returned by ivi compositor
> +on server-side warnings.
> +
> +
> +
> +

I have a couple more thoughts about these errors/warnings.  For one, I
think some of these should be errors.  For instance, there is no way that
the given wl_surface will be invalid unless the client has destroyed it.
Honestly, I'm not even sure if it's possible, given how libwayland is
written, to get a truely invalid wl_surface.  From what you've written in
previous e-mails, I can't quite tell but it sounds like you want to prevent
a client from attaaching multiple ivi_surface objects (and IVI ID's) to the
same surface.  If this is the case then doing so should probably also be a
fatal error because that means the client was written wrong.

With regards to what happens if a client tries to use an ID that's already
in use, I'm not 100% sure what to do there.  You know IVI systems better
than I do.  Is this something that happens with some degree of regularity?
Or is this something that only happens if the there is a mistake in the
client code?  I'll leave that up to you.

That said, if there is an issue, you need to explicitly say what happens to
the newly created ivi_surface object.  The Wayland protocol has no concept
of returning NULL.  Whenever a request or event is fired which has a new_id
parameter, both client and server-side objects always get created.  If
surface_create can throw a non-fatal error, we need to decide what happens
to the new ivi_surface object.  One way to do this would be to have the
error/warning event on the ivi_surface itself instead of on
ivi_application.  Then the client would know that if 

[RFCv3.1 weston] WIP protocol: add flags and refresh stream to presentation

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

This is quick write-up of
http://cgit.collabora.com/git/user/pq/weston.git/tree/buffer-queue3.txt?h=buffer-queue-spec

How would this idea feel?

Thanks,
pq
---
 protocol/presentation_timing.xml | 66 
 1 file changed, 66 insertions(+)

diff --git a/protocol/presentation_timing.xml b/protocol/presentation_timing.xml
index e191b87..7da735b 100644
--- a/protocol/presentation_timing.xml
+++ b/protocol/presentation_timing.xml
@@ -235,6 +235,24 @@
summary="new feedback object"/>
 
 
+
+  
+The no-skip flag will cause the compositor to never discard the
+flagged update. Instead, it will postpone following updates to the
+next output refresh cycle if needed to ensure, that this update
+will be on screen for at least one refresh cycle.
+
+Normally, the compositor will try to match the given target timestamp
+to the closest refresh cycle, which means that the update may hit
+the screen slightly earlier than requested. Not-before flag guarantees
+that the update is never shown before the given target time.
+  
+
+  
+  
+
+
 
   
 This request changes the behaviour of the very next
@@ -265,6 +283,7 @@
summary="low 32 bits of the seconds part of the target timestamp"/>
   
+  
 
 
 
@@ -288,6 +307,16 @@
summary="target surface"/>
 
 
+
+  
+  
+
+  
+  
+
+
 
   
 This event tells the client, in which clock domain the
@@ -366,6 +395,19 @@
summary="presentation output"/>
 
 
+
+  
+  
+
+  
+  
+  
+  
+
+
 
   
 The associated content update was displayed to the user at the
@@ -422,6 +464,7 @@
summary="high 32 bits of refresh counter"/>
   
+  
 
 
 
@@ -431,4 +474,27 @@
 
   
 
+  
+
+
+
+
+  
+  
+
+
+
+  
+  
+  
+  
+  
+
+  
+
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH weston-ivi-shell v2 02/15] ivi application protocol:

2014-03-07 Thread Nobuhiko Tanibata
Add interface ivi_application, which creates ivi_surface objects tied
to a given wl_surface with a given id. The given id can be used in a
shell to identify which application is assigned to a wl_surface and
layout the surface wherever the shell wants. ivi_surface objects can
be used to receive status of wl_surface in the scenegraph of the
compositor.

Signed-off-by: Nobuhiko Tanibata 
---

Changes for v2:
   - Rename "error" to "warning" because meaning of "error" in wayland is fatal.

 protocol/ivi-application.xml | 88 
 1 file changed, 88 insertions(+)
 create mode 100755 protocol/ivi-application.xml

diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml
new file mode 100755
index 000..8659ec6
--- /dev/null
+++ b/protocol/ivi-application.xml
@@ -0,0 +1,88 @@
+
+
+
+
+Copyright (C) 2013 DENSO CORPORATION
+Copyright (c) 2013 BMW Car IT GmbH
+
+Permission is hereby granted, free of charge, to any person obtaining a 
copy
+of this software and associated documentation files (the "Software"), to 
deal
+in the Software without restriction, including without limitation the 
rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+The new visibility state is provided in argument visibility.
+If visibility is 0, the surface has become invisible.
+If visibility is not 0, the surface has become visible.
+
+
+
+
+
+
+
+
+
+
+
+surface_create will create a new surface with surface_id in 
ivi compositor,
+if it does not yet exists. If the surface with surface_id 
already exists in
+ivi compositor, the application content provided in argument 
surface will
+be used as surface content. If an other ivi application 
already registered
+content for surface with surface_id, an warning event will 
indicate the problem.
+
+
+
+
+
+
+
+
+These warning codes define all possible warning codes returned 
by ivi compositor
+on server-side warnings.
+
+
+
+
+
+
+
+The ivi compositor encountered warning while processing a 
request by this
+application. The warning is defined by argument warning_code 
and optional
+warning_text.
+If the application requires to associate this warning event to 
a request,
+it can
+1. send request
+2. force display roundtrip
+3. check, if warning event was received
+ but this restricts the application to have only one open 
request at a time.
+
+
+
+
+
+
+
+
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston] weston-launch: Do not run weston in a shell

2014-03-07 Thread Pekka Paalanen
On Thu,  6 Mar 2014 17:25:49 +0100
Quentin Glidic  wrote:

> From: Quentin Glidic 
> 
> Since 636156d5f693ac5b01cec6a2937d2b6cd4237ea9 it is not needed any
> more to allow the user to pass environment to weston. Actually, the
> login shell is wiping parts of the environment.
> 
> Signed-off-by: Quentin Glidic 
> ---
> 
> Then we should remove the shell invocation alltogether.
> 
> I still need a way to run things at weston’s start and stop,
> but that can wait for another patch.
> 
>  src/weston-launch.c | 12 
>  1 file changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/src/weston-launch.c b/src/weston-launch.c
> index 56e22b1..1f67557 100644
> --- a/src/weston-launch.c
> +++ b/src/weston-launch.c
> @@ -644,16 +644,12 @@ launch_compositor(struct weston_launch *wl, int
> argc, char *argv[]) sigaddset(&mask, SIGINT);
>   sigprocmask(SIG_UNBLOCK, &mask, NULL);
>  
> - child_argv[0] = "/bin/sh";
> - child_argv[1] = "-l";
> - child_argv[2] = "-c";
> - child_argv[3] = BINDIR "/weston \"$@\"";
> - child_argv[4] = "weston";
> + child_argv[0] = BINDIR "/weston";
>   for (i = 0; i < argc; ++i)
> - child_argv[5 + i] = argv[i];
> - child_argv[5 + i] = NULL;
> + child_argv[1 + i] = argv[i];
> + child_argv[1 + i] = NULL;
>  
> - execv(child_argv[0], child_argv);
> + execv("weston", child_argv);
>   error(1, errno, "exec failed");
>  }
>  

Hi,

Quentin pointed out that weston-launch no longer wipes the environment
if ran without -u, so I guess that would be enough to keep my weston
setup running.

I install everything into a $prefix under my homedir, including
libwayland and Mesa, so I need some environment variables to make that
run. I use the same approach when developing for RPi, too.

There was some talk about wiping the environment for Weston in the
future, and starting the clients through a freshly initialized user
shell. In such case, we would need something like a minimal environment
setup compiled into weston-launch binary, set during ./configure or
something.

I thought I'd mention this, since I have interest in keeping my
development environment running without running everything as root. I
also have not migrated my workstation to systemd yet, nor is Raspbian,
so the logind integration doesn't help me.


Thanks,
pq
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 13/15] clients: add presentation-shm demo

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

This started as a copy of simple-shm.c before it was converted to
xdg_shell.

This demo excercises the presentation feedback interface in three
different mode:

- A continuous repaint loop triggered by frame callbacks, and using
  immediate commits, just gathering presentation feedback and computing
  some time intervals for statistics.

- A burst mode, where it queues around 60 frames, and manages to sleep
  without any Wayland protocol traffic for around 1 second on a 60 Hz
  display while still animating continuously, until it needs to send
  the next burst.

- A burst mode with presentation feedback for every frame.

In all modes, all frames are pre-rendered at startup, so no rendering
happens during the animation.

By default, queueing the frames happens in random order, to test the
compositor's ability to order queued updates by the timestamp.

The target timestamps for queued frames are produced by a trivial
algorithm, without any attempt to explicitly and quickly synchronize to
the refresh cycle.

Signed-off-by: Pekka Paalanen 
---
 .gitignore |   1 +
 Makefile.am|   8 +
 clients/presentation-shm.c | 929 +
 3 files changed, 938 insertions(+)
 create mode 100644 clients/presentation-shm.c

diff --git a/.gitignore b/.gitignore
index e0a73c0..851e205 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@ weston-gears
 weston-image
 weston-nested
 weston-nested-client
+weston-presentation-shm
 weston-resizor
 weston-scaler
 weston-simple-egl
diff --git a/Makefile.am b/Makefile.am
index 79e6a7d..753e8b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -377,6 +377,7 @@ if BUILD_SIMPLE_CLIENTS
 demo_clients +=\
weston-simple-shm   \
weston-simple-touch \
+   weston-presentation-shm \
weston-multi-resource
 
 weston_simple_shm_SOURCES = clients/simple-shm.c
@@ -390,6 +391,13 @@ weston_simple_touch_SOURCES = clients/simple-touch.c
 weston_simple_touch_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
 weston_simple_touch_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la
 
+weston_presentation_shm_SOURCES = clients/presentation-shm.c
+nodist_weston_presentation_shm_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
+weston_presentation_shm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
+weston_presentation_shm_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la
+
 weston_multi_resource_SOURCES = clients/multi-resource.c
 weston_multi_resource_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
 weston_multi_resource_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la -lm
diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
new file mode 100644
index 000..612312d
--- /dev/null
+++ b/clients/presentation-shm.c
@@ -0,0 +1,929 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../shared/os-compatibility.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+enum run_mode {
+   RUN_MODE_BURST,
+   RUN_MODE_FEEDBACK,
+   RUN_MODE_QUEUE_FEEDBACK,
+};
+
+struct output {
+   struct wl_output *output;
+   uint32_t name;
+   struct wl_list link;
+};
+
+struct display {
+   struct wl_display *display;
+   struct wl_registry *registry;
+   struct wl_compositor *compositor;
+   struct wl_shell *shell;
+
+   struct wl_shm *shm;
+   uint32_t formats;
+
+   struct presentatio

[RFCv3 weston 11/15] compositor-drm: deliver frame seq for feedback

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Add 'msc' field to weston_output to maintain the refresh counter, and
use it in presentation_feedback.presented.

Make compositor-drm update the per-output refresh counter with the
values reported by DRM. If the DRM reported value jumps backwards,
assume it wrapped around once.

Other backends do not update weston_output::msc, and there
presentation_feedback will always deliver refresh counter as zero.

Signed-off-by: Pekka Paalanen 
---
 src/compositor-drm.c | 14 ++
 src/compositor.c |  2 +-
 src/compositor.h |  1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 533eb0e..aac3d1d 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -712,6 +712,17 @@ finish_frame:
 }
 
 static void
+drm_output_update_msc(struct drm_output *output, unsigned int seq)
+{
+   uint64_t msc_hi = output->base.msc >> 32;
+
+   if (seq < (output->base.msc & 0x))
+   msc_hi++;
+
+   output->base.msc = (msc_hi << 32) + seq;
+}
+
+static void
 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
   void *data)
 {
@@ -719,6 +730,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
struct drm_output *output = s->output;
struct timespec ts;
 
+   drm_output_update_msc(output, frame);
output->vblank_pending = 0;
 
drm_output_release_fb(output, s->current);
@@ -742,6 +754,8 @@ page_flip_handler(int fd, unsigned int frame,
struct drm_output *output = (struct drm_output *) data;
struct timespec ts;
 
+   drm_output_update_msc(output, frame);
+
/* We don't set page_flip_pending on start_repaint_loop, in that case
 * we just want to page flip to the current buffer to get an accurate
 * timestamp */
diff --git a/src/compositor.c b/src/compositor.c
index c11e82b..c05167d 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1901,7 +1901,7 @@ weston_output_finish_frame(struct weston_output *output,
refresh_nsec = 1UL / output->current_mode->refresh;
weston_presentation_feedback_present_list(&output->feedback_list,
  output, refresh_nsec, stamp,
- 0);
+ output->msc);
 
output->frame_time = stamp->tv_sec * 1000 + stamp->tv_nsec / 100;
 
diff --git a/src/compositor.h b/src/compositor.h
index 0dcc414..c94f836 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -198,6 +198,7 @@ struct weston_output {
struct wl_signal move_signal;
int move_x, move_y;
uint32_t frame_time; /* presentation timestamp in milliseconds */
+   uint64_t msc;/* media stream counter */
int disable_planes;
int destroying;
struct wl_list feedback_list;
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 09/15] compositor: set and use the presentation clock everywhere

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Add presentation clock setters that verify the given clock actually
works. Offer an automatic choice of a software fallback clock, when a
backend has to always use clock_gettime() to approximate the
presentation time.

The DRM backend already queried the DRM about the clock id, just let the
DRM backend set the presentation clock from that.

For all other backends which do not get a timestamp from the driver,
call the software clock setter to choose a suitable clock.

Report the chosen clock via presentation.clock_id event to clients.

In finish_frame(), upgrade the argument from uint32_t milliseconds to
struct timespec which can accurately hold the presentation clock values.
This will be needed when weston_output_finish_frame() starts to send out
presentation_feedback.presented events.

While at it, replace gettimeofday() calls with clock_gettime() using the
chosen presentation clock, so we manufacture presentation timestamps
from the presentation clock when the gfx drivers cannot give us a proper
timestamp.

Rpi patch is more verbose due to not having the compositor pointer
available in rpi_flippipe_update_complete(). Explicitly carry the clock
id with flippipe so it is available in the thread.

Signed-off-by: Pekka Paalanen 
---
 src/compositor-drm.c  | 32 +++
 src/compositor-fbdev.c| 12 ---
 src/compositor-headless.c | 11 ---
 src/compositor-rdp.c  | 11 ---
 src/compositor-rpi.c  | 48 ++--
 src/compositor-wayland.c  | 11 +--
 src/compositor-x11.c  | 11 ---
 src/compositor.c  | 79 ++-
 src/compositor.h  | 14 +++--
 9 files changed, 160 insertions(+), 69 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 71c4812..533eb0e 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -106,7 +106,6 @@ struct drm_compositor {
 
uint32_t prev_state;
 
-   clockid_t clock;
struct udev_input input;
 };
 
@@ -686,7 +685,6 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
struct drm_compositor *compositor = (struct drm_compositor *)
output_base->compositor;
uint32_t fb_id;
-   uint32_t msec;
struct timespec ts;
 
if (output->destroy_pending)
@@ -709,9 +707,8 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
 
 finish_frame:
/* if we cannot page-flip, immediately finish frame */
-   clock_gettime(compositor->clock, &ts);
-   msec = ts.tv_sec * 1000 + ts.tv_nsec / 100;
-   weston_output_finish_frame(output_base, msec);
+   clock_gettime(compositor->base.presentation_clock, &ts);
+   weston_output_finish_frame(output_base, &ts);
 }
 
 static void
@@ -720,7 +717,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
 {
struct drm_sprite *s = (struct drm_sprite *)data;
struct drm_output *output = s->output;
-   uint32_t msecs;
+   struct timespec ts;
 
output->vblank_pending = 0;
 
@@ -729,8 +726,9 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
s->next = NULL;
 
if (!output->page_flip_pending) {
-   msecs = sec * 1000 + usec / 1000;
-   weston_output_finish_frame(&output->base, msecs);
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(&output->base, &ts);
}
 }
 
@@ -742,7 +740,7 @@ page_flip_handler(int fd, unsigned int frame,
  unsigned int sec, unsigned int usec, void *data)
 {
struct drm_output *output = (struct drm_output *) data;
-   uint32_t msecs;
+   struct timespec ts;
 
/* We don't set page_flip_pending on start_repaint_loop, in that case
 * we just want to page flip to the current buffer to get an accurate
@@ -758,8 +756,9 @@ page_flip_handler(int fd, unsigned int frame,
if (output->destroy_pending)
drm_output_destroy(&output->base);
else if (!output->vblank_pending) {
-   msecs = sec * 1000 + usec / 1000;
-   weston_output_finish_frame(&output->base, msecs);
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(&output->base, &ts);
 
/* We can't call this from frame_notify, because the output's
 * repaint needed flag is cleared just after that */
@@ -1265,6 +1264,7 @@ init_drm(struct drm_compositor *ec, struct udev_device 
*device)
const char *filename, *sysnum;
uint64_t cap;
int fd, ret;
+   clockid_t clk_id;
 
sysnum = udev_device_get_sysnum(device);
if (sysnum)
@@ -1290,9 +1290,15 @@ init_drm(struct drm_compositor *ec, struct udev_device 
*device)
 
ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
if

[RFCv3 weston 07/15] compositor: add stub implementation of presentation interface

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

You can bind to the global interface, and it delivers a fake clock id.
All requests on it raise an error.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 70 +++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/src/compositor.c b/src/compositor.c
index 16b9b57..cd07a0d 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1,7 +1,7 @@
 /*
  * Copyright © 2010-2011 Intel Corporation
  * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2012 Collabora, Ltd.
+ * Copyright © 2012-2014 Collabora, Ltd.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation for any purpose is hereby granted without fee, provided
@@ -54,6 +54,7 @@
 
 #include "compositor.h"
 #include "scaler-server-protocol.h"
+#include "presentation_timing-server-protocol.h"
 #include "../shared/os-compatibility.h"
 #include "git-version.h"
 #include "version.h"
@@ -3475,6 +3476,69 @@ bind_scaler(struct wl_client *client,
 }
 
 static void
+presentation_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+presentation_feedback(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface,
+ uint32_t callback)
+{
+   wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_METHOD,
+  "presentation_feedback unimplemented");
+}
+
+static void
+presentation_queue(struct wl_client *client,
+  struct wl_resource *resource,
+  struct wl_resource *surface,
+  uint32_t tv_sec_hi,
+  uint32_t tv_sec_lo,
+  uint32_t tv_nsec)
+{
+   wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_METHOD,
+  "presentation_queue unimplemented");
+}
+
+static void
+presentation_discard_queue(struct wl_client *client,
+  struct wl_resource *resource,
+  struct wl_resource *surface)
+{
+   wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_METHOD,
+  "presentation_discard_queue unimplemented");
+}
+
+static const struct presentation_interface presentation_implementation = {
+   presentation_destroy,
+   presentation_feedback,
+   presentation_queue,
+   presentation_discard_queue
+};
+
+static void
+bind_presentation(struct wl_client *client,
+ void *data, uint32_t version, uint32_t id)
+{
+   struct weston_compositor *compositor = data;
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &presentation_interface,
+ MIN(version, 1), id);
+   if (resource == NULL) {
+   wl_client_post_no_memory(client);
+   return;
+   }
+
+   wl_resource_set_implementation(resource, &presentation_implementation,
+  compositor, NULL);
+   presentation_send_clock_id(resource, CLOCK_MONOTONIC);
+}
+
+static void
 compositor_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
 {
@@ -3568,6 +3632,10 @@ weston_compositor_init(struct weston_compositor *ec,
  ec, bind_scaler))
return -1;
 
+   if (!wl_global_create(ec->wl_display, &presentation_interface, 1,
+ ec, bind_presentation))
+   return -1;
+
wl_list_init(&ec->view_list);
wl_list_init(&ec->plane_list);
wl_list_init(&ec->layer_list);
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 14/15] protocol: add scaler TODO

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

These changes are needed by the queueing in Presentation extension.
---
 protocol/scaler.xml | 4 
 src/compositor.c| 3 +++
 2 files changed, 7 insertions(+)

diff --git a/protocol/scaler.xml b/protocol/scaler.xml
index dfe44b8..f3a7232 100644
--- a/protocol/scaler.xml
+++ b/protocol/scaler.xml
@@ -142,6 +142,10 @@
arguments to wl_surface.attach. The x, y, dst_width, and dst_height
define the surface-local coordinate system irrespective of the
attached wl_buffer size.
+
+   XXX TODO: we need separate requests for src and dst variables,
+   maybe even three: src x,y; src w,h; dst w,h. Define what happens
+   when only src or dst is set.
   
 
   
diff --git a/src/compositor.c b/src/compositor.c
index 00213d4..2e5e6d8 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3862,6 +3862,9 @@ viewport_set(struct wl_client *client,
struct weston_surface *surface =
wl_resource_get_user_data(resource);
 
+   /* XXX TODO: split wl_viewport.set into separate dst and src
+* requests */
+
assert(surface->viewport_resource != NULL);
 
if (wl_fixed_to_double(src_width) < 0 ||
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 10/15] compositor: implement presentation_feedback

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Implement the presentation.feedback request, and the
presentation_feedback protocol interface. Feedback information is
delivered to clients as the backend reports it, except the refresh
counter (MSC) which is always reported as zero.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 170 +--
 src/compositor.h |   8 +++
 2 files changed, 174 insertions(+), 4 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index f1029ef..c11e82b 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -418,6 +418,7 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->views);
 
wl_list_init(&surface->frame_callback_list);
+   wl_list_init(&surface->feedback_list);
 
surface->pending.buffer_destroy_listener.notify =
surface_handle_pending_buffer_destroy;
@@ -425,6 +426,7 @@ weston_surface_create(struct weston_compositor *compositor)
pixman_region32_init(&surface->pending.opaque);
region_init_infinite(&surface->pending.input);
wl_list_init(&surface->pending.frame_callback_list);
+   wl_list_init(&surface->pending.feedback_list);
 
wl_list_init(&surface->subsurface_list);
wl_list_init(&surface->subsurface_list_pending);
@@ -1334,6 +1336,74 @@ struct weston_frame_callback {
struct wl_list link;
 };
 
+struct weston_presentation_feedback {
+   struct wl_resource *resource;
+
+   /* XXX: could use just wl_resource_get_link() instead */
+   struct wl_list link;
+};
+
+static void
+weston_presentation_feedback_discard(
+   struct weston_presentation_feedback *feedback)
+{
+   presentation_feedback_send_discarded(feedback->resource);
+   wl_list_remove(&feedback->link);
+   wl_list_init(&feedback->link);
+}
+
+static void
+weston_presentation_feedback_discard_list(struct wl_list *list)
+{
+   struct weston_presentation_feedback *feedback, *tmp;
+
+   wl_list_for_each_safe(feedback, tmp, list, link)
+   weston_presentation_feedback_discard(feedback);
+}
+
+static void
+weston_presentation_feedback_present(
+   struct weston_presentation_feedback *feedback,
+   struct weston_output *output,
+   uint32_t refresh_nsec,
+   const struct timespec *ts,
+   uint64_t seq)
+{
+   struct wl_client *client = wl_resource_get_client(feedback->resource);
+   struct wl_resource *o;
+   uint64_t secs;
+
+   wl_resource_for_each(o, &output->resource_list) {
+   if (wl_resource_get_client(o) != client)
+   continue;
+
+   presentation_feedback_send_sync_output(feedback->resource, o);
+   }
+
+   secs = ts->tv_sec;
+   presentation_feedback_send_presented(feedback->resource,
+secs >> 32, secs & 0x,
+ts->tv_nsec,
+refresh_nsec,
+seq >> 32, seq & 0x);
+   wl_list_remove(&feedback->link);
+   wl_list_init(&feedback->link);
+}
+
+static void
+weston_presentation_feedback_present_list(struct wl_list *list,
+ struct weston_output *output,
+ uint32_t refresh_nsec,
+ const struct timespec *ts,
+ uint64_t seq)
+{
+   struct weston_presentation_feedback *feedback, *tmp;
+
+   wl_list_for_each_safe(feedback, tmp, list, link)
+   weston_presentation_feedback_present(feedback, output,
+refresh_nsec, ts, seq);
+}
+
 WL_EXPORT void
 weston_view_destroy(struct weston_view *view)
 {
@@ -1380,6 +1450,9 @@ weston_surface_destroy(struct weston_surface *surface)
  &surface->pending.frame_callback_list, link)
wl_resource_destroy(cb->resource);
 
+   weston_presentation_feedback_discard_list(
+   &surface->pending.feedback_list);
+
pixman_region32_fini(&surface->pending.input);
pixman_region32_fini(&surface->pending.opaque);
pixman_region32_fini(&surface->pending.damage);
@@ -1396,6 +1469,8 @@ weston_surface_destroy(struct weston_surface *surface)
wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
wl_resource_destroy(cb->resource);
 
+   weston_presentation_feedback_discard_list(&surface->feedback_list);
+
free(surface);
 }
 
@@ -1497,6 +1572,7 @@ weston_surface_attach(struct weston_surface *surface,
surface->compositor->renderer->attach(surface, buffer);
 
weston_surface_set_size_from_buffer(surface);
+   weston_presentation_feedback_discard_list(&surface->feedback_list);
 }
 
 WL_EXPORT void
@

[RFCv3 weston 12/15] compositor: implement presentation.queue

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Implement the queueing and queue processing of the Presentation
extension.

Every weston_surface (wl_surface) has a queue_list, which is ordered by
the target presentation timestamp of the queued updates. A
wl_surface.commit following a presentation.queue will trigger queueing
instead of a normal commit.

The buffer_viewport handling is changed to match the Presentation
specification.

In output repaint, the compositor predicts when the current repaint
would hit the screen, based on the previous repaint's timestamp.
The DRM vblank events carry a timestamp for the start of the active
period, but they can be emitted earlier. This can make it look like the
previous presentation finished in the future. This is dealt with by
using proper rounding, and allowing timestamps that are at most 1 cycle
in the future in weston_output_predict_presentation.

The weston_surface::queue_list is processed during output repaint if the
weston_surface's main output is the one being repainted. An update from
the queue is applied according to the target timestamp, and earlier
updates are discarded.

The compositor will keep on repainting if there are any queued updates
still existing in the weston_surfaces that have been processed by output
repaint. Surfaces that are not part of the repaint will not
automatically schedule a new repaint based on the queue; instead it is
assumed that a repaint is scheduled when such a surface enters the
repainted set of surfaces. A client queueing an update will also cause a
repaint to be scheduled, to ensure the queue will get processed if the
surface is on an output.

As the realized presentation timestamp is available only after output
repaint, updating all relevant surface timestamps would require a
per-output list of weston_surfaces. Instead, weston_surfaces hold a
reference to a weston_timestamp, which then gets the realized
presentation timestamp in finish_frame(). The surface's
presentation_time is used to discard queued updates that would replace
the current content with an older content.

Frame callbacks are not queued. A queueing commit does not touch any
pending frame callbacks.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 436 +++
 src/compositor.h |  18 +++
 2 files changed, 426 insertions(+), 28 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index c05167d..00213d4 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -344,6 +344,58 @@ region_init_infinite(pixman_region32_t *region)
  UINT32_MAX, UINT32_MAX);
 }
 
+struct weston_timestamp {
+   int ref_count;
+   struct timespec stamp;
+};
+
+static struct weston_timestamp *
+weston_timestamp_ref(struct weston_timestamp *ts)
+{
+   ++ts->ref_count;
+   return ts;
+}
+
+static struct weston_timestamp *
+weston_timestamp_create(void)
+{
+   struct weston_timestamp *ts;
+
+   ts = malloc(sizeof *ts);
+   if (!ts)
+   return NULL;
+
+   ts->ref_count = 1;
+   ts->stamp.tv_sec = 0;
+   ts->stamp.tv_nsec = -1;
+
+   return ts;
+}
+
+static void
+weston_timestamp_unref(struct weston_timestamp *ts)
+{
+   if (!ts)
+   return;
+
+   if (--ts->ref_count)
+   return;
+
+   free(ts);
+}
+
+static const struct timespec *
+weston_timestamp_get_time(const struct weston_timestamp *ts)
+{
+   if (!ts)
+   return NULL;
+
+   if (ts->stamp.tv_nsec < 0)
+   return NULL;
+
+   return &ts->stamp;
+}
+
 static struct weston_subsurface *
 weston_surface_to_subsurface(struct weston_surface *surface);
 
@@ -427,10 +479,13 @@ weston_surface_create(struct weston_compositor 
*compositor)
region_init_infinite(&surface->pending.input);
wl_list_init(&surface->pending.frame_callback_list);
wl_list_init(&surface->pending.feedback_list);
+   surface->pending.target_timestamp.tv_nsec = -1;
 
wl_list_init(&surface->subsurface_list);
wl_list_init(&surface->subsurface_list_pending);
 
+   wl_list_init(&surface->queue_list);
+
return surface;
 }
 
@@ -1404,6 +1459,182 @@ weston_presentation_feedback_present_list(struct 
wl_list *list,
 refresh_nsec, ts, seq);
 }
 
+struct weston_queued_update {
+   struct wl_list queue_link;
+   struct timespec timestamp;
+   struct weston_buffer_reference buffer_ref;
+   struct wl_list feedback_list;
+   struct weston_buffer_viewport buffer_viewport;
+};
+
+#define NSEC_PER_SEC 10
+#define ONE_PER_PICO 1
+
+static int
+timespec_cmp(const struct timespec *a, const struct timespec *b)
+{
+   assert(a->tv_nsec >= 0 && a->tv_nsec < NSEC_PER_SEC);
+   assert(b->tv_nsec >= 0 && b->tv_nsec < NSEC_PER_SEC);
+
+   if (a->tv_sec < b->tv_sec)
+   return -1;
+
+   if (a->tv_sec > b->tv_sec)
+   return 1;
+
+ 

[RFCv3 weston 15/15] compositor: add presentation debug functions

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

These are to be enabled by a developer as needed. They helped to track
down a problem, where the prediction was deemed practically perfect but
feedback was sent on the frame after, leading to incorrect feedback that
looked like all queued updates were always one frame late.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/src/compositor.c b/src/compositor.c
index 2e5e6d8..0da8d71 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1470,6 +1470,30 @@ struct weston_queued_update {
 #define NSEC_PER_SEC 10
 #define ONE_PER_PICO 1
 
+static void
+debug_weston_surface_queue_process(const struct timespec *cutoff,
+  const struct timespec *target,
+  const struct timespec *current,
+  struct weston_queued_update *update)
+{
+#if 0
+   struct weston_presentation_feedback *feedback;
+
+   fprintf(stderr, "cutoff %ld.%09ld, target %ld.%09ld, "
+   "current %ld.%09ld, update %ld.%09ld, feedbacks:",
+   (long)cutoff->tv_sec, (long)cutoff->tv_nsec,
+   (long)target->tv_sec, (long)target->tv_nsec,
+   current ? (long)current->tv_sec : -1,
+   current ? (long)current->tv_nsec : 0,
+   (long)update->timestamp.tv_sec,
+   (long)update->timestamp.tv_nsec);
+
+   wl_list_for_each(feedback, &update->feedback_list, link)
+   fprintf(stderr, " %d", wl_resource_get_id(feedback->resource));
+   fprintf(stderr, "\n");
+#endif
+}
+
 static int
 timespec_cmp(const struct timespec *a, const struct timespec *b)
 {
@@ -1613,6 +1637,7 @@ weston_surface_queue_process(struct weston_surface 
*surface,
 */
 
current = weston_timestamp_get_time(surface->presentation_time);
+   debug_weston_surface_queue_process(cutoff, target, current, update);
if (!current)
current = target;
 
@@ -2043,6 +2068,18 @@ weston_compositor_build_view_list(struct 
weston_compositor *compositor)
 }
 
 static void
+debug_weston_output_predict_presentation(const struct timespec *now,
+const struct timespec *last,
+int64_t inc)
+{
+#if 0
+   fprintf(stderr, "\nnow %ld.%09ld, last finish %ld.%09ld, "
+   "inc %" PRIi64 "\n", (long)now->tv_sec, (long)now->tv_nsec,
+   (long)last->tv_sec, (long)last->tv_nsec, inc);
+#endif
+}
+
+static void
 timespec_add_nsec(struct timespec *result,
  const struct timespec *base, int64_t ns)
 {
@@ -2086,6 +2123,8 @@ weston_output_predict_presentation(struct weston_output 
*output,
 
inc = timespec_diff_to_cycles_floor(now, &output->last_finish_time,
output->current_mode->refresh);
+   debug_weston_output_predict_presentation(now, &output->last_finish_time,
+inc);
 
if (inc < -1)
weston_log("warning in %s: inc = %" PRIi64
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 04/15] compositor: reorganize struct weston_buffer_viewport

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Queueing in the Presentation extension requires splitting the viewport
state into buffer state and surface state. To conveniently allow
assigning only one, the other, or both, reorganize the
weston_buffer_viewport structure.

Signed-off-by: Pekka Paalanen 
---
 desktop-shell/shell.c |  6 ++---
 src/compositor-drm.c  | 12 +
 src/compositor.c  | 70 ++-
 src/compositor.h  | 27 
 src/gl-renderer.c |  2 +-
 src/pixman-renderer.c | 25 +-
 6 files changed, 76 insertions(+), 66 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index fd9ead0..7f28f07 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -2659,11 +2659,11 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
if (shell_surface_is_top_fullscreen(shsurf)) {
struct weston_mode mode = {0,
-   surf_width * surface->buffer_viewport.scale,
-   surf_height * surface->buffer_viewport.scale,
+   surf_width * 
surface->buffer_viewport.buffer.scale,
+   surf_height * 
surface->buffer_viewport.buffer.scale,
shsurf->fullscreen.framerate};
 
-   if (weston_output_switch_mode(output, &mode, 
surface->buffer_viewport.scale,
+   if (weston_output_switch_mode(output, &mode, 
surface->buffer_viewport.buffer.scale,
WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) 
{
weston_view_set_position(shsurf->view,
 output->x - surf_x,
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index e45f47d..71c4812 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -456,6 +456,7 @@ drm_output_prepare_scanout_view(struct weston_output 
*_output,
struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor;
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
+   struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
struct gbm_bo *bo;
uint32_t format;
 
@@ -464,7 +465,7 @@ drm_output_prepare_scanout_view(struct weston_output 
*_output,
buffer == NULL || c->gbm == NULL ||
buffer->width != output->base.current_mode->width ||
buffer->height != output->base.current_mode->height ||
-   output->base.transform != ev->surface->buffer_viewport.transform ||
+   output->base.transform != viewport->buffer.transform ||
ev->transform.enabled)
return NULL;
 
@@ -809,6 +810,7 @@ drm_output_prepare_overlay_view(struct weston_output 
*output_base,
 {
struct weston_compositor *ec = output_base->compositor;
struct drm_compositor *c =(struct drm_compositor *) ec;
+   struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
struct drm_sprite *s;
int found = 0;
struct gbm_bo *bo;
@@ -820,10 +822,10 @@ drm_output_prepare_overlay_view(struct weston_output 
*output_base,
if (c->gbm == NULL)
return NULL;
 
-   if (ev->surface->buffer_viewport.transform != output_base->transform)
+   if (viewport->buffer.transform != output_base->transform)
return NULL;
 
-   if (ev->surface->buffer_viewport.scale != output_base->current_scale)
+   if (viewport->buffer.scale != output_base->current_scale)
return NULL;
 
if (c->sprites_are_broken)
@@ -933,8 +935,8 @@ drm_output_prepare_overlay_view(struct weston_output 
*output_base,
 
tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width),
   wl_fixed_from_int(ev->surface->height),
-  ev->surface->buffer_viewport.transform,
-  ev->surface->buffer_viewport.scale,
+  viewport->buffer.transform,
+  viewport->buffer.scale,
   tbox);
 
s->src_x = tbox.x1 << 8;
diff --git a/src/compositor.c b/src/compositor.c
index e1d6df1..f204a6d 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -400,9 +400,9 @@ weston_surface_create(struct weston_compositor *compositor)
surface->compositor = compositor;
surface->ref_count = 1;
 
-   surface->buffer_viewport.transform = WL_OUTPUT_TRANSFORM_NORMAL;
-   surface->buffer_viewport.scale = 1;
-   surface->buffer_viewport.viewport_set = 0;
+   surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
+   surface->buffer_viewport.buffer.scale = 1;
+   surface->buffer_viewport.b

[RFCv3 weston 03/15] compositor: refactor code into weston_surface_reset_pending_buffer()

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

No functional changes.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 2911157..e1d6df1 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1312,6 +1312,17 @@ weston_surface_unmap(struct weston_surface *surface)
surface->output = NULL;
 }
 
+static void
+weston_surface_reset_pending_buffer(struct weston_surface *surface)
+{
+   if (surface->pending.buffer)
+   wl_list_remove(&surface->pending.buffer_destroy_listener.link);
+   surface->pending.buffer = NULL;
+   surface->pending.sx = 0;
+   surface->pending.sy = 0;
+   surface->pending.newly_attached = 0;
+}
+
 struct weston_frame_callback {
struct wl_resource *resource;
struct wl_list link;
@@ -2021,12 +2032,7 @@ weston_surface_commit(struct weston_surface *surface)
surface->configure(surface,
   surface->pending.sx, surface->pending.sy);
 
-   if (surface->pending.buffer)
-   wl_list_remove(&surface->pending.buffer_destroy_listener.link);
-   surface->pending.buffer = NULL;
-   surface->pending.sx = 0;
-   surface->pending.sy = 0;
-   surface->pending.newly_attached = 0;
+   weston_surface_reset_pending_buffer(surface);
 
/* wl_surface.damage */
pixman_region32_union(&surface->damage, &surface->damage,
@@ -2317,12 +2323,7 @@ weston_subsurface_commit_to_cache(struct 
weston_subsurface *sub)
sub->cached.sx += surface->pending.sx;
sub->cached.sy += surface->pending.sy;
 
-   if (surface->pending.buffer)
-   wl_list_remove(&surface->pending.buffer_destroy_listener.link);
-   surface->pending.buffer = NULL;
-   surface->pending.sx = 0;
-   surface->pending.sy = 0;
-   surface->pending.newly_attached = 0;
+   weston_surface_reset_pending_buffer(surface);
 
sub->cached.buffer_viewport = surface->pending.buffer_viewport;
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 06/15] protocol: add presentation extension RFC v3

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Add accurate presentation timing features to Wayland: queueing and
feedback.

This specification is based on the draft written by Frederic Plourde
 and redesigned by Pekka Paalanen.

The RFC v2 version is from
http://lists.freedesktop.org/archives/wayland-devel/2014-January/012988.html

Changes in v3:

* associate presentation time to current surface contents

This implements the suggestion from
http://lists.freedesktop.org/archives/wayland-devel/2014-February/013066.html

which prevents surface content from jumping backwards in time if a
client retroactively queues an update with a target time in the past.

* use 64-bit tv_sec in presentation

The time_t type used in struct timespec could be almost anything. POSIX
probably defines it to be an integer, but not the size. Apparently it is
usually 'long', which makes it 64-bit on x86_64.

To be able to fully represent timespec values returned by clock_gettime,
change the protocol to use 64 bits for the tv_sec part.

* define an error for invalid tv_nsec

This allow us to rely on the normalized timestamp form.

* define some interactions with sub-surfaces

Sub-surface cached state updates (synchronized mode) are designed
especially for resizing. As queued updates are not meant to produce any
resizing-like effects, they also do not trigger any sub-surface
operations.

* add sub-headings as xml comments

* queued update cannot map

Because before mapping, the surface has no main output assigned. An
immediate commit is needed anyway, to be able to set all the surface
state, which a queued update cannot touch.

* frame callbacks are not queued

It is not known when queueing frame callbacks would be useful.

Signed-off-by: Pekka Paalanen 
---
 Makefile.am  |   5 +
 protocol/presentation_timing.xml | 434 +++
 2 files changed, 439 insertions(+)
 create mode 100644 protocol/presentation_timing.xml

diff --git a/Makefile.am b/Makefile.am
index 64d0743..998dc54 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,6 +77,8 @@ nodist_weston_SOURCES =   
\
protocol/input-method-server-protocol.h \
protocol/workspaces-protocol.c  \
protocol/workspaces-server-protocol.h   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-server-protocol.h  \
protocol/scaler-protocol.c  \
protocol/scaler-server-protocol.h
 
@@ -416,6 +418,8 @@ nodist_libtoytoolkit_la_SOURCES =   \
protocol/scaler-client-protocol.h   \
protocol/workspaces-protocol.c  \
protocol/workspaces-client-protocol.h   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h  \
protocol/xdg-shell-protocol.c   \
protocol/xdg-shell-client-protocol.h
 
@@ -911,6 +915,7 @@ EXTRA_DIST +=   \
protocol/text-cursor-position.xml   \
protocol/wayland-test.xml   \
protocol/xdg-shell.xml  \
+   protocol/presentation_timing.xml\
protocol/scaler.xml
 
 man_MANS = weston.1 weston.ini.5
diff --git a/protocol/presentation_timing.xml b/protocol/presentation_timing.xml
new file mode 100644
index 000..e191b87
--- /dev/null
+++ b/protocol/presentation_timing.xml
@@ -0,0 +1,434 @@
+
+
+
+
+  
+Copyright © 2013-2014 Collabora, Ltd.
+
+Permission to use, copy, modify, distribute, and sell this
+software and its documentation for any purpose is hereby granted
+without fee, provided that the above copyright notice appear in
+all copies and that both that copyright notice and this permission
+notice appear in supporting documentation, and that the name of
+the copyright holders not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission.  The copyright holders make no
+representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied
+warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+  
+
+  
+
+
+
+
+  The main features of this interface are accurate presentation
+  timing feedback, and queued wl_surface content updates to ensure
+  smooth video playback while maintaining audio/vide

[RFCv3 weston 08/15] weston-info: report presentation clock

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Signed-off-by: Pekka Paalanen 
---
 Makefile.am   |  3 ++
 clients/weston-info.c | 81 +++
 2 files changed, 84 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index 998dc54..79e6a7d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -547,6 +547,9 @@ weston_simple_im_LDADD = $(CLIENT_LIBS)
 weston_simple_im_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
 weston_info_SOURCES = clients/weston-info.c
+nodist_weston_info_SOURCES =   \
+   protocol/presentation_timing-protocol.c \
+   protocol/presentation_timing-client-protocol.h
 weston_info_LDADD = $(WESTON_INFO_LIBS) libshared.la
 weston_info_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
 
diff --git a/clients/weston-info.c b/clients/weston-info.c
index 147dc48..12710a8 100644
--- a/clients/weston-info.c
+++ b/clients/weston-info.c
@@ -27,10 +27,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
 #include "../shared/os-compatibility.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
 
 typedef void (*print_info_t)(void *info);
 typedef void (*destroy_info_t)(void *info);
@@ -92,6 +96,13 @@ struct seat_info {
char *name;
 };
 
+struct presentation_info {
+   struct global_info global;
+   struct presentation *presentation;
+
+   clockid_t clk_id;
+};
+
 struct weston_info {
struct wl_display *display;
struct wl_registry *registry;
@@ -467,6 +478,74 @@ add_output_info(struct weston_info *info, uint32_t id, 
uint32_t version)
 }
 
 static void
+destroy_presentation_info(void *info)
+{
+   struct presentation_info *prinfo = info;
+
+   presentation_destroy(prinfo->presentation);
+}
+
+static const char *
+clock_name(clockid_t clk_id)
+{
+   static const char *names[] = {
+   [CLOCK_REALTIME] =  "CLOCK_REALTIME",
+   [CLOCK_MONOTONIC] = "CLOCK_MONOTONIC",
+   [CLOCK_MONOTONIC_RAW] = "CLOCK_MONOTONIC_RAW",
+   [CLOCK_REALTIME_COARSE] =   "CLOCK_REALTIME_COARSE",
+   [CLOCK_MONOTONIC_COARSE] =  "CLOCK_MONOTONIC_COARSE",
+   [CLOCK_BOOTTIME] =  "CLOCK_BOOTTIME",
+   };
+
+   if (clk_id < 0 || (unsigned)clk_id >= ARRAY_LENGTH(names))
+   return "unknown";
+
+   return names[clk_id];
+}
+
+static void
+print_presentation_info(void *info)
+{
+   struct presentation_info *prinfo = info;
+
+   print_global_info(info);
+
+   printf("\tpresentation clock id: %d (%s)\n",
+   prinfo->clk_id, clock_name(prinfo->clk_id));
+}
+
+static void
+presentation_handle_clock_id(void *data, struct presentation *presentation,
+uint32_t clk_id)
+{
+   struct presentation_info *prinfo = data;
+
+   prinfo->clk_id = clk_id;
+}
+
+static const struct presentation_listener presentation_listener = {
+   presentation_handle_clock_id
+};
+
+static void
+add_presentation_info(struct weston_info *info, uint32_t id, uint32_t version)
+{
+   struct presentation_info *prinfo = xzalloc(sizeof *prinfo);
+
+   init_global_info(info, &prinfo->global, id, "presentation", version);
+   prinfo->global.print = print_presentation_info;
+   prinfo->global.destroy = destroy_presentation_info;
+
+   prinfo->clk_id = -1;
+   prinfo->presentation = wl_registry_bind(info->registry, id,
+   &presentation_interface, 1);
+   presentation_add_listener(prinfo->presentation, &presentation_listener,
+ prinfo);
+
+   info->roundtrip_needed = true;
+}
+
+static void
 destroy_global_info(void *data)
 {
 }
@@ -494,6 +573,8 @@ global_handler(void *data, struct wl_registry *registry, 
uint32_t id,
add_shm_info(info, id, version);
else if (!strcmp(interface, "wl_output"))
add_output_info(info, id, version);
+   else if (!strcmp(interface, "presentation"))
+   add_presentation_info(info, id, version);
else
add_global_info(info, id, interface, version);
 }
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 02/15] compositor: buffer can be non-NULL only if newly_attached

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

There is no need for weston_subsurface_commit_to_cache() to leave the
pending.buffer set. Reset it to NULL.

This makes pending.buffer always NULL if pending.newly_attached == 0.
IOW, pending.buffer cannot be non-NULL unless
pending.newly_attached == 1.

Therefore no need to check pending.buffer nor cached.buffer_ref.buffer
for the weston_surface_attach() calls.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 09e1acb..2911157 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2006,13 +2006,15 @@ weston_surface_commit(struct weston_surface *surface)
struct weston_view *view;
pixman_region32_t opaque;
 
+   /* XXX: wl_viewport.set without an attach should call configure */
+
/* wl_surface.set_buffer_transform */
/* wl_surface.set_buffer_scale */
/* wl_viewport.set */
surface->buffer_viewport = surface->pending.buffer_viewport;
 
/* wl_surface.attach */
-   if (surface->pending.buffer || surface->pending.newly_attached)
+   if (surface->pending.newly_attached)
weston_surface_attach(surface, surface->pending.buffer);
 
if (surface->configure && surface->pending.newly_attached)
@@ -2236,7 +2238,7 @@ weston_subsurface_commit_from_cache(struct 
weston_subsurface *sub)
surface->buffer_viewport = sub->cached.buffer_viewport;
 
/* wl_surface.attach */
-   if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached)
+   if (sub->cached.newly_attached)
weston_surface_attach(surface, sub->cached.buffer_ref.buffer);
weston_buffer_reference(&sub->cached.buffer_ref, NULL);
 
@@ -2314,6 +2316,10 @@ weston_subsurface_commit_to_cache(struct 
weston_subsurface *sub)
}
sub->cached.sx += surface->pending.sx;
sub->cached.sy += surface->pending.sy;
+
+   if (surface->pending.buffer)
+   wl_list_remove(&surface->pending.buffer_destroy_listener.link);
+   surface->pending.buffer = NULL;
surface->pending.sx = 0;
surface->pending.sy = 0;
surface->pending.newly_attached = 0;
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 05/15] compositor: replace weston_buffer_viewport::viewport_set

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Remove the explicit boolean variable, and use illegal width to denote
"not set".

Split the boolean into two, so we can later start having buffer.src_*
and surface.* set or not set independently. This may become useful when
the wl_viewport interface is changed to allow modifying them separately.

At the moment, both buffer.src_width and surface.width conditions are
always in sync.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c  | 15 +--
 src/compositor.h  | 12 +++-
 src/pixman-renderer.c |  3 ++-
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index f204a6d..16b9b57 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -402,7 +402,8 @@ weston_surface_create(struct weston_compositor *compositor)
 
surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
surface->buffer_viewport.buffer.scale = 1;
-   surface->buffer_viewport.buffer.viewport_set = 0;
+   surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
+   surface->buffer_viewport.surface.width = -1;
surface->pending.buffer_viewport = surface->buffer_viewport;
surface->output = NULL;
surface->pending.newly_attached = 0;
@@ -641,7 +642,8 @@ scaler_surface_to_buffer(struct weston_surface *surface,
 {
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
 
-   if (vp->buffer.viewport_set) {
+   if (vp->buffer.src_width != wl_fixed_from_int(-1) &&
+   vp->surface.width != -1) {
double a, b;
 
a = sx / vp->surface.width;
@@ -1204,7 +1206,8 @@ weston_surface_set_size_from_buffer(struct weston_surface 
*surface)
return;
}
 
-   if (vp->buffer.viewport_set) {
+   if (vp->buffer.src_width != wl_fixed_from_int(-1) &&
+   vp->surface.width != -1) {
surface->width = vp->surface.width;
surface->height = vp->surface.height;
return;
@@ -3355,7 +3358,9 @@ destroy_viewport(struct wl_resource *resource)
wl_resource_get_user_data(resource);
 
surface->viewport_resource = NULL;
-   surface->pending.buffer_viewport.buffer.viewport_set = 0;
+   surface->pending.buffer_viewport.buffer.src_width =
+   wl_fixed_from_int(-1);
+   surface->pending.buffer_viewport.surface.width = -1;
 }
 
 static void
@@ -3398,8 +3403,6 @@ viewport_set(struct wl_client *client,
return;
}
 
-   surface->pending.buffer_viewport.buffer.viewport_set = 1;
-
surface->pending.buffer_viewport.buffer.src_x = src_x;
surface->pending.buffer_viewport.buffer.src_y = src_y;
surface->pending.buffer_viewport.buffer.src_width = src_width;
diff --git a/src/compositor.h b/src/compositor.h
index f1f126b..d2afacd 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -662,16 +662,18 @@ struct weston_buffer_viewport {
/* wl_surface.set_scaling_factor */
int32_t scale;
 
-   /* bool for whether wl_viewport.set has been
-* called yet (before this is called there is no
-* cropping or scaling on the surface) */
-   int viewport_set; /* bool */
-
+   /*
+* If src_width != wl_fixed_from_int(-1),
+* then and only then src_* are used.
+*/
wl_fixed_t src_x, src_y;
wl_fixed_t src_width, src_height;
} buffer;
 
struct {
+   /*
+* If width == -1, the size is inferred from the buffer.
+*/
int32_t width, height;
} surface;
 };
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index 4849155..ee28e45 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -258,7 +258,8 @@ repaint_region(struct weston_view *ev, struct weston_output 
*output,
   pixman_double_to_fixed 
((double)-ev->geometry.y));
}
 
-   if (vp->buffer.viewport_set) {
+   if (vp->buffer.src_width != wl_fixed_from_int(-1) &&
+   vp->surface.width != -1) {
double viewport_x, viewport_y, viewport_width, viewport_height;
double ratio_x, ratio_y;
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 01/15] compositor: refactor more into weston_surface_attach

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Merge more code into a common function. No functional changes.

Signed-off-by: Pekka Paalanen 
---
 src/compositor.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 7c29d51..09e1acb 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1478,6 +1478,8 @@ weston_surface_attach(struct weston_surface *surface,
}
 
surface->compositor->renderer->attach(surface, buffer);
+
+   weston_surface_set_size_from_buffer(surface);
 }
 
 WL_EXPORT void
@@ -2010,10 +2012,8 @@ weston_surface_commit(struct weston_surface *surface)
surface->buffer_viewport = surface->pending.buffer_viewport;
 
/* wl_surface.attach */
-   if (surface->pending.buffer || surface->pending.newly_attached) {
+   if (surface->pending.buffer || surface->pending.newly_attached)
weston_surface_attach(surface, surface->pending.buffer);
-   weston_surface_set_size_from_buffer(surface);
-   }
 
if (surface->configure && surface->pending.newly_attached)
surface->configure(surface,
@@ -2236,10 +2236,8 @@ weston_subsurface_commit_from_cache(struct 
weston_subsurface *sub)
surface->buffer_viewport = sub->cached.buffer_viewport;
 
/* wl_surface.attach */
-   if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached) {
+   if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached)
weston_surface_attach(surface, sub->cached.buffer_ref.buffer);
-   weston_surface_set_size_from_buffer(surface);
-   }
weston_buffer_reference(&sub->cached.buffer_ref, NULL);
 
if (surface->configure && sub->cached.newly_attached)
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[RFCv3 weston 00/15] Wayland Presentation extension

2014-03-07 Thread Pekka Paalanen
From: Pekka Paalanen 

Hi all,

here is the third RFC of the Wayland Presentation protocol, now
with a complete implementation!

RFCv2 can be found at
http://lists.freedesktop.org/archives/wayland-devel/2014-January/012988.html
and the email thread contains extensive discussion, from which
the conclusions have been implemented. Let me know, if I missed
something.

The changes to the protocol itself are listed in patch 6/15. I
have not forgot about the new features listed in
http://cgit.collabora.com/git/user/pq/weston.git/tree/buffer-queue3.txt?h=buffer-queue-spec
and I intend to write a protocol patch to get the discussion
about those started.

The impact to the Wayland core protocol still exists, but is
mitigated by the fact that frame callbacks are no longer queued,
and hence whether there is an attach or not does not affect the
processing of frame callbacks on commit.

Still, doing an immediate commit without a preceding
wl_surface.attach is defined to work differently than in the
core: the buffer state will not be applied without an attach.
IOW, you cannot change e.g. buffer_scale without attaching a
wl_buffer. In my opinion, the newly disabled actions did not make
sense in the first place, but it is still a change to the core
protocol.

Kristian, patches 1-5 are clean-ups and refactoring to prepare
for the Presentation extension. If you like where this is going,
you could merge those already.

Patch 6 adds the protocol, patches 7 and 9-12 implement the
extension, patches 8 and 13 add clients to test the extensions,
and patch 14 serves as a reminder that I still intend to change
the wl_viewport interface.

Do we want things like patch 15 in Weston?

This whole patch set is available at
http://cgit.collabora.com/git/user/pq/weston.git/log/?h=presentation-RFCv3
  git://git.collabora.co.uk/git/user/pq/weston.git presentation-RFCv3

Pekka Paalanen (15):
  compositor: refactor more into weston_surface_attach
  compositor: buffer can be non-NULL only if newly_attached
  compositor: refactor code into weston_surface_reset_pending_buffer()
  compositor: reorganize struct weston_buffer_viewport
  compositor: replace weston_buffer_viewport::viewport_set
  protocol: add presentation extension RFC v3
  compositor: add stub implementation of presentation interface
  weston-info: report presentation clock
  compositor: set and use the presentation clock everywhere
  compositor: implement presentation_feedback
  compositor-drm: deliver frame seq for feedback
  compositor: implement presentation.queue
  clients: add presentation-shm demo
  protocol: add scaler TODO
  compositor: add presentation debug functions

 .gitignore   |   1 +
 Makefile.am  |  16 +
 clients/presentation-shm.c   | 929 +++
 clients/weston-info.c|  81 
 desktop-shell/shell.c|   6 +-
 protocol/presentation_timing.xml | 434 ++
 protocol/scaler.xml  |   4 +
 src/compositor-drm.c |  58 ++-
 src/compositor-fbdev.c   |  12 +-
 src/compositor-headless.c|  11 +-
 src/compositor-rdp.c |  11 +-
 src/compositor-rpi.c |  48 +-
 src/compositor-wayland.c |  11 +-
 src/compositor-x11.c |  11 +-
 src/compositor.c | 861 +---
 src/compositor.h |  70 ++-
 src/gl-renderer.c|   2 +-
 src/pixman-renderer.c|  26 +-
 18 files changed, 2431 insertions(+), 161 deletions(-)
 create mode 100644 clients/presentation-shm.c
 create mode 100644 protocol/presentation_timing.xml

Here are some examples of weston-presentation-shm statistics
output on Weston on DRM with gl-renderer. See patch 13 for more
details.

Mode -f, feedback from frame callback driven immediate commit
loop:

 7: f2c  1 ms, c2p 32 ms, f2p 33 ms, p2p 16648 us, t2p 32670, seq 7741506
 8: f2c  0 ms, c2p 33 ms, f2p 33 ms, p2p 16650 us, t2p 32677, seq 7741507
 9: f2c  1 ms, c2p 33 ms, f2p 34 ms, p2p 16652 us, t2p 32671, seq 7741508
10: f2c  1 ms, c2p 32 ms, f2p 33 ms, p2p 16648 us, t2p 32700, seq 7741509
11: f2c  0 ms, c2p 33 ms, f2p 33 ms, p2p 16651 us, t2p 32680, seq 7741510


Mode -q, queueing with feedback for every frame, random
committing order:

   172: c2p   32 ms, p2p 16650 us, t2p   -30 us, seq 7742478
   130: c2p   50 ms, p2p 16652 us, t2p   -43 us, seq 7742479
   133: c2p   67 ms, p2p 16651 us, t2p   -56 us, seq 7742480
   151: c2p   83 ms, p2p 16656 us, t2p   -65 us, seq 7742481
   166: c2p   99 ms, p2p 16642 us, t2p   -88 us, seq 7742482
   177: c2p  115 ms, p2p 16652 us, t2p  -101 us, seq 7742483
   174: c2p  132 ms, p2p 16648 us, t2p  -117 us, seq 7742484
   159: c2p  150 ms, p2p 16651 us, t2p  -131 us, seq 7742485
   148: c2p  166 ms, p2p 16651 us, t2p  -145 us, seq 7742486

Note, that the refresh period is taken as 1/refresh_frequency,
which becomes 1 us, but the actual measured

[PATCH v2 02/12] shell.c: Restore maximized and fullscreen window on destroyed output

2014-03-07 Thread Xiong Zhang
When maximized or fullscreen window is on destroyed output, compositor
can't change these windows to normal window without notify client,
otherwise maximize icon or F11 buttion lose its effect after output unplug.

Instead we keep these window as maximized or fullscreen, just change
it's size to target output.

Signed-off-by: Xiong Zhang 
---
 desktop-shell/shell.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index bee1b0b..d5d6eab 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -5534,6 +5534,7 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
struct shell_surface *shsurf;
float x, y;
int visible;
+   struct weston_view *black_view;
 
x = view->geometry.x;
y = view->geometry.y;
@@ -5557,6 +5558,8 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
x = first_output->x + first_output->width / 4;
y = first_output->y + first_output->height / 4;
 
+   output = first_output;
+
weston_view_set_position(view, x, y);
} else
weston_view_geometry_dirty(view);
@@ -5566,9 +5569,24 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
 
if (shsurf) {
shsurf->saved_position_valid = false;
-   shsurf->next_state.maximized = false;
-   shsurf->next_state.fullscreen = false;
-   shsurf->state_changed = true;
+
+   /* Resize maxmized window to target output. */
+   if (shsurf->state.maximized)
+   set_maximized(shsurf, output);
+
+   /* Resize fullscreen window to target output. */
+   if (shsurf->state.fullscreen) {
+   black_view = shsurf->fullscreen.black_view;
+   weston_surface_destroy(black_view->surface);
+   shsurf->fullscreen.black_view = NULL;
+
+   set_fullscreen(shsurf,
+  shsurf->fullscreen.type,
+  shsurf->fullscreen.framerate,
+  output);
+   }
+
+   shsurf->state_changed = false;
}
 }
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 11/12] compositor: Hot plug a output in clone mode

2014-03-07 Thread Xiong Zhang
If adding output is a clone output, first system will find its master,
then system will put this output into master->clone_output_list

If adding output is a master output, system will loop the output_list
to find its clone output. If this master has clone output, the clone
output will downgrade from master to clone.

Signed-off-by: Xiong Zhang 
---
 src/compositor-drm.c |  9 +++-
 src/compositor.c | 61 ++--
 src/compositor.h |  2 ++
 3 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 58a0efa..a30f88d 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -2258,7 +2258,7 @@ update_outputs(struct drm_compositor *ec, struct 
udev_device *drm_device)
drmModeRes *resources;
struct drm_output *output, *next;
uint32_t connected = 0, disconnects = 0;
-   int i;
+   int i, add_output = 0;
 
resources = drmModeGetResources(ec->drm.fd);
if (!resources) {
@@ -2287,11 +2287,18 @@ update_outputs(struct drm_compositor *ec, struct 
udev_device *drm_device)
drm_device);
weston_log("connector %d connected\n", connector_id);
 
+   add_output = 1;
+
}
drmModeFreeConnector(connector);
}
drmModeFreeResources(resources);
 
+   if (add_output) {
+   weston_compositor_add_clone_outputs(&ec->base);
+   weston_compositor_add_master_outputs(&ec->base);
+   }
+
disconnects = ec->connector_allocator & ~connected;
if (disconnects) {
wl_list_for_each_safe(output, next, &ec->base.output_list,
diff --git a/src/compositor.c b/src/compositor.c
index 72d29a0..39081bb 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3139,11 +3139,9 @@ weston_compositor_remove_output(struct weston_compositor 
*compositor,
}
 }
 
-WL_EXPORT void
-weston_output_destroy(struct weston_output *output)
+static void
+delete_output_from_list(struct weston_output *output)
 {
-   output->destroying = 1;
-
if (!output->is_clone)
weston_compositor_remove_output(output->compositor, output);
 
@@ -3155,12 +3153,10 @@ weston_output_destroy(struct weston_output *output)
wl_signal_emit(&output->destroy_signal, output);
}
 
-   free(output->name);
-   if (output->master_output_name)
-   free(output->master_output_name);
pixman_region32_fini(&output->region);
pixman_region32_fini(&output->previous_damage);
pixman_region32_fini(&output->damage);
+
output->compositor->output_id_pool &= ~(1 << output->id);
 
if (!output->is_clone)
@@ -3168,6 +3164,57 @@ weston_output_destroy(struct weston_output *output)
 }
 
 static void
+migrate_clone_output(struct weston_output *clone, struct weston_output *master)
+{
+   delete_output_from_list(clone);
+
+   clone->master_output = master;
+   clone->is_clone = 1;
+
+   weston_output_init(clone, clone->compositor, clone->mm_width,
+  clone->mm_height,  clone->transform,
+  clone->original_scale);
+}
+
+WL_EXPORT void
+weston_output_destroy(struct weston_output *output)
+{
+   output->destroying = 1;
+
+   delete_output_from_list(output);
+
+   free(output->name);
+   if (output->master_output_name)
+   free(output->master_output_name);
+}
+
+/* At first a clone output is discoveryed but associated master isn't found
+ * this clone output will be upgraded to master output;
+ * Then the master output is hot plugged, the original clone output
+ * should be downgraded to clone. */
+WL_EXPORT void
+weston_compositor_add_master_outputs(struct weston_compositor *compositor)
+{
+   struct weston_output *output, *master, *clone, *next1, *next2;
+
+   master = container_of(compositor->output_list.prev,
+   struct weston_output, link);
+
+   wl_list_for_each_safe(output, next1, &compositor->output_list, link) {
+   if (output->master_output_name == NULL ||
+   strncmp(output->master_output_name, master->name,
+   strlen(output->master_output_name)) != 0)
+   continue;
+
+   wl_list_for_each_safe(clone, next2, &output->clone_output_list,
+ link)
+   migrate_clone_output(clone, master);
+
+   migrate_clone_output(output, master);
+   }
+}
+
+static void
 weston_output_compute_transform(struct weston_output *output)
 {
struct weston_matrix transform;
diff --git a/src/compositor.h b/src/compositor.h
index ed7aa45..da63666 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -1222,6 +1222,8 @@ weston_output_init(struct weston_output *output, struct 
weston_compositor *c

[PATCH 10/12] compositor-drm: Deal with VT switch in clone mode

2014-03-07 Thread Xiong Zhang
Signed-off-by: Xiong Zhang 
---
 src/compositor-drm.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index de777b3..58a0efa 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -2376,7 +2376,7 @@ drm_destroy(struct weston_compositor *ec)
 static void
 drm_compositor_set_modes(struct drm_compositor *compositor)
 {
-   struct drm_output *output;
+   struct drm_output *output, *clone_output;
 
wl_list_for_each(output, &compositor->base.output_list, base.link) {
if (!output->current) {
@@ -2390,16 +2390,33 @@ drm_compositor_set_modes(struct drm_compositor 
*compositor)
}
 
drm_output_set_mode(output, output->current->fb_id);
+
+   /* Set mode for all associated clone outputs. */
+   wl_list_for_each(clone_output, &output->base.clone_output_list,
+base.link)
+   drm_output_set_mode(clone_output,
+   clone_output->current->fb_id);
}
 }
 
 static void
+drm_output_clear_cursor(struct drm_output *output)
+{
+   struct drm_compositor *ec =
+   (struct drm_compositor *)output->base.compositor;
+
+   output->base.repaint_needed = 0;
+   drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
+
+}
+
+static void
 session_notify(struct wl_listener *listener, void *data)
 {
struct weston_compositor *compositor = data;
struct drm_compositor *ec = data;
struct drm_sprite *sprite;
-   struct drm_output *output;
+   struct drm_output *output, *clone;
 
if (ec->base.session_active) {
weston_log("activating session\n");
@@ -2423,8 +2440,11 @@ session_notify(struct wl_listener *listener, void *data)
 * pending frame callbacks. */
 
wl_list_for_each(output, &ec->base.output_list, base.link) {
-   output->base.repaint_needed = 0;
-   drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
+   drm_output_clear_cursor(output);
+
+   wl_list_for_each(clone, &output->base.clone_output_list,
+base.link)
+   drm_output_clear_cursor(clone);
}
 
output = container_of(ec->base.output_list.next,
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 09/12] compositor: Output repaint in clone mode

2014-03-07 Thread Xiong Zhang
Because clone output isn't in compositor->output_list, all the repaint
request are for master output.

When master output repaint, all the associated clone output must
repaint also.

Signed-off-by: Xiong Zhang 
---
 src/compositor.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index c9fe06c..72d29a0 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1548,14 +1548,19 @@ output_update_damage(struct weston_output *output)
 {
struct weston_compositor *ec = output->compositor;
pixman_region32_t new_damage;
+   struct weston_output *clone_output;
 
pixman_region32_init(&new_damage);
pixman_region32_intersect(&new_damage,
  &ec->primary_plane.damage, &output->region);
pixman_region32_union(&output->damage, &output->damage, &new_damage);
pixman_region32_fini(&new_damage);
+
+   wl_list_for_each(clone_output, &output->clone_output_list, link)
+   output_update_damage(clone_output);
 }
 
+
 static void
 compositor_accumulate_damage(struct weston_compositor *ec)
 {
@@ -1855,6 +1860,7 @@ WL_EXPORT void
 weston_output_schedule_repaint(struct weston_output *output)
 {
struct weston_compositor *compositor = output->compositor;
+   struct weston_output *clone;
struct wl_event_loop *loop;
 
if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
@@ -1862,6 +1868,10 @@ weston_output_schedule_repaint(struct weston_output 
*output)
return;
 
loop = wl_display_get_event_loop(compositor->wl_display);
+
+   wl_list_for_each(clone, &output->clone_output_list, link)
+   weston_output_schedule_repaint(clone);
+
output->repaint_needed = 1;
if (output->repaint_scheduled)
return;
@@ -3351,6 +3361,8 @@ weston_output_init(struct weston_output *output, struct 
weston_compositor *c,
return;
}
 
+   wl_list_init(&output->clone_output_list);
+
/* Find the position for this output */
if (output->is_clone) {
output->x = output->master_output->x;
@@ -3367,7 +3379,8 @@ weston_output_init(struct weston_output *output, struct 
weston_compositor *c,
}
 
weston_output_init_geometry(output, output->x, output->y);
-   weston_output_damage(output);
+   if (!output->is_clone)
+   weston_output_damage(output);
 
wl_signal_init(&output->frame_signal);
wl_signal_init(&output->destroy_signal);
@@ -3377,8 +3390,6 @@ weston_output_init(struct weston_output *output, struct 
weston_compositor *c,
output->id = ffs(~output->compositor->output_id_pool) - 1;
output->compositor->output_id_pool |= 1 << output->id;
 
-   wl_list_init(&output->clone_output_list);
-
if (!output->is_clone) {
wl_list_insert(c->output_list.prev, &output->link);
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 00/12] implement per connector clone mode

2014-03-07 Thread Xiong Zhang
With the help of Ander, this is the new round clone mode patchset.

The implementation points are:
a. master output are in compositor->output_list, clone output are in
master_output->clone_output_list. we create global_output for master
output only. Client can't get any information for clone output. 

b. All the external repaint request are for master output. when master
output repaint, all the associated clone output should repaint also.
Master output and clone outputs have seperate frame buffer, but they
reference the same surface.

Note there are still two minor issues for this:
a. when the refresh rate difference between master and clone is large
enough, sometimes the picture among them may be different.

b. when the size of clone output is larger than master output, the display
for extra area on clone output is ugly and mess.
   when the size of clone output is smaller than master output, clone output 
can just show partial master output.
   I will supply one patch to scale clone output for this case.

patch 1~2: bug fix patch for output unplug in extend mode
patch 3~6: refactor patch for clone mode
patch 7~12: implement clone mode

Ander Conselvan de Oliveira (3):
  compositor: Move output positining logic out of the backends
  compositor: Add output to the compositor output list in the core
  compositor: Track damage properly for overlapping outputs

Xiong Zhang (9):
  shell.c: Set dirty for visible views on destroyed output
  shell.c: Restore maximized and fullscreen window on destroyed output
  compositor-drm: Abstract drm_output_set_mode()
  compositor: Add per connector clone mode support
  compositor: Move all clone outputs when move master outptu
  compositor: Output repaint in clone mode
  compositor-drm: Deal with VT switch in clone mode
  compositor: Hot plug a output in clone mode
  compositor: Output unplug in clone mode

 desktop-shell/shell.c |  30 +-
 src/compositor-drm.c  | 161 +---
 src/compositor-fbdev.c|  12 +--
 src/compositor-headless.c |   8 +-
 src/compositor-rdp.c  |   5 +-
 src/compositor-rpi.c  |   9 +-
 src/compositor-wayland.c  |  32 +++---
 src/compositor-x11.c  |  34 +++---
 src/compositor.c  | 263 +-
 src/compositor.h  |  14 ++-
 weston.ini.in |   2 +
 11 files changed, 419 insertions(+), 151 deletions(-)

-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 01/12] shell.c: Set dirty for visible views on destroyed output

2014-03-07 Thread Xiong Zhang
The geometry for visible views will keep unchanged,
weston_view_set_position() doesn't mark these views
as dirty. So there is no chance for them to reassign output, then
these views will disappear.

Signed-off-by: Xiong Zhang 
---
 desktop-shell/shell.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index fd9ead0..bee1b0b 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -5556,9 +5556,11 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
 
x = first_output->x + first_output->width / 4;
y = first_output->y + first_output->height / 4;
-   }
 
-   weston_view_set_position(view, x, y);
+   weston_view_set_position(view, x, y);
+   } else
+   weston_view_geometry_dirty(view);
+
 
shsurf = get_shell_surface(view->surface);
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 04/12] compositor: Add output to the compositor output list in the core

2014-03-07 Thread Xiong Zhang
From: Ander Conselvan de Oliveira 

Previously the insertion was done by the backends, with a potential
crash in the error path. Calls to weston_output_destroy() would try
to remove the output from the compositor list before it was actually
inserted.

This patch moves the insertion to weston_output_init().

Signed-off-by: Ander Conselvan de Oliveira 

---
 src/compositor-drm.c  |  2 --
 src/compositor-fbdev.c|  2 --
 src/compositor-headless.c |  2 --
 src/compositor-rdp.c  |  1 -
 src/compositor-rpi.c  |  2 --
 src/compositor-wayland.c  |  2 --
 src/compositor-x11.c  | 12 +++-
 src/compositor.c  |  2 ++
 8 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 57064ec..6109cec 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -2049,8 +2049,6 @@ create_output_for_connector(struct drm_compositor *ec,
weston_log("Failed to initialize backlight\n");
}
 
-   wl_list_insert(ec->base.output_list.prev, &output->base.link);
-
find_and_parse_output_edid(ec, output, connector);
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
output->base.connection_internal = 1;
diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
index 076a9a8..3eaa57b 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -639,8 +639,6 @@ fbdev_output_create(struct fbdev_compositor *compositor,
output->finish_frame_timer =
wl_event_loop_add_timer(loop, finish_frame_handler, output);
 
-   wl_list_insert(compositor->base.output_list.prev, &output->base.link);
-
weston_log("fbdev output %d×%d px\n",
   output->mode.width, output->mode.height);
weston_log_continue(STAMP_SPACE "guessing %d Hz and 96 dpi\n",
diff --git a/src/compositor-headless.c b/src/compositor-headless.c
index 326c11b..a07fd49 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -126,8 +126,6 @@ headless_compositor_create_output(struct 
headless_compositor *c,
output->base.set_dpms = NULL;
output->base.switch_mode = NULL;
 
-   wl_list_insert(c->base.output_list.prev, &output->base.link);
-
return 0;
 }
 
diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
index e8e4a8d..a6c192b 100644
--- a/src/compositor-rdp.c
+++ b/src/compositor-rdp.c
@@ -506,7 +506,6 @@ rdp_compositor_create_output(struct rdp_compositor *c, int 
width, int height,
output->base.switch_mode = rdp_switch_mode;
c->output = output;
 
-   wl_list_insert(c->base.output_list.prev, &output->base.link);
return 0;
 
 out_shadow_surface:
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
index 7312822..8dc12d1 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -387,8 +387,6 @@ rpi_output_create(struct rpi_compositor *compositor, 
uint32_t transform)
if (rpi_renderer_output_create(&output->base, output->display) < 0)
goto out_output;
 
-   wl_list_insert(compositor->base.output_list.prev, &output->base.link);
-
weston_log("Raspberry Pi HDMI output %dx%d px\n",
   output->mode.width, output->mode.height);
weston_log_continue(STAMP_SPACE "guessing %d Hz and 96 dpi\n",
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 9e94a7b..a850dab 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -826,8 +826,6 @@ wayland_output_create(struct wayland_compositor *c,
output->base.set_dpms = NULL;
output->base.switch_mode = NULL;
 
-   wl_list_insert(c->base.output_list.prev, &output->base.link);
-
return output;
 
 err_output:
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 01af835..6c3eb15 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -882,28 +882,30 @@ x11_compositor_create_output(struct x11_compositor *c,
if (x11_output_init_shm(c, output,
output->mode.width,
output->mode.height) < 0)
-   return NULL;
+   goto err_output;
if (pixman_renderer_output_create(&output->base) < 0) {
x11_output_deinit_shm(c, output);
-   return NULL;
+   goto err_output;
}
} else {
ret = gl_renderer->output_create(&output->base,
 (EGLNativeWindowType) 
output->window);
if (ret < 0)
-   return NULL;
+   goto err_output;
}
 
loop = wl_display_get_event_loop(c->base.wl_display);
output->finish_frame_timer =
wl_event_loop_add_timer(loop, finish_frame_handler, output);
 
-   wl_list_insert(c->base.output_list.prev, &output->base.link);
-
weston_log("x1

[PATCH 05/12] compositor: Track damage properly for overlapping outputs

2014-03-07 Thread Xiong Zhang
From: Ander Conselvan de Oliveira 

The assumption that there are no overlapping outputs allows damage to
be kept in a compositor-wide region that is cleared by the backends
after output repaint. When outputs overlap, however, the repaint of
one output clears the damage for the overlapping region before it is
seen during the repaint of another output.

To fix this problem, this patch decouples the primary plane damage from
output damage. During repaint of any output, all primary plane damage is
processed and pushed to an output specific damage region. The backends
clear only the damage of the output being repainted, without affecting
any other overlapping output.

Signed-off-by: Ander Conselvan de Oliveira 

---
 src/compositor-drm.c  |  4 ++--
 src/compositor-fbdev.c|  8 
 src/compositor-headless.c |  4 ++--
 src/compositor-rdp.c  |  4 ++--
 src/compositor-rpi.c  |  5 ++---
 src/compositor-wayland.c  |  8 
 src/compositor-x11.c  |  8 
 src/compositor.c  | 26 +++---
 src/compositor.h  |  1 +
 9 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 6109cec..78292a6 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -567,8 +567,8 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
else
drm_output_render_gl(output, damage);
 
-   pixman_region32_subtract(&c->base.primary_plane.damage,
-&c->base.primary_plane.damage, damage);
+   pixman_region32_subtract(&output->base.damage,
+&output->base.damage, damage);
 }
 
 static void
diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
index 3eaa57b..0c9625e 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -182,8 +182,8 @@ fbdev_output_repaint_pixman(struct weston_output *base, 
pixman_region32_t *damag
}
 
/* Update the damage region. */
-   pixman_region32_subtract(&ec->primary_plane.damage,
-&ec->primary_plane.damage, damage);
+   pixman_region32_subtract(&output->base.damage,
+&output->base.damage, damage);
 
/* Schedule the end of the frame. We do not sync this to the frame
 * buffer clock because users who want that should be using the DRM
@@ -208,8 +208,8 @@ fbdev_output_repaint(struct weston_output *base, 
pixman_region32_t *damage)
} else {
ec->renderer->repaint_output(base, damage);
/* Update the damage region. */
-   pixman_region32_subtract(&ec->primary_plane.damage,
-&ec->primary_plane.damage, damage);
+   pixman_region32_subtract(&output->base.damage,
+&output->base.damage, damage);
 
wl_event_source_timer_update(output->finish_frame_timer,
 100 / output->mode.refresh);
diff --git a/src/compositor-headless.c b/src/compositor-headless.c
index a07fd49..52a2aec 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -69,8 +69,8 @@ headless_output_repaint(struct weston_output *output_base,
 
ec->renderer->repaint_output(&output->base, damage);
 
-   pixman_region32_subtract(&ec->primary_plane.damage,
-&ec->primary_plane.damage, damage);
+   pixman_region32_subtract(&output->base.damage,
+&output->base.damage, damage);
 
wl_event_source_timer_update(output->finish_frame_timer, 16);
 
diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
index a6c192b..cc8a839 100644
--- a/src/compositor-rdp.c
+++ b/src/compositor-rdp.c
@@ -328,8 +328,8 @@ rdp_output_repaint(struct weston_output *output_base, 
pixman_region32_t *damage)
}
}
 
-   pixman_region32_subtract(&ec->primary_plane.damage,
-&ec->primary_plane.damage, damage);
+   pixman_region32_subtract(&output->base.damage,
+&output->base.damage, damage);
 
wl_event_source_timer_update(output->finish_frame_timer, 16);
return 0;
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
index 8dc12d1..6b0f062 100644
--- a/src/compositor-rpi.c
+++ b/src/compositor-rpi.c
@@ -230,7 +230,6 @@ rpi_output_repaint(struct weston_output *base, 
pixman_region32_t *damage)
 {
struct rpi_output *output = to_rpi_output(base);
struct rpi_compositor *compositor = output->compositor;
-   struct weston_plane *primary_plane = &compositor->base.primary_plane;
DISPMANX_UPDATE_HANDLE_T update;
 
DBG("frame update start\n");
@@ -243,8 +242,8 @@ rpi_output_repaint(struct weston_output *base, 
pixman_region32_t *damage)
rpi_renderer_set_update_handle(&output->base, update);
compositor->base.re

[PATCH 07/12] compositor: Add per connector clone mode support

2014-03-07 Thread Xiong Zhang
Master output will be in compositor->output_list.
Clone output won't be in compositor->output_list, while it is in
master->clone_output_list.

The group of master output and associated clone outputs will be treated
as one output, client can't get any information about clone output.

Signed-off-by: Xiong Zhang 
---
 src/compositor-drm.c |   9 
 src/compositor.c | 114 ++-
 src/compositor.h |   9 
 weston.ini.in|   2 +
 4 files changed, 115 insertions(+), 19 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index dd1c251..de777b3 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1951,6 +1951,13 @@ create_output_for_connector(struct drm_compositor *ec,
setup_output_seat_constraint(ec, &output->base, s);
free(s);
 
+   weston_config_section_get_string(section, "clone", &s, "");
+   if (strcmp(s, "") != 0) {
+   output->base.is_clone = 1;
+   output->base.master_output_name = strdup(s);
+   }
+   free(s);
+
output->crtc_id = resources->crtcs[i];
output->pipe = i;
ec->crtc_allocator |= (1 << output->crtc_id);
@@ -2231,6 +2238,8 @@ create_outputs(struct drm_compositor *ec, uint32_t 
option_connector,
drmModeFreeConnector(connector);
}
 
+   weston_compositor_add_clone_outputs(&ec->base);
+
if (wl_list_empty(&ec->base.output_list)) {
weston_log("No currently active connector found.\n");
drmModeFreeResources(resources);
diff --git a/src/compositor.c b/src/compositor.c
index 6aff7ab..402ac75 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3066,6 +3066,47 @@ bind_output(struct wl_client *client,
wl_output_send_done(resource);
 }
 
+static void
+add_clone_output(struct weston_output *clone_output)
+{
+   struct weston_compositor *compositor = clone_output->compositor;
+   struct weston_output *master_output;
+   uint32_t found = 0;
+
+   wl_list_for_each(master_output, &compositor->output_list, link) {
+   if (clone_output->master_output_name == NULL ||
+   strncmp(clone_output->master_output_name,
+   master_output->name,
+   strlen(clone_output->master_output_name) != 0))
+   continue;
+
+   clone_output->master_output = master_output;
+   found = 1;
+   }
+
+   if (found == 0)
+   clone_output->is_clone = 0;
+
+   weston_output_init(clone_output, compositor,
+  clone_output->mm_width,
+  clone_output->mm_height,
+  clone_output->transform,
+  clone_output->original_scale);
+}
+
+WL_EXPORT void
+weston_compositor_add_clone_outputs(struct weston_compositor *compositor)
+{
+   struct weston_output *clone_output, *next;
+
+   wl_list_for_each_safe(clone_output, next,
+ &compositor->temp_clone_list, link) {
+   wl_list_remove(&clone_output->link);
+
+   add_clone_output(clone_output);
+   }
+}
+
 /* Move other outputs when one is removed so the space remains contiguos. */
 static void
 weston_compositor_remove_output(struct weston_compositor *compositor,
@@ -3093,19 +3134,27 @@ weston_output_destroy(struct weston_output *output)
 {
output->destroying = 1;
 
-   weston_compositor_remove_output(output->compositor, output);
+   if (!output->is_clone)
+   weston_compositor_remove_output(output->compositor, output);
+
wl_list_remove(&output->link);
 
-   wl_signal_emit(&output->compositor->output_destroyed_signal, output);
-   wl_signal_emit(&output->destroy_signal, output);
+   if (!output->is_clone) {
+   wl_signal_emit(&output->compositor->output_destroyed_signal,
+  output);
+   wl_signal_emit(&output->destroy_signal, output);
+   }
 
free(output->name);
+   if (output->master_output_name)
+   free(output->master_output_name);
pixman_region32_fini(&output->region);
pixman_region32_fini(&output->previous_damage);
pixman_region32_fini(&output->damage);
output->compositor->output_id_pool &= ~(1 << output->id);
 
-   wl_global_destroy(output->global);
+   if (!output->is_clone)
+   wl_global_destroy(output->global);
 }
 
 static void
@@ -3284,8 +,28 @@ weston_output_init(struct weston_output *output, struct 
weston_compositor *c,
 {
struct weston_output *last;
 
+   output->compositor = c;
+   output->mm_width = mm_width;
+   output->mm_height = mm_height;
+   output->dirty = 1;
+   output->original_scale = scale;
+
+   weston_output_transform_scale_init(output, transform, scale);
+   weston_output_init_zoom(output);
+
+

[PATCH 02/12] shell.c: Restore maximized and fullscreen window on destroyed output

2014-03-07 Thread Xiong Zhang
When maximized or fullscreen window is on destroyed output, compositor
can't change these windows to normal window without notify client,
otherwise maximize icon or F11 buttion lose its effect after output unplug.

Instead we keep these window as maximized or fullscreen, just change
it's size to target output.

Signed-off-by: Xiong Zhang 
---
 desktop-shell/shell.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index bee1b0b..02dd1b8 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -5534,6 +5534,7 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
struct shell_surface *shsurf;
float x, y;
int visible;
+   struct weston_view *black_view;
 
x = view->geometry.x;
y = view->geometry.y;
@@ -5557,6 +5558,8 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
x = first_output->x + first_output->width / 4;
y = first_output->y + first_output->height / 4;
 
+   output = first_output;
+
weston_view_set_position(view, x, y);
} else
weston_view_geometry_dirty(view);
@@ -5566,9 +5569,24 @@ shell_reposition_view_on_output_destroy(struct 
weston_view *view)
 
if (shsurf) {
shsurf->saved_position_valid = false;
-   shsurf->next_state.maximized = false;
-   shsurf->next_state.fullscreen = false;
-   shsurf->state_changed = true;
+
+   /* Resize maxmized window to target output. */
+   if (shsurf->state.maximized)
+   set_maximized(shsurf, output);
+
+   /* Resize fullscreen window to target output. */
+   if (shsurf->state.fullscreen) {
+   black_view = shsurf->fullscreen.black_view->surface;
+   weston_surface_destroy(black_view->surface);
+   shsurf->fullscreen.black_view = NULL;
+
+   set_fullscreen(shsurf,
+  shsurf->fullscreen.type,
+  shsurf->fullscreen.framerate,
+  output);
+   }
+
+   shsurf->state_changed = false;
}
 }
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 06/12] compositor-drm: Abstract drm_output_set_mode()

2014-03-07 Thread Xiong Zhang
Signed-off-by: Xiong Zhang 
---
 src/compositor-drm.c | 45 +++--
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 78292a6..dd1c251 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -593,6 +593,26 @@ drm_output_set_gamma(struct weston_output *output_base,
 }
 
 static int
+drm_output_set_mode(struct drm_output *output, uint32_t fb_id)
+{
+   struct drm_compositor *compositor =
+   (struct drm_compositor *)output->base.compositor;
+   struct drm_mode *mode;
+   int ret = 0;
+
+   mode = container_of(output->base.current_mode,
+   struct drm_mode, base);
+   ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
+fb_id, 0, 0,
+&output->connector_id, 1,
+&mode->mode_info);
+   if (ret)
+   weston_log("set mode failed: %m\n");
+
+   return ret;
+}
+
+static int
 drm_output_repaint(struct weston_output *output_base,
   pixman_region32_t *damage)
 {
@@ -600,7 +620,6 @@ drm_output_repaint(struct weston_output *output_base,
struct drm_compositor *compositor =
(struct drm_compositor *) output->base.compositor;
struct drm_sprite *s;
-   struct drm_mode *mode;
int ret = 0;
 
if (output->destroy_pending)
@@ -611,17 +630,11 @@ drm_output_repaint(struct weston_output *output_base,
if (!output->next)
return -1;
 
-   mode = container_of(output->base.current_mode, struct drm_mode, base);
if (!output->current ||
output->current->stride != output->next->stride) {
-   ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
-output->next->fb_id, 0, 0,
-&output->connector_id, 1,
-&mode->mode_info);
-   if (ret) {
-   weston_log("set mode failed: %m\n");
+   if (drm_output_set_mode(output, output->next->fb_id))
goto err_pageflip;
-   }
+
output_base->set_dpms(output_base, WESTON_DPMS_ON);
}
 
@@ -2355,8 +2368,6 @@ static void
 drm_compositor_set_modes(struct drm_compositor *compositor)
 {
struct drm_output *output;
-   struct drm_mode *drm_mode;
-   int ret;
 
wl_list_for_each(output, &compositor->base.output_list, base.link) {
if (!output->current) {
@@ -2369,17 +2380,7 @@ drm_compositor_set_modes(struct drm_compositor 
*compositor)
continue;
}
 
-   drm_mode = (struct drm_mode *) output->base.current_mode;
-   ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
-output->current->fb_id, 0, 0,
-&output->connector_id, 1,
-&drm_mode->mode_info);
-   if (ret < 0) {
-   weston_log(
-   "failed to set mode %dx%d for output at %d,%d: 
%m\n",
-   drm_mode->base.width, drm_mode->base.height, 
-   output->base.x, output->base.y);
-   }
+   drm_output_set_mode(output, output->current->fb_id);
}
 }
 
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 03/12] compositor: Move output positining logic out of the backends

2014-03-07 Thread Xiong Zhang
From: Ander Conselvan de Oliveira 

Move the code for choosing the x and y of an output out of the backend
into weston_output_init(). All the backends implement the same simple
behavior, so this lets that code be in just one place.

Signed-off-by: Ander Conselvan de Oliveira 

---
 src/compositor-drm.c  | 24 
 src/compositor-fbdev.c|  2 +-
 src/compositor-headless.c |  2 +-
 src/compositor-rpi.c  |  2 +-
 src/compositor-wayland.c  | 22 +-
 src/compositor-x11.c  | 14 +-
 src/compositor.c  | 20 
 src/compositor.h  |  2 +-
 8 files changed, 38 insertions(+), 50 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index a1f653c..57064ec 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1871,7 +1871,7 @@ static int
 create_output_for_connector(struct drm_compositor *ec,
drmModeRes *resources,
drmModeConnector *connector,
-   int x, int y, struct udev_device *drm_device)
+   struct udev_device *drm_device)
 {
struct drm_output *output;
struct drm_mode *drm_mode, *next, *preferred, *current, *configured, 
*best;
@@ -2024,7 +2024,7 @@ create_output_for_connector(struct drm_compositor *ec,
 
output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
 
-   weston_output_init(&output->base, &ec->base, x, y,
+   weston_output_init(&output->base, &ec->base,
   connector->mmWidth, connector->mmHeight,
   transform, scale);
 
@@ -2179,7 +2179,6 @@ create_outputs(struct drm_compositor *ec, uint32_t 
option_connector,
drmModeConnector *connector;
drmModeRes *resources;
int i;
-   int x = 0, y = 0;
 
resources = drmModeGetResources(ec->drm.fd);
if (!resources) {
@@ -2211,15 +2210,11 @@ create_outputs(struct drm_compositor *ec, uint32_t 
option_connector,
(option_connector == 0 ||
 connector->connector_id == option_connector)) {
if (create_output_for_connector(ec, resources,
-   connector, x, y,
+   connector,
drm_device) < 0) {
drmModeFreeConnector(connector);
continue;
}
-
-   x += container_of(ec->base.output_list.prev,
- struct weston_output,
- link)->width;
}
 
drmModeFreeConnector(connector);
@@ -2242,7 +2237,6 @@ update_outputs(struct drm_compositor *ec, struct 
udev_device *drm_device)
drmModeConnector *connector;
drmModeRes *resources;
struct drm_output *output, *next;
-   int x = 0, y = 0;
uint32_t connected = 0, disconnects = 0;
int i;
 
@@ -2268,18 +2262,8 @@ update_outputs(struct drm_compositor *ec, struct 
udev_device *drm_device)
connected |= (1 << connector_id);
 
if (!(ec->connector_allocator & (1 << connector_id))) {
-   struct weston_output *last =
-   container_of(ec->base.output_list.prev,
-struct weston_output, link);
-
-   /* XXX: not yet needed, we die with 0 outputs */
-   if (!wl_list_empty(&ec->base.output_list))
-   x = last->x + last->width;
-   else
-   x = 0;
-   y = 0;
create_output_for_connector(ec, resources,
-   connector, x, y,
+   connector,
drm_device);
weston_log("connector %d connected\n", connector_id);
 
diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
index 0d96269..076a9a8 100644
--- a/src/compositor-fbdev.c
+++ b/src/compositor-fbdev.c
@@ -555,7 +555,7 @@ fbdev_output_create(struct fbdev_compositor *compositor,
output->base.model = output->fb_info.id;
 
weston_output_init(&output->base, &compositor->base,
-  0, 0, output->fb_info.width_mm,
+  output->fb_info.width_mm,
   output->fb_info.height_mm,
   WL_OUTPUT_TRANSFORM_NORMAL,
   1);
diff --git a/src/compositor-headless.c b/src/compositor-headless.c
index 4ecb8d4..326c11b 100644
--- a/src/compositor-headless.c
+++ b/src/compositor-headless.c
@@ -108,7 +108,7 @@ headless_compositor_create_output(s

[PATCH 12/12] compositor: Output unplug in clone mode

2014-03-07 Thread Xiong Zhang
If unplugged output is a clone output or a master output without
associated clone output, just destroy it as normal.

If unplugged output is a master output with associated clone output,
one clone output will be upgraded to master output, this new master
is put at the end of compositor->output_list.

Signed-off-by: Xiong Zhang 
---
 src/compositor-drm.c | 40 
 src/compositor.c | 46 ++
 2 files changed, 74 insertions(+), 12 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index a30f88d..56d60d9 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -2252,11 +2252,36 @@ create_outputs(struct drm_compositor *ec, uint32_t 
option_connector,
 }
 
 static void
+destroy_disconnect_output(struct drm_output *output, uint32_t *disconnects)
+{
+   if (*disconnects & (1 << output->connector_id)) {
+   *disconnects &= ~(1 << output->connector_id);
+
+   weston_log("connector %d disconnected\n", output->connector_id);
+
+   drm_output_destroy(&output->base);
+   }
+}
+
+static void
+destroy_disconnect_outputs(struct drm_compositor *ec, uint32_t disconnects)
+{
+   struct drm_output *output, *clone, *next1, *next2;
+
+   wl_list_for_each_safe(output, next1, &ec->base.output_list, base.link) {
+   wl_list_for_each_safe(clone, next2,
+   &output->base.clone_output_list, base.link)
+   destroy_disconnect_output(clone, &disconnects);
+
+   destroy_disconnect_output(output, &disconnects);
+   }
+}
+
+static void
 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 {
drmModeConnector *connector;
drmModeRes *resources;
-   struct drm_output *output, *next;
uint32_t connected = 0, disconnects = 0;
int i, add_output = 0;
 
@@ -2300,17 +2325,8 @@ update_outputs(struct drm_compositor *ec, struct 
udev_device *drm_device)
}
 
disconnects = ec->connector_allocator & ~connected;
-   if (disconnects) {
-   wl_list_for_each_safe(output, next, &ec->base.output_list,
- base.link) {
-   if (disconnects & (1 << output->connector_id)) {
-   disconnects &= ~(1 << output->connector_id);
-   weston_log("connector %d disconnected\n",
-  output->connector_id);
-   drm_output_destroy(&output->base);
-   }
-   }
-   }
+   if (disconnects)
+   destroy_disconnect_outputs(ec, disconnects);
 
/* FIXME: handle zero outputs, without terminating */   
if (ec->connector_allocator == 0)
diff --git a/src/compositor.c b/src/compositor.c
index 39081bb..5694d29 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3117,6 +3117,24 @@ weston_compositor_add_clone_outputs(struct 
weston_compositor *compositor)
}
 }
 
+/* The output with max width wll be new master. */
+static struct weston_output *
+find_new_master(struct weston_output *master)
+{
+   struct weston_output *new, *output;
+   int32_t max_width = 0;
+
+   new = NULL;
+   wl_list_for_each(output, &master->clone_output_list, link) {
+   if (output->width > max_width) {
+   new = output;
+   max_width = output->width;
+   }
+   }
+
+   return new;
+}
+
 /* Move other outputs when one is removed so the space remains contiguos. */
 static void
 weston_compositor_remove_output(struct weston_compositor *compositor,
@@ -3176,11 +3194,39 @@ migrate_clone_output(struct weston_output *clone, 
struct weston_output *master)
   clone->original_scale);
 }
 
+/* If a master is unplugged, one output will be chosen from
+ * master->clone_output_list to replace the unplugged master. */
+static void
+output_destroy_with_clone(struct weston_output *output)
+{
+   struct weston_compositor *compositor = output->compositor;
+   struct weston_output *new_master;
+   struct weston_output *clone, *next;
+
+   new_master = find_new_master(output);
+
+   delete_output_from_list(new_master);
+
+   new_master->master_output = NULL;
+   new_master->is_clone = 0;
+
+   weston_output_init(new_master, compositor, new_master->mm_width,
+  new_master->mm_height, new_master->transform,
+  new_master->original_scale);
+
+   wl_list_for_each_safe(clone, next, &output->clone_output_list, link)
+   migrate_clone_output(clone, new_master);
+
+}
+
 WL_EXPORT void
 weston_output_destroy(struct weston_output *output)
 {
output->destroying = 1;
 
+   if (!wl_list_empty(&output->clone_output_list))
+   output_destroy_with_clone(output);
+

[PATCH 08/12] compositor: Move all clone outputs when move master outptu

2014-03-07 Thread Xiong Zhang
Signed-off-by: Xiong Zhang 
---
 src/compositor.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 402ac75..c9fe06c 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3294,8 +3294,8 @@ weston_output_init_geometry(struct weston_output *output, 
int x, int y)
 WL_EXPORT void
 weston_output_move(struct weston_output *output, int x, int y)
 {
-   pixman_region32_t old_region;
struct wl_resource *resource;
+   struct weston_output *clone;
 
output->move_x = x - output->x;
output->move_y = y - output->y;
@@ -3303,9 +3303,6 @@ weston_output_move(struct weston_output *output, int x, 
int y)
if (output->move_x == 0 && output->move_y == 0)
return;
 
-   pixman_region32_init(&old_region);
-   pixman_region32_copy(&old_region, &output->region);
-
weston_output_init_geometry(output, x, y);
 
output->dirty = 1;
@@ -3324,6 +3321,10 @@ weston_output_move(struct weston_output *output, int x, 
int y)
output->make,
output->model,
output->transform);
+
+   /* Move the associated clone outputs. */
+   wl_list_for_each(clone, &output->clone_output_list, link)
+   weston_output_move(clone, x, y);
 }
 
 WL_EXPORT void
-- 
1.8.3.2

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel