Re: [PATCH wayland v2] wayland-server: abort instead of posting events with wrong client objects

2016-12-09 Thread The Rasterman
On Fri, 9 Dec 2016 15:51:10 +0100 Giulio Camuffo  said:

> 2016-12-08 20:36 GMT+01:00 Derek Foreman :
> > Check that all the objects in an event belong to the same client as
> > the resource posting it.  This prevents a compositor from accidentally
> > mixing client objects and posting an event that causes a client to
> > kill itself.
> >
> > It's intended that the compositor killing itself be easier to debug
> > than the client killing itself for something that it's completely
> > innocent of.
> 
> It may be easier, but as an user the compositor crashing is a highly
> disruptive event, and i think we should strive to avoid it at all
> times. By all means, log the problem, get a backtrace and print it,
> maybe, but i don't agree with the abort(). Unless the problem really
> is unrecoverable, but it seems this is not the case. If it was an
> assert(0) it may be better, but i'm not sure i'd like that either.

i agree. aborts are VERY anti-social for a library to do. reporting an error
and making the function a "NOP" is by far the best thing. 

> Cheers,
> Giulio
> 
> >
> > Signed-off-by: Derek Foreman 
> > ---
> >
> > Changes since v1:
> > uses get_next_arguments and arg_count_for_signature in the normal fashion
> > abort instead of assert
> >
> >
> > This does not address Pekka's request for a new_id test, as it's not
> > immediately clear to me how to write it.
> >
> >  src/wayland-server.c | 29 +
> >  1 file changed, 29 insertions(+)
> >
> > diff --git a/src/wayland-server.c b/src/wayland-server.c
> > index 9d7d9c1..429dbef 100644
> > --- a/src/wayland-server.c
> > +++ b/src/wayland-server.c
> > @@ -160,6 +160,33 @@ log_closure(struct wl_resource *resource,
> > }
> >  }
> >
> > +static void
> > +verify_objects(struct wl_resource *resource, uint32_t opcode,
> > + union wl_argument *args)
> > +{
> > +   struct wl_object *object = >object;
> > +   const char *signature = object->interface->events[opcode].signature;
> > +   struct argument_details arg;
> > +   struct wl_resource *res;
> > +   int count, i;
> > +
> > +   count = arg_count_for_signature(signature);
> > +   for (i = 0; i < count; i++) {
> > +   signature = get_next_argument(signature, );
> > +   switch (arg.type) {
> > +   case 'o':
> > +   res = (struct wl_resource *) (args[i].o);
> > +   if (res && res->client != resource->client) {
> > +   wl_log("unrecoverable error: The compositor
> > "
> > +  "tried to use an object from one "
> > +  "client in an event for a different "
> > +  "client.\n");
> > +   abort();
> > +   }
> > +   }
> > +   }
> > +}
> > +
> >  WL_EXPORT void
> >  wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
> >  union wl_argument *args)
> > @@ -167,6 +194,7 @@ wl_resource_post_event_array(struct wl_resource
> > *resource, uint32_t opcode, struct wl_closure *closure;
> > struct wl_object *object = >object;
> >
> > +   verify_objects(resource, opcode, args);
> > closure = wl_closure_marshal(object, opcode, args,
> >  >interface->events[opcode]);
> >
> > @@ -206,6 +234,7 @@ wl_resource_queue_event_array(struct wl_resource
> > *resource, uint32_t opcode, struct wl_closure *closure;
> > struct wl_object *object = >object;
> >
> > +   verify_objects(resource, opcode, args);
> > closure = wl_closure_marshal(object, opcode, args,
> >  >interface->events[opcode]);
> >
> > --
> > 2.10.2
> >
> > ___
> > wayland-devel mailing list
> > wayland-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/wayland-devel
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel


-- 
- Codito, ergo sum - "I code, therefore I am" --
The Rasterman (Carsten Haitzler)ras...@rasterman.com

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


Re: [RFC wayland-protocols] Color management protocol

2016-12-09 Thread The Rasterman
On Fri, 09 Dec 2016 14:06:46 +0100 Niels Ole Salscheider
 said:

> Am Freitag, 9. Dezember 2016, 12:02:07 CET schrieb Carsten Haitzler:
> > On Thu, 8 Dec 2016 17:32:37 +1100 Graeme Gill  said:
> > > Carsten Haitzler (The Rasterman) wrote:
> > > > i'm curious... is the intent to make it requird that all compositors
> > > > support color management (and thus have to support all the possible
> > > > colorspaces> 
> > > > defined)... or are we going to go the path of:
> > > I'd be happy if there was support for core color management (i.e.
> > > application color management), before adding layers that depend on the
> > > core.
> > 
> > but is the intent that compositors MUST support color management and
> > applications will fail entirely or fail to display even partly correctly if
> > compositor doesnt support color management or doesnt support the color
> > profile/space requested by the client? or will it be expected that apps need
> > to always be able to convert to sRGB for compatibility and then have added
> > colorspace capabilities if it's supported? what is the intent?
> 
> We can't make support for this protocol mandatory because color correction 
> might be too much overhead for compositors for embedded devices.

well graeme disagrees and effectively thinks it should be. :)

> But I would say that every compositor that does some sort of color correction 
> should also implement the color management protocol.
> If the protocol is not supported by the compositor you would assume that you 
> have to output the colors in the device color space (or just ignore it if you 
> do not care about accurate colors).
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel


-- 
- Codito, ergo sum - "I code, therefore I am" --
The Rasterman (Carsten Haitzler)ras...@rasterman.com

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


Re: [RFC wayland-protocols] Color management protocol

2016-12-09 Thread The Rasterman
On Fri, 09 Dec 2016 14:38:37 +0100 Niels Ole Salscheider
 said:

> Am Donnerstag, 8. Dezember 2016, 15:51:12 CET schrieb Graeme Gill:
> > Niels Ole Salscheider wrote:
> > > Therefore I think that the situation has changed and I'd like to propose
> > > this protocol for inclusion in wayland-protocols again.
> > > What do you think?
> > 
> > Hi,
> > I'm prompted to look into the current state of color management
> > in Wayland, by Richard Hughes comment on the ArgyllCMS mailing list
> > 
> > recently that:
> > > About this; in the near future systems will be migrating from X11 to
> > > Wayland (Fedora 25 already defaults to Wayland, other distros will
> > > follow) and so setting X atoms is no longer going to work. Even with
> > > XWayland (the compatibility "wrapper" that provides an isolated
> > > xserver for the app) you can't use the root window as it's isolated
> > > from the other windows. I think most applications that want to know
> > > what profile to use are now using either libcolord, or more commonly,
> > > the colord DBus API.
> > 
> > What I take from this is that XWayland is lacking in its emulation
> > of existing X11 color management protocols (primarily due to lack
> > of underlying support in Wayland), and that currently the only
> > option for pure Wayland applications is to depend on system
> > specific work-arounds such as using Weston with colord. I can
> > therefore see that users that depend on color managed X11 applications
> > (such as photographers, desktop publishers, video editors etc.)
> > aren't going to be switching to Wayland based systems any
> > time soon.
> > 
> > Looking through the current Wayland color-management protocol
> > proposal, I think it is missing a really fundamental thing -
> > managing the output device color calibration state and color
> > profile. I guess the assumption is that this is being done
> > by colord, but my understanding is that colord is specific
> > to Gnome based systems, and certainly depends on DBus, which
> > Wayland does not. [ Please correct me if I've got any of this wrong. ]
> 
> It is (currently) up to the compositor to decide how to implement this. The 
> compositor could come with its own settings for the output color profiles or 
> query some other program. This might be colord, but it could also be 
> kolormanager, or something else.
> 
> > It also seems fundamentally poor design to be using a parallel
> > protocol to manage the color of the graphics system, rather
> > than it being kept in sync with the elements being managed,
> > such as outputs and pixel rasters, etc. Certainly in X11 it is
> > all kept within the X11 protocol or its extensions.
> > If Wayland gets extended to be a remote protocol, then
> > the existence of in band protocols for color management
> > become even more important.
> 
> Yes, with the protocol I proposed there is a (small) time window after 
> changing the output color space where the application might still display 
> surfaces with the old color space...

wouldn't it be best not to explicitly ask for an output colorspace and just
provide the colorspace of your buffer and let the compositor decide? e.g. if
your window is on top, or it's the largest one, or it's focused,then the
compositor MAY switch the colorspace of that monitor to match your surface's
buffer colorspace, and if it goes into the background or whatever, switch back?
it can (and likely should) emulato other colorspaced then.

e.g. if buffer is adobe rgb, then switch display to work in adobe rgb but
re-render everything else that is sRGB into adobe argb space... there might be
a slight "flicker" so to speak as maybe some banding appears in some gradients
of SRGB windows or colors are ever so slightly off, but the compositor is
optimizing for the surface it thinks it most important. i really don't like the
idea of applications explicitly controlling screen colorspace. simple being
able to list colorspaces available, know which might be native or emulated, and
then say which colorspace their buffer has. this way colorspace is tired
directly to the buffer and the compositor can avoid these glitches (like time
difference between switching screen colorspace and buffers actually being
provided in that colorspace).

> > So as a broad outline, what I would regard as features of
> > a reasonable color management facility for a graphics
> > system such as Wayland are:
> > 
> > * That color management protocol's have two uses :- 1) configuring
> >   color management and 2) allowing applications to use color management.
> >   These two uses may need different security profiles.
> >   The assumption should be that color management applications
> >   used to create calibrations, profiles and configure the
> >   state of color management, are of equal importance to color
> >   managed applications that depend on a properly profiled and
> >   configured color management system, since you can't have latter
> >   

Re: [RFC wayland-protocols] Color management protocol

2016-12-09 Thread The Rasterman
On Fri, 09 Dec 2016 14:29:14 +0100 Niels Ole Salscheider
 said:

> Am Donnerstag, 8. Dezember 2016, 13:33:20 CET schrieb Graeme Gill:
> > Niels Ole Salscheider wrote:
> > 
> > Hi,
> > 
> > > The first version of my proposal had such a flag. I removed it and
> > > replaced it by the described version based on feedback from Zoxc
> > > (zox...@gmail.com).
> > Do you have a link to the specifics ?
> 
> Most of the discussion happened on IRC back then. It should be in the logs 
> but...
> 
> > > I can see advantages with both solutions. One advantage with the current
> > > proposal is that you can have a surface that covers multiple screens. In
> > > this case the compositor can still try its best to correct the colours
> > > for all but the main screen.
> > 
> > I'm not quite sure what you mean. Generally an application will have
> > specific reasons for wanting to do it's own color management - for
> > instance, perhaps it is previewing a CMYKOGlclm file, and wants to
> > treat out of gamut mapping and black point mapping in a particular way, etc.
> > I don't think the Wayland compositor is going to be expected to handle
> > CMYKOGlclm etc. input rasters, never mind all the requirements of
> > specialist application color management!
> 
> This is of course something that the client application has to do. It would 
> query the main output for its surface, do the conversions to that color space 
> and then attach the output color space to the surface.
> 
> The compositor now must not touch the parts of the surface on the main output 
> (where the color spaces match). But it could still try to convert from the 
> color space of the main output to that of a secondary screen if the surface 
> covers two screens with different color profiles.
> 
> This might of course cause artifacts when one of the screens has a too small 
> gamut but still seems better than ignoring this.
> 
> But then again most people that work with professional applications would not 
> make them cover multiple screens, I guess. Therefore I'm not opposed to
> adding a flag that indicates that the application wants to disable color
> corrections completely for that surface, independent of the output.

why not simply let the compositor decide. if a surface spans multile screens it
may have to emulate on another screen (egh one screen can do adobe arg, another
is ye-olde sRGB). this is simply a matter of letting the compositor know what
colorspace the rgb values are in so it can "do the appropriate thing". :)

> > Which is not to say that compositor color management doesn't have its
> > place - it is ideal for applications that just want to use "RGB", and
> > not deal with specific display behavior.
> 
> Very simple applications would just keep the attached sRGB color space and 
> maybe place images on subsurfaces with the embedded color space from the
> image attached.
> 
> Applications that care a bit more about color correction (but do not have 
> professional needs) could convert all their colors to the blending color
> space of the compositor. I'd expect this blending color space to be linear if
> the compositor cares about good colors.
> This would have the advantage that the compositor does not have to do the 
> conversion "application output color space -> blending color space".

if compositor just lists what colorspaces it can do, which happen to have
native hardware support (i.e. the display panel itself is capable of it), then
client can choose whatever works best, and compositor just "does its best" too
which may mean adjusting dislpay gammut or output transforms at the gpu level
or via side-bad protocols with the display panel itself if that were to exist.

> > > Back then I argued that this might not be good enough if you want to
> > > calibrate the monitor. But the consent was that this would require
> > > another protocol to disable all colour corrections anyway and that it
> > > could be developed at a later point.
> > 
> > I strongly disagree with this idea - disabling application-side color
> > management is a fundamental step in achieving end to end color management.
> > You don't have color management until you are able to profile the output
> > device, so this is not something that can be left until latter!
> > 
> > Graeme Gill.
> > 
> > 
> > ___
> > wayland-devel mailing list
> > wayland-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 
> 
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel


-- 
- Codito, ergo sum - "I code, therefore I am" --
The Rasterman (Carsten Haitzler)ras...@rasterman.com

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org

Re: [PATCH wayland] util: Document wl_array and wl_list members

2016-12-09 Thread Daniel Stone
Hi Yong,

On 6 December 2016 at 15:21, Yong Bakos  wrote:
> Despite their clear names, wl_array and wl_list members are undocumented,
> resulting in doxygen warnings[1] when building documentation.
>
> Document these members, suppressing the warnings.

Not a difficult review; pushed.

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


Re: [PATCH weston RFC] compositor-wayland: Support building without EGL

2016-12-09 Thread Daniel Stone
Hi Armin,

On 9 December 2016 at 21:58, Armin Krezović  wrote:
> +#ifdef ENABLE_EGL /* Defined but not used */
> +#ifdef ENABLE_EGL /* Force pixman when EGL support is disabled */
> b->use_pixman = new_config->use_pixman;
> +#else
> +   b->use_pixman = true;
> +#endif

Bikeshedding a bit, I don't think these comments really add anything,
and I'd just ditch them when applying. But that being said:
Acked-by: Daniel Stone 

and if no-one beats me to setting up an EGL-less environment to test
it, I'll upgrade to R-b when I do.

Thanks! (And yes, I'll modify pixel-formats to suit.)

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


Re: [PATCH 0/2] xdg-shell: Proposal to be more generic for decorations

2016-12-09 Thread Dima Ryazanov
Overall, I like the idea - it seems to solve the issues with raise/lower,
etc.

I wonder, though, if removing the explicit move/resize/etc. requests makes
it too restrictive. Suppose that, for whatever reason, the client wants to
trigger a move or a resize using the right or middle button. Maybe it's a
weirdly-shaped surface (like weston-flower) where all of it is draggable,
or some other strange case. As far as I can tell, it's possible in v6, but
not v7.

Another, more real use case: nautilus has a bunch of buttons in the
titlebar. If you click them, they work as usual - but dragging a button
triggers a shell move. That means, at the time the client receives a mouse
down event, it doesn't know yet what it should do. Once it gets a mouse
move, it sends a shell move request. Would that still be possible in v7?


On Fri, Dec 9, 2016 at 2:20 PM, Adam Goode  wrote:

> Hi,
>
> There were many different opinions and suggestions for how to allow
> for raise and lower to be bound to mouse clicks in titlebars. This
> is one possible way forward. It removes some of the semantic requests
> in xdg-shell and replaces it with a "interact_with_decoration"
> request that lets more window management logic move into the compositor.
>
> Comments welcome. I know this is a tricky issue, but I hope this
> is leading somewhat in the right direction.
>
>
> Adam
>
>
>
> Adam Goode (2):
>   xdg-shell: Introduce protocol v7
>   xdg-shell: Fold several client-side decoration requests into a generic
> request
>
>  COPYING  |1 +
>  unstable/xdg-shell/xdg-shell-unstable-v7.xml | 1012
> ++
>  2 files changed, 1013 insertions(+)
>  create mode 100644 unstable/xdg-shell/xdg-shell-unstable-v7.xml
>
> --
> 2.8.0.rc3.226.g39d4020
>
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/2] xdg-shell: Fold several client-side decoration requests into a generic request

2016-12-09 Thread Adam Goode
Compositors currently receive "move", "resize", and "show_window_menu"
requests from clients whose decorations have been interacted with.
Clients currently implement key- and mouse-binding policies to
determine which one of these requests to send to the compositor in
response to user action.

Desktop environments traditionally have let users bind a large number of
potential actions to various interactions with decorations: not just a
handful like move and resize.

This change to xdg-shell makes the protocol more generic, allowing more
surface management policy to be implemented in the compositor directly.
This centralizes more policy in compositors, reducing policy duplication
from client toolkits and allowing for more standard surface management
behavior across them.

Signed-off-by: Adam Goode 
---
 COPYING  |   1 +
 unstable/xdg-shell/xdg-shell-unstable-v7.xml | 137 +++
 2 files changed, 55 insertions(+), 83 deletions(-)

diff --git a/COPYING b/COPYING
index 8ab3291..73cebf9 100644
--- a/COPYING
+++ b/COPYING
@@ -6,6 +6,7 @@ Copyright © 2014  Jonas Ådahl
 Copyright © 2014  Jason Ekstrand
 Copyright © 2014-2015 Collabora, Ltd.
 Copyright © 2015  Red Hat Inc.
+Copyright © 2016  Google Inc.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/unstable/xdg-shell/xdg-shell-unstable-v7.xml 
b/unstable/xdg-shell/xdg-shell-unstable-v7.xml
index de5d21c..c039936 100644
--- a/unstable/xdg-shell/xdg-shell-unstable-v7.xml
+++ b/unstable/xdg-shell/xdg-shell-unstable-v7.xml
@@ -580,101 +580,72 @@
   
 
 
-
-  
-   Clients implementing client-side decorations might want to show
-   a context menu when right-clicking on the decorations, giving the
-   user a menu that they can use to maximize or minimize the window.
-
-   This request asks the compositor to pop up such a window menu at
-   the given position, relative to the local surface coordinates of
-   the parent surface. There are no guarantees as to what menu items
-   the window menu contains.
-
-   This request must be used in response to some sort of user action
-   like a button press, key press, or touch down event.
-  
-  
-  
-  
-  
-
-
-
-  
-   Start an interactive, user-driven move of the surface.
-
-   This request must be used in response to some sort of user action
-   like a button press, key press, or touch down event. The passed
-   serial is used to determine the type of interactive move (touch,
-   pointer, etc).
-
-   The server may ignore move requests depending on the state of
-   the surface (e.g. fullscreen or maximized), or if the passed serial
-   is no longer valid.
-
-   If triggered, the surface will lose the focus of the device
-   (wl_pointer, wl_touch, etc) used for the move. It is up to the
-   compositor to visually indicate that the move is taking place, such as
-   updating a pointer cursor, during the move. There is no guarantee
-   that the device focus will return when the move is completed.
-  
-  
-  
-
-
-
-  
-   These values are used to indicate which edge of a surface
-   is being dragged in a resize operation.
+
+  
+   These values are used to indicate which part of a surface
+   is being interacted with in an interact_with_decoration operation.
   
   
-  
-  
-  
-  
-  
-  
-  
-  
+  
+  
+  
+  
+  
+  
+  
+  
+  
 
 
-
-  
-   Start a user-driven, interactive resize of the surface.
+
+  
+   Start a user-driven interaction on a client-side
+   decoration. Clients should send this when a user interacts
+   with the bare titlebar or edge of a client-side decoration.
 
This request must be used in response to some sort of user action
like a button press, key press, or touch down event. The passed
-   serial is used to determine the type of interactive resize (touch,
+   serial is used to determine the type of interactive action (touch,
pointer, etc).
 
-   The server may ignore resize requests depending on the state of
-   the surface (e.g. fullscreen or maximized).
-
-   If triggered, the client will receive configure events with the
-   "resize" state enum value and the expected sizes. See the "resize"
-   enum value for more details about what is required. The client
-   must also acknowledge configure events using "ack_configure". After
-   the resize is completed, the client will receive another "configure"
-   event without the resize state.
-
-   If triggered, the surface also will lose the focus of the device
-   (wl_pointer, wl_touch, etc) 

[PATCH 0/2] xdg-shell: Proposal to be more generic for decorations

2016-12-09 Thread Adam Goode
Hi,

There were many different opinions and suggestions for how to allow
for raise and lower to be bound to mouse clicks in titlebars. This
is one possible way forward. It removes some of the semantic requests
in xdg-shell and replaces it with a "interact_with_decoration"
request that lets more window management logic move into the compositor.

Comments welcome. I know this is a tricky issue, but I hope this
is leading somewhat in the right direction.


Adam



Adam Goode (2):
  xdg-shell: Introduce protocol v7
  xdg-shell: Fold several client-side decoration requests into a generic
request

 COPYING  |1 +
 unstable/xdg-shell/xdg-shell-unstable-v7.xml | 1012 ++
 2 files changed, 1013 insertions(+)
 create mode 100644 unstable/xdg-shell/xdg-shell-unstable-v7.xml

-- 
2.8.0.rc3.226.g39d4020

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


[PATCH 1/2] xdg-shell: Introduce protocol v7

2016-12-09 Thread Adam Goode
There are no changes in this from v6 to v7, that will come next.

Signed-off-by: Adam Goode 
---
 unstable/xdg-shell/xdg-shell-unstable-v7.xml | 1041 ++
 1 file changed, 1041 insertions(+)
 create mode 100644 unstable/xdg-shell/xdg-shell-unstable-v7.xml

diff --git a/unstable/xdg-shell/xdg-shell-unstable-v7.xml 
b/unstable/xdg-shell/xdg-shell-unstable-v7.xml
new file mode 100644
index 000..de5d21c
--- /dev/null
+++ b/unstable/xdg-shell/xdg-shell-unstable-v7.xml
@@ -0,0 +1,1041 @@
+
+
+
+  
+Copyright © 2008-2013 Kristian Høgsberg
+Copyright © 2013  Rafael Antognolli
+Copyright © 2013  Jasper St. Pierre
+Copyright © 2010-2013 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.
+  
+
+  
+
+  xdg_shell allows clients to turn a wl_surface into a "real window"
+  which can be dragged, resized, stacked, and moved around by the
+  user. Everything about this interface is suited towards traditional
+  desktop environments.
+
+
+
+  
+  
+  
+  
+  
+  
+
+
+
+  
+   Destroy this xdg_shell object.
+
+   Destroying a bound xdg_shell object while there are surfaces
+   still alive created by this xdg_shell object instance is illegal
+   and will result in a protocol error.
+  
+
+
+
+  
+   Create a positioner object. A positioner object is used to position
+   surfaces relative to some parent surface. See the interface description
+   and xdg_surface.get_popup for details.
+  
+  
+
+
+
+  
+   This creates an xdg_surface for the given surface. While xdg_surface
+   itself is not a role, the corresponding surface may only be assigned
+   a role extending xdg_surface, such as xdg_toplevel or xdg_popup.
+
+   This creates an xdg_surface for the given surface. An xdg_surface is
+   used as basis to define a role to a given surface, such as xdg_toplevel
+   or xdg_popup. It also manages functionality shared between xdg_surface
+   based surface roles.
+
+   See the documentation of xdg_surface for more details about what an
+   xdg_surface is and how it is used.
+  
+  
+  
+
+
+
+  
+   A client must respond to a ping event with a pong request or
+   the client may be deemed unresponsive. See xdg_shell.ping.
+  
+  
+
+
+
+  
+   The ping event asks the client if it's still alive. Pass the
+   serial specified in the event back to the compositor by sending
+   a "pong" request back with the specified serial. See xdg_shell.ping.
+
+   Compositors can use this to determine if the client is still
+   alive. It's unspecified what will happen if the client doesn't
+   respond to the ping request, or in what timeframe. Clients should
+   try to respond in a reasonable amount of time.
+
+   A compositor is free to ping in any way it wants, but a client must
+   always respond to any xdg_shell object it created.
+  
+  
+
+  
+
+  
+
+  The xdg_positioner provides a collection of rules for the placement of a
+  child surface relative to a parent surface. Rules can be defined to 
ensure
+  the child surface remains within the visible area's borders, and to
+  specify how the child surface changes its position, such as sliding along
+  an axis, or flipping around a rectangle.
+
+  See the various requests for details about possible rules.
+
+  At the time of the request, the compositor makes a copy of the rules
+  specified by the xdg_positioner. Thus, after the request is complete the
+  xdg_positioner object can be destroyed or reused; further changes to the
+  object will have no effect on previous usages.
+
+  For an xdg_positioner object to be considered 

Re: Fwd: [PATCH weston 01/68] libweston: Add pixel-format helpers

2016-12-09 Thread Armin Krezović
On 09.12.2016 22:30, Daniel Stone wrote:
> Hi,
> 

Hi,

> On 9 December 2016 at 20:37, Armin Krezović  wrote:
>> On 09.12.2016 20:57, Daniel Stone wrote:
>>>  libweston/pixel-formats.c | 398 
>>> ++
>>>  libweston/pixel-formats.h | 112 +
>>
>> Where are corresponding build system modifications?
> 
> Missing, apparently ... :\
> 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>
>> Is it supposed to work without EGL/GLESv2 enabled?
> 
> Not really, no; note that the DRM backend has a hard dependency on GBM
> and the Wayland backend has a hard dependency on libwayland-egl, so
> this only really affects people building the X11/headless backends
> only with no EGL. I suppose we could do a giant #ifdef tree, or just
> pull all the tokens we use into weston-egl-ext.h and use that. Do you
> have any preferences?
> 

Well, if my guess is correct, this is supposed to be part of libweston, no?

I don't think some people would like to have hard EGL dep on libweston itself,
and conditionally building this into the library might produce incompatible
lib with and without --disable-egl using the same source.

That said, I'm all for importing the needed bits into weston-egl-ext.h (if
you prefer to #ifdef a lot, go ahead).

>>> +/**
>>> + * Table of DRM formats supported by Weston; RGB, ARGB and YUV formats are
>>> + * supported. Indexed/greyscale formats, and formats not containing 
>>> complete
>>> + * colour channels, are not supported.
>>> + */
>>
>> I expected something using this immediately. I suggest you squash it with 
>> something
>> else that uses this.
> 
> It could be squashed with 'Store format in drm_fb', but as the
> DRM-specific parts of the series were getting very little review, and
> it can also be useful for gl-renderer's SHM uploads in particular, I
> didn't want to muddle it in with the rest of the series. Depending on
> how that goes (whether I get to porting gl-renderer, if earlier parts
> of the series get reviewed so we can merge this, etc), it can be
> squashed into its first user.
> 

Well, you could've squashed it into that patch and sent it (from what I've
seen it doesn't involve any new code and doesn't depend on anything else),
and I can help you with review and gl-renderer porting, as this can be
landed independently from rest of the series.

Even if they don't fit together, at least make the patch that uses this a
next one, so someone can take a look at example usage without having to
dig through whole series to find out what is using this.

> Cheers,
> Daniel
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH weston RFC] compositor-wayland: Support building without EGL

2016-12-09 Thread Armin Krezović
Signed-off-by: Armin Krezović 
---
 Makefile.am|  1 +
 configure.ac   |  9 ++---
 libweston/compositor-wayland.c | 23 ++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 2219e3d5..704d17af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -383,6 +383,7 @@ wayland_backend_la_LDFLAGS = -module -avoid-version
 wayland_backend_la_LIBADD =\
$(COMPOSITOR_LIBS)  \
$(WAYLAND_COMPOSITOR_LIBS)  \
+   $(WAYLAND_COMPOSITOR_EGL_LIBS)  \
libshared-cairo.la
 wayland_backend_la_CFLAGS =\
$(COMPOSITOR_CFLAGS)\
diff --git a/configure.ac b/configure.ac
index 1e251bfe..0542332c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -237,11 +237,14 @@ AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, 
$ac_wayland_protocols_pkgdatadir)
 AC_ARG_ENABLE(wayland-compositor, [  --enable-wayland-compositor],,
  enable_wayland_compositor=yes)
 AM_CONDITIONAL(ENABLE_WAYLAND_COMPOSITOR,
-  test x$enable_wayland_compositor = xyes -a x$enable_egl = xyes)
-if test x$enable_wayland_compositor = xyes -a x$enable_egl = xyes; then
+  test x$enable_wayland_compositor = xyes)
+if test x$enable_wayland_compositor = xyes; then
   AC_DEFINE([BUILD_WAYLAND_COMPOSITOR], [1],
[Build the Wayland (nested) compositor])
-  PKG_CHECK_MODULES(WAYLAND_COMPOSITOR, [wayland-client >= 
$WAYLAND_PREREQ_VERSION wayland-egl wayland-cursor])
+  PKG_CHECK_MODULES(WAYLAND_COMPOSITOR, [wayland-client >= 
$WAYLAND_PREREQ_VERSION wayland-cursor])
+  if test x$enable_egl = xyes; then
+PKG_CHECK_MODULES(WAYLAND_COMPOSITOR_EGL, [wayland-egl])
+  fi
 fi
 
 
diff --git a/libweston/compositor-wayland.c b/libweston/compositor-wayland.c
index d1e387df..925d2790 100644
--- a/libweston/compositor-wayland.c
+++ b/libweston/compositor-wayland.c
@@ -38,9 +38,12 @@
 #include 
 
 #include 
-#include 
 #include 
 
+#ifdef ENABLE_EGL
+#include 
+#endif
+
 #include "compositor.h"
 #include "compositor-wayland.h"
 #include "gl-renderer.h"
@@ -386,6 +389,7 @@ draw_initial_frame(struct wayland_output *output)
  output->base.current_mode->height);
 }
 
+#ifdef ENABLE_EGL /* Defined but not used */
 static void
 wayland_output_update_gl_border(struct wayland_output *output)
 {
@@ -455,6 +459,7 @@ wayland_output_update_gl_border(struct wayland_output 
*output)
   
cairo_image_surface_get_stride(output->gl.border.bottom) / 4,
   
cairo_image_surface_get_data(output->gl.border.bottom));
 }
+#endif
 
 static void
 wayland_output_start_repaint_loop(struct weston_output *output_base)
@@ -480,6 +485,7 @@ wayland_output_start_repaint_loop(struct weston_output 
*output_base)
wl_display_flush(wb->parent.wl_display);
 }
 
+#ifdef ENABLE_EGL
 static int
 wayland_output_repaint_gl(struct weston_output *output_base,
  pixman_region32_t *damage)
@@ -498,6 +504,7 @@ wayland_output_repaint_gl(struct weston_output *output_base,
 >primary_plane.damage, damage);
return 0;
 }
+#endif
 
 static void
 wayland_output_update_shm_border(struct wayland_shm_buffer *buffer)
@@ -665,9 +672,11 @@ wayland_output_disable(struct weston_output *base)
 
if (b->use_pixman) {
pixman_renderer_output_destroy(>base);
+#ifdef ENABLE_EGL
} else {
gl_renderer->output_destroy(>base);
wl_egl_window_destroy(output->gl.egl_window);
+#endif
}
 
wayland_output_destroy_shm_buffers(output);
@@ -702,6 +711,7 @@ wayland_output_destroy(struct weston_output *base)
 
 static const struct wl_shell_surface_listener shell_surface_listener;
 
+#ifdef ENABLE_EGL
 static int
 wayland_output_init_gl_renderer(struct wayland_output *output)
 {
@@ -737,6 +747,7 @@ cleanup_window:
wl_egl_window_destroy(output->gl.egl_window);
return -1;
 }
+#endif
 
 static int
 wayland_output_init_pixman_renderer(struct wayland_output *output)
@@ -785,6 +796,7 @@ wayland_output_resize_surface(struct wayland_output *output)
wl_region_destroy(region);
}
 
+#ifdef ENABLE_EGL
if (output->gl.egl_window) {
wl_egl_window_resize(output->gl.egl_window,
 width, height, 0, 0);
@@ -811,6 +823,7 @@ wayland_output_resize_surface(struct wayland_output *output)
cairo_surface_destroy(output->gl.border.bottom);
output->gl.border.bottom = NULL;
}
+#endif
 
wayland_output_destroy_shm_buffers(output);
 }
@@ -1037,11 +1050,13 @@ wayland_output_switch_mode(struct weston_output 
*output_base,
pixman_renderer_output_destroy(output_base);
if (wayland_output_init_pixman_renderer(output) < 

Re: [PATCH weston v2 0/68] Atomic modesetting, planes, extended drm_fb

2016-12-09 Thread Daniel Stone
Hi,

On 9 December 2016 at 19:58, Daniel Stone  wrote:
> This is v2 of the atomic patchset, which incorporates quite a few
> fixups on the original code, and extends it far enough to flip
> sprites_are_broken off for atomic. \o/

And it lives here:
git://git.collabora.com/git/user/daniels/weston#wip/phab/T7595-atomic-modeset

> First we try to construct a view made entirely out of planes and
> nothing else; if this succeeds, we just use that and we don't need to
> render anything. Failing that, we try to incrementally build a state,
> trying one view at a time on one plane at a time, and seeing if that
> changes anything. Doing this is what lets us flip sprites_are_broken,
> because we can not only generate an optimal configuration, but make
> sure it'll actually work when we do it.

There are a couple of things I'm not entirely happy with here in
hindsight, that a nice long walk has helped clarify.

The duplicate_renderer dance in drm_output_propose_state /
drm_output_prepare_scanout_view is messy, and in fact leaks the old
state when we successfully promote a view to scanout. I did play
around with special-casing the drm_plane_state_*() API to deal with
this, but didn't like the non-obviousness it introduced. I think a
cleaner solution might just be to duplicate the entire output_state;
I'll have another play around with both (and a clearer head) next
week.

The 'test plane states' commit is obscured by the fact overlay
assignment moves from picking one plane early and sticking to that, to
testing all the planes in a loop. I was trying to avoid exploding the
series into too many patches, but may have got the balance wrong
there. I'll probably change that in the next iteration.

I think we also need to delay start_repaint_loop() if we have a DPMS
off that hasn't completed; in testing just now I was able to hit a
rare breakage (hooray for asserts!) which I suspect was exactly this.

Short of this, any general commments welcome, as well as review of the
earlier patches in the series (thanks Armin!), so we can start landing
the less dangerous/controversial pieces and trim the series down a
bit. Testing on exotic platforms is always good too: I have Intel,
Rockchip (with the Mali driver), and Raspberry Pi (less interesting as
it can't put client surfaces in planes) here, and hopefully will have
Freedreno running next week. Maybe Tegra if Alexandre posts a tree
with that working too.

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


Fwd: [PATCH weston 01/68] libweston: Add pixel-format helpers

2016-12-09 Thread Daniel Stone
Hi,

On 9 December 2016 at 20:37, Armin Krezović  wrote:
> On 09.12.2016 20:57, Daniel Stone wrote:
>>  libweston/pixel-formats.c | 398 
>> ++
>>  libweston/pixel-formats.h | 112 +
>
> Where are corresponding build system modifications?

Missing, apparently ... :\

>> +#include 
>> +#include 
>> +#include 
>> +#include 
>
> Is it supposed to work without EGL/GLESv2 enabled?

Not really, no; note that the DRM backend has a hard dependency on GBM
and the Wayland backend has a hard dependency on libwayland-egl, so
this only really affects people building the X11/headless backends
only with no EGL. I suppose we could do a giant #ifdef tree, or just
pull all the tokens we use into weston-egl-ext.h and use that. Do you
have any preferences?

>> +/**
>> + * Table of DRM formats supported by Weston; RGB, ARGB and YUV formats are
>> + * supported. Indexed/greyscale formats, and formats not containing complete
>> + * colour channels, are not supported.
>> + */
>
> I expected something using this immediately. I suggest you squash it with 
> something
> else that uses this.

It could be squashed with 'Store format in drm_fb', but as the
DRM-specific parts of the series were getting very little review, and
it can also be useful for gl-renderer's SHM uploads in particular, I
didn't want to muddle it in with the rest of the series. Depending on
how that goes (whether I get to porting gl-renderer, if earlier parts
of the series get reviewed so we can merge this, etc), it can be
squashed into its first user.

Cheers,
Daniel


signature.asc
Description: PGP signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 02/68] meson: pixel-formats

2016-12-09 Thread Daniel Stone
Hi Armin,

On 9 December 2016 at 20:37, Armin Krezović  wrote:
>> diff --git a/libweston/meson.build b/libweston/meson.build
>> index d396c00..aee444a 100644
>> --- a/libweston/meson.build
>> +++ b/libweston/meson.build
>> @@ -19,6 +19,7 @@ srcs_libweston = [
>>   'noop-renderer.c',
>>   'pixman-renderer.c',
>>   'linux-dmabuf.c',
>> + 'pixel-formats.c',
>>   'screenshooter.c',
>>   '../shared/file-util.c',
>>   '../shared/matrix.c',
>>
>
> Since when is meson supported? I don't see it in git master.

Oh, it's not; it's just there to make it easier for people who want to
use Meson to build. Like me. :) It's really useful for this branch,
since when rebasing I'll frequently do 'git rebase -i --exec
[make|ninja]' along the entire branch to make sure it builds the whole
way; it's easy to introduce warnings in intermediate patches when
doing that. With 68 patches, Meson does this in around 30sec for the
whole tree, against ~4min for autotools.

Safe to say you can ignore this if you're not using Meson; it'll be
squashed into either the actual pixel-formats patch or the Meson
patch, depending on what lands first, as introducing intermediate
build breakage is bad. I wanted to keep it separate from pixel-formats
though, so that can land separately if necessary.

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


Re: [PATCH weston 41/68] [XXX] compositor-drm: Don't restore original CRTC mode

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> When leaving Weston, don't attempt to restore the previous CRTC
> settings. The framebuffer may well have disappeared, and in every
> likelihood, whoever gets the KMS device afterwards will be repainting
> anyway.
> 
> XXX: This breaks gamma. Need to work around that.
> 
> Differential Revision: https://phabricator.freedesktop.org/D1502
> 
> Signed-off-by: Daniel Stone 
> ---
>  libweston/compositor-drm.c | 20 +---
>  1 file changed, 1 insertion(+), 19 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 5959aed..2db48f1 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -297,7 +297,6 @@ struct drm_output {
>   uint32_t crtc_id; /* object ID to pass to DRM functions */
>   int pipe; /* index of CRTC in resource array / bitmasks */
>   uint32_t connector_id;
> - drmModeCrtcPtr original_crtc;
>   struct drm_edid edid;
>   drmModePropertyPtr dpms_prop;
>   uint32_t gbm_format;
> @@ -1513,8 +1512,6 @@ drm_output_set_gamma(struct weston_output *output_base,
>   /* check */
>   if (output_base->gamma_size != size)
>   return;
> - if (!output->original_crtc)
> - return;
>  
>   rc = drmModeCrtcSetGamma(backend->drm.fd,
>output->crtc_id,
> @@ -3630,8 +3627,6 @@ drm_output_set_mode(struct weston_output *base,
>   output->base.serial_number = "unknown";
>   wl_list_init(>base.mode_list);
>  
> - output->original_crtc = drmModeGetCrtc(b->drm.fd, output->crtc_id);
> -

Can't you just store gamma_size from here? No need to store the original_crtc,
just get the gamma value and let it go.

>   if (connector_get_current_mode(output->connector, b->drm.fd, 
> _mode) < 0)
>   goto err_free;
>  
> @@ -3658,9 +3653,6 @@ drm_output_set_mode(struct weston_output *base,
>   return 0;
>  
>  err_free:
> - drmModeFreeCrtc(output->original_crtc);
> - output->original_crtc = NULL;
> -
>   wl_list_for_each_safe(drm_mode, next, >base.mode_list,
>   base.link) {
>   wl_list_remove(_mode->base.link);
> @@ -3741,7 +3733,7 @@ drm_output_enable(struct weston_output *base)
>   output->base.set_dpms = drm_set_dpms;
>   output->base.switch_mode = drm_output_switch_mode;
>  
> - output->base.gamma_size = output->original_crtc->gamma_size;
> + output->base.gamma_size = 0; /* XXX */
>   output->base.set_gamma = drm_output_set_gamma;
>  
>   output->base.subpixel = 
> drm_subpixel_to_wayland(output->connector->subpixel);
> @@ -3805,7 +3797,6 @@ drm_output_destroy(struct weston_output *base)
>  {
>   struct drm_output *output = to_drm_output(base);
>   struct drm_backend *b = to_drm_backend(base->compositor);
> - drmModeCrtcPtr origcrtc = output->original_crtc;
>  
>   if (output->page_flip_pending || output->vblank_pending) {
>   output->destroy_pending = 1;
> @@ -3816,14 +3807,6 @@ drm_output_destroy(struct weston_output *base)
>   if (output->base.enabled)
>   drm_output_deinit(>base);
>  
> - if (origcrtc) {
> - /* Restore original CRTC state */
> - drmModeSetCrtc(b->drm.fd, origcrtc->crtc_id, 
> origcrtc->buffer_id,
> -origcrtc->x, origcrtc->y,
> ->connector_id, 1, >mode);
> - drmModeFreeCrtc(origcrtc);
> - }
> -
>   weston_output_destroy(>base);
>  
>   drmModeFreeConnector(output->connector);
> @@ -3914,7 +3897,6 @@ create_output_for_connector(struct drm_backend *b,
>  
>   output->destroy_pending = 0;
>   output->disable_pending = 0;
> - output->original_crtc = NULL;
>  
>   output->state_cur = drm_output_state_alloc(output);
>  
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 18/68] compositor-drm: Drop output from release_fb

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> We only need it for the GBM surface the FB was originally created
> against; a mismatch here is very bad indeed, so no reason to pass it in
> explictly every time rather than store it.
> 
> Differential Revision: https://phabricator.freedesktop.org/D1490
> 
> Signed-off-by: Daniel Stone 

Makes sense.

Reviewed-by: Armin Krezović 

> ---
>  libweston/compositor-drm.c | 20 +++-
>  1 file changed, 11 insertions(+), 9 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 7dbfc6b..eb735b2 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -148,6 +148,7 @@ struct drm_fb {
>  
>   /* Used by gbm fbs */
>   struct gbm_bo *bo;
> + struct gbm_surface *gbm_surface;
>  
>   /* Used by dumb fbs */
>   void *map;
> @@ -466,7 +467,7 @@ drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer 
> *buffer)
>  }
>  
>  static void
> -drm_output_release_fb(struct drm_output *output, struct drm_fb *fb)
> +drm_fb_unref(struct drm_fb *fb)
>  {
>   if (!fb)
>   return;
> @@ -479,7 +480,7 @@ drm_output_release_fb(struct drm_output *output, struct 
> drm_fb *fb)
>   gbm_bo_destroy(fb->bo);
>   break;
>   case BUFFER_GBM_SURFACE:
> - gbm_surface_release_buffer(output->gbm_surface, fb->bo);
> + gbm_surface_release_buffer(fb->gbm_surface, fb->bo);
>   break;
>   default:
>   assert(NULL);
> @@ -615,6 +616,7 @@ drm_output_render_gl(struct drm_output *output, 
> pixman_region32_t *damage)
>   gbm_surface_release_buffer(output->gbm_surface, bo);
>   return;
>   }
> + output->next->gbm_surface = output->gbm_surface;
>  }
>  
>  static void
> @@ -798,7 +800,7 @@ drm_output_repaint(struct weston_output *output_base,
>  err_pageflip:
>   output->cursor_view = NULL;
>   if (output->next) {
> - drm_output_release_fb(output, output->next);
> + drm_fb_unref(output->next);
>   output->next = NULL;
>   }
>  
> @@ -900,7 +902,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
> sec, unsigned int usec,
>   drm_output_update_msc(output, frame);
>   output->vblank_pending = 0;
>  
> - drm_output_release_fb(output, s->current);
> + drm_fb_unref(s->current);
>   s->current = s->next;
>   s->next = NULL;
>  
> @@ -930,7 +932,7 @@ page_flip_handler(int fd, unsigned int frame,
>* we just want to page flip to the current buffer to get an accurate
>* timestamp */
>   if (output->page_flip_pending) {
> - drm_output_release_fb(output, output->current);
> + drm_fb_unref(output->current);
>   output->current = output->next;
>   output->next = NULL;
>   }
> @@ -1452,8 +1454,8 @@ drm_output_switch_mode(struct weston_output 
> *output_base, struct weston_mode *mo
>   WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
>  
>   /* reset rendering stuff. */
> - drm_output_release_fb(output, output->current);
> - drm_output_release_fb(output, output->next);
> + drm_fb_unref(output->current);
> + drm_fb_unref(output->next);
>   output->current = output->next = NULL;
>  
>   if (b->use_pixman) {
> @@ -2672,8 +2674,8 @@ destroy_sprites(struct drm_backend *backend)
>   sprite->plane_id,
>   output->crtc_id, 0, 0,
>   0, 0, 0, 0, 0, 0, 0, 0);
> - drm_output_release_fb(output, sprite->current);
> - drm_output_release_fb(output, sprite->next);
> + drm_fb_unref(sprite->current);
> + drm_fb_unref(sprite->next);
>   weston_plane_release(>plane);
>   free(sprite);
>   }
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 16/68] compositor-drm: Store format in drm_fb

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> This uses the new pixel-format helpers, so we can also replace depth/bpp
> with these.
> 
> Signed-off-by: Daniel Stone 
> 
> Differential Revision: https://phabricator.freedesktop.org/D1513

So, this is where code added by patch 1 is being used. I suggest
squashing it with this one (unless I missed an earlier patch that
also uses it).

> ---
>  libweston/compositor-drm.c | 43 +++
>  1 file changed, 27 insertions(+), 16 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 217db32..af43a15 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -54,6 +54,7 @@
>  #include "gl-renderer.h"
>  #include "weston-egl-ext.h"
>  #include "pixman-renderer.h"
> +#include "pixel-formats.h"
>  #include "libbacklight.h"
>  #include "libinput-seat.h"
>  #include "launcher-util.h"
> @@ -140,6 +141,7 @@ struct drm_fb {
>   enum drm_fb_type type;
>  
>   uint32_t fb_id, stride, handle, size;
> + const struct pixel_format_info *format;
>   int width, height;
>   int fd;
>   struct weston_buffer_reference buffer_ref;
> @@ -267,7 +269,6 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
> height,
>  {
>   struct drm_fb *fb;
>   int ret;
> - uint32_t bpp, depth;
>  
>   struct drm_mode_create_dumb create_arg;
>   struct drm_mode_destroy_dumb destroy_arg;
> @@ -277,20 +278,20 @@ drm_fb_create_dumb(struct drm_backend *b, int width, 
> int height,
>   if (!fb)
>   return NULL;
>  
> - switch (format) {
> - case GBM_FORMAT_XRGB:
> - bpp = 32;
> - depth = 24;
> - break;
> - case GBM_FORMAT_RGB565:
> - bpp = depth = 16;
> - break;
> - default:
> - return NULL;
> + fb->format = pixel_format_get_info(format);
> + if (!fb->format) {
> + weston_log("failed to look up format 0x%lx\n",
> +(unsigned long) format);
> + goto err_fb;
> + }
> +
> + if (!fb->format->depth || !fb->format->bpp) {
> + weston_log("format 0x%lx is not compatible with dumb buffers\n",
> +(unsigned long) format);
>   }
>  
>   memset(_arg, 0, sizeof create_arg);
> - create_arg.bpp = bpp;
> + create_arg.bpp = fb->format->bpp;
>   create_arg.width = width;
>   create_arg.height = height;
>  
> @@ -316,7 +317,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
> height,
>   offsets[0] = 0;
>  
>   ret = drmModeAddFB2(b->drm.fd, width, height,
> - format, handles, pitches, offsets,
> + fb->format->format,
> + handles, pitches, offsets,
>   >fb_id, 0);
>   if (ret) {
>   weston_log("addfb2 failed: %m\n");
> @@ -325,7 +327,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
> height,
>   }
>  
>   if (ret) {
> - ret = drmModeAddFB(b->drm.fd, width, height, depth, bpp,
> + ret = drmModeAddFB(b->drm.fd, width, height,
> +fb->format->depth, fb->format->bpp,
>  fb->stride, fb->handle, >fb_id);
>   }
>  
> @@ -402,9 +405,16 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
> *backend,
>   fb->height = gbm_bo_get_height(bo);
>   fb->stride = gbm_bo_get_stride(bo);
>   fb->handle = gbm_bo_get_handle(bo).u32;
> + fb->format = pixel_format_get_info(format);
>   fb->size = fb->stride * fb->height;
>   fb->fd = backend->drm.fd;
>  
> + if (!fb->format) {
> + weston_log("couldn't look up format 0x%lx\n",
> +(unsigned long) format);
> + goto err_free;
> + }
> +
>   if (backend->min_width > fb->width ||
>   fb->width > backend->max_width ||
>   backend->min_height > fb->height ||
> @@ -430,9 +440,10 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
> *backend,
>   }
>   }
>  
> - if (ret)
> + if (ret && fb->format->depth && fb->format->bpp)
>   ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
> -24, 32, fb->stride, fb->handle, >fb_id);
> +fb->format->depth, fb->format->bpp,
> +fb->stride, fb->handle, >fb_id);
>  
>   if (ret) {
>   weston_log("failed to create kms fb: %m\n");
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org

Re: [PATCH weston 14/68] compositor-drm: Store width and height inside drm_fb

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> This will be used so we can later determine the compatibility of drm_fbs
> without needing to introspect external state.
> 
> Differential Revision: https://phabricator.freedesktop.org/D1487
> 
> Signed-off-by: Daniel Stone 

Looks fine.

Reviewed-by: Armin Krezović 

> ---
>  libweston/compositor-drm.c | 24 +---
>  1 file changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index a5052b9..4ef7343 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -131,6 +131,7 @@ struct drm_mode {
>  
>  struct drm_fb {
>   uint32_t fb_id, stride, handle, size;
> + int width, height;
>   int fd;
>   int is_client_buffer;
>   struct weston_buffer_reference buffer_ref;
> @@ -292,6 +293,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
> height,
>   fb->handle = create_arg.handle;
>   fb->stride = create_arg.pitch;
>   fb->size = create_arg.size;
> + fb->width = width;
> + fb->height = height;
>   fb->fd = b->drm.fd;
>  
>   ret = -1;
> @@ -371,7 +374,6 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>  struct drm_backend *backend, uint32_t format)
>  {
>   struct drm_fb *fb = gbm_bo_get_user_data(bo);
> - int width, height;
>   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
>   int ret;
>  
> @@ -384,17 +386,17 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>  
>   fb->bo = bo;
>  
> - width = gbm_bo_get_width(bo);
> - height = gbm_bo_get_height(bo);
> + fb->width = gbm_bo_get_width(bo);
> + fb->height = gbm_bo_get_height(bo);
>   fb->stride = gbm_bo_get_stride(bo);
>   fb->handle = gbm_bo_get_handle(bo).u32;
> - fb->size = fb->stride * height;
> + fb->size = fb->stride * fb->height;
>   fb->fd = backend->drm.fd;
>  
> - if (backend->min_width > width ||
> - width > backend->max_width ||
> - backend->min_height > height ||
> - height > backend->max_height) {
> + if (backend->min_width > fb->width ||
> + fb->width > backend->max_width ||
> + backend->min_height > fb->height ||
> + fb->height > backend->max_height) {
>   weston_log("bo geometry out of bounds\n");
>   goto err_free;
>   }
> @@ -406,7 +408,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>   pitches[0] = fb->stride;
>   offsets[0] = 0;
>  
> - ret = drmModeAddFB2(backend->drm.fd, width, height,
> + ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
>   format, handles, pitches, offsets,
>   >fb_id, 0);
>   if (ret) {
> @@ -417,8 +419,8 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>   }
>  
>   if (ret)
> - ret = drmModeAddFB(backend->drm.fd, width, height, 24, 32,
> -fb->stride, fb->handle, >fb_id);
> + ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
> +24, 32, fb->stride, fb->handle, >fb_id);
>  
>   if (ret) {
>   weston_log("failed to create kms fb: %m\n");
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 13/68] compositor-drm: Use signed int for width/height

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> This makes it sign-compatible with weston_output->{width,height}.
> 
> Differential Revision: https://phabricator.freedesktop.org/D1486
> 
> Signed-off-by: Daniel Stone 
> Reviewed-by: Quentin Glidic 

Makes sense

Reviewed-by: Armin Krezović 

> ---
>  libweston/compositor-drm.c | 11 ++-
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index a9bde0c..a5052b9 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -104,8 +104,8 @@ struct drm_backend {
>* due to out of bounds dimensions, and then mistakenly set
>* sprites_are_broken:
>*/
> - uint32_t min_width, max_width;
> - uint32_t min_height, max_height;
> + int min_width, max_width;
> + int min_height, max_height;
>   int no_addfb2;
>  
>   struct wl_list sprite_list;
> @@ -253,7 +253,7 @@ drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
>  }
>  
>  static struct drm_fb *
> -drm_fb_create_dumb(struct drm_backend *b, unsigned width, unsigned height,
> +drm_fb_create_dumb(struct drm_backend *b, int width, int height,
>  uint32_t format)
>  {
>   struct drm_fb *fb;
> @@ -371,7 +371,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>  struct drm_backend *backend, uint32_t format)
>  {
>   struct drm_fb *fb = gbm_bo_get_user_data(bo);
> - uint32_t width, height;
> + int width, height;
>   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
>   int ret;
>  
> @@ -391,7 +391,8 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>   fb->size = fb->stride * height;
>   fb->fd = backend->drm.fd;
>  
> - if (backend->min_width > width || width > backend->max_width ||
> + if (backend->min_width > width ||
> + width > backend->max_width ||
>   backend->min_height > height ||
>   height > backend->max_height) {
>   weston_log("bo geometry out of bounds\n");
> 

Ha, the patch description didn't mention coding style fix!

(Just kidding)



signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 12/68] compositor-drm: Use fb->fd consistently

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> Everyone else uses fb->fd rather than pulling the FD back out of GBM.
> Use that in the destroy callback too.
> 
> Signed-off-by: Daniel Stone 
> 

Makes sense.

Reviewed-by: Armin Krezović 

> Differential Revision: https://phabricator.freedesktop.org/D1406
> ---
>  libweston/compositor-drm.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 3276ed0..a9bde0c 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -243,10 +243,9 @@ static void
>  drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
>  {
>   struct drm_fb *fb = data;
> - struct gbm_device *gbm = gbm_bo_get_device(bo);
>  
>   if (fb->fb_id)
> - drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id);
> + drmModeRmFB(fb->fd, fb->fb_id);
>  
>   weston_buffer_reference(>buffer_ref, NULL);
>  
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 09/68] compositor-drm: Reshuffle and comment plane conditions

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> Try to harmonise the various plane-import paths a little bit, starting
> with reshuffling and commenting the conditions to do so.
> 
> Signed-off-by: Daniel Stone 
> 

This makes code more readable and understandable. So have a

Reviewed-by: Armin Krezović 

> Differential Revision: https://phabricator.freedesktop.org/D1413
> ---
>  libweston/compositor-drm.c | 79 
> --
>  1 file changed, 48 insertions(+), 31 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 5fb45b4..8cd9d5a 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -502,18 +502,28 @@ drm_output_prepare_scanout_view(struct drm_output 
> *output,
>   struct gbm_bo *bo;
>   uint32_t format;
>  
> - if (ev->geometry.x != output->base.x ||
> - ev->geometry.y != output->base.y ||
> - buffer == NULL || b->gbm == NULL ||
> - buffer->width != output->base.current_mode->width ||
> - buffer->height != output->base.current_mode->height ||
> - output->base.transform != viewport->buffer.transform ||
> - ev->transform.enabled)
> + /* We use GBM to import buffers. */
> + if (b->gbm == NULL)
> + return NULL;
> +
> + if (buffer == NULL)
>   return NULL;
>  
> + /* Make sure our view is exactly compatible with the output. */
> + if (ev->geometry.x != output->base.x ||
> + ev->geometry.y != output->base.y)
> + return NULL;
> + if (ev->transform.enabled)
> + return NULL;
>   if (ev->geometry.scissor_enabled)
>   return NULL;
>  
> + if (buffer->width != output->base.current_mode->width ||
> + buffer->height != output->base.current_mode->height)
> + return NULL;
> + if (viewport->buffer.transform != output->base.transform)
> + return NULL;
> +
>   bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
>  buffer->resource, GBM_BO_USE_SCANOUT);
>  
> @@ -950,34 +960,33 @@ drm_output_prepare_overlay_view(struct drm_output 
> *output,
>   uint32_t format;
>   wl_fixed_t sx1, sy1, sx2, sy2;
>  
> - if (b->gbm == NULL)
> - return NULL;
> -
> - if (viewport->buffer.transform != output->base.transform)
> - return NULL;
> -
> - if (viewport->buffer.scale != output->base.current_scale)
> - return NULL;
> -
>   if (b->sprites_are_broken)
>   return NULL;
>  
> + /* Don't import buffers which span multiple outputs. */
>   if (ev->output_mask != (1u << output->base.id))
>   return NULL;
>  
> - if (ev->surface->buffer_ref.buffer == NULL)
> + /* We can only import GBM buffers. */
> + if (b->gbm == NULL)
>   return NULL;
> - buffer_resource = ev->surface->buffer_ref.buffer->resource;
>  
> - if (ev->alpha != 1.0f)
> + if (ev->surface->buffer_ref.buffer == NULL)
>   return NULL;
> -
> + buffer_resource = ev->surface->buffer_ref.buffer->resource;
>   if (wl_shm_buffer_get(buffer_resource))
>   return NULL;
>  
> + if (viewport->buffer.transform != output->base.transform)
> + return NULL;
> + if (viewport->buffer.scale != output->base.current_scale)
> + return NULL;
>   if (!drm_view_transform_supported(ev))
>   return NULL;
>  
> + if (ev->alpha != 1.0f)
> + return NULL;
> +
>   wl_list_for_each(s, >sprite_list, link) {
>   if (!drm_sprite_crtc_supported(output, s))
>   continue;
> @@ -1114,23 +1123,20 @@ drm_output_prepare_cursor_view(struct drm_output 
> *output,
>   struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
>   struct wl_shm_buffer *shmbuf;
>  
> - if (ev->transform.enabled &&
> - (ev->transform.matrix.type > WESTON_MATRIX_TRANSFORM_TRANSLATE))
> - return NULL;
> - if (b->gbm == NULL)
> - return NULL;
> - if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
> - return NULL;
> - if (viewport->buffer.scale != output->base.current_scale)
> + if (b->cursors_are_broken)
>   return NULL;
> +
>   if (output->cursor_view)
>   return NULL;
> +
> + /* Don't import buffers which span multiple outputs. */
>   if (ev->output_mask != (1u << output->base.id))
>   return NULL;
> - if (b->cursors_are_broken)
> - return NULL;
> - if (ev->geometry.scissor_enabled)
> +
> + /* We use GBM to import SHM buffers. */
> + if (b->gbm == NULL)
>   return NULL;
> +
>   if (ev->surface->buffer_ref.buffer == NULL)
>   return NULL;
>   shmbuf = wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource);
> @@ -1138,6 

Re: [PATCH weston 04/68] compositor-drm: Delete drm_backend_set_modes

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> Even if we do have a framebuffer matching the mode, we immediately
> schedule a repaint, meaning we either do work for no reason, or show
> stale content before we bring up the new content.
> 
> Delete this and just let repaint deal with it.
> 
> Differential Revision: https://phabricator.freedesktop.org/D1481
> 
> Signed-off-by: Daniel Stone 

Since drm_output_repaint() calls drmModeSetCrtc() when needed and
weston_compositor_damage_all() will schedule a repaint, this makes
sense.

Reviewed-by: Armin Krezović 

> ---
>  libweston/compositor-drm.c | 33 -
>  1 file changed, 33 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 268117d..7d1c01b 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -2824,38 +2824,6 @@ drm_destroy(struct weston_compositor *ec)
>  }
>  
>  static void
> -drm_backend_set_modes(struct drm_backend *backend)
> -{
> - struct drm_output *output;
> - struct drm_mode *drm_mode;
> - int ret;
> -
> - wl_list_for_each(output, >compositor->output_list, base.link) {
> - if (!output->current) {
> - /* If something that would cause the output to
> -  * switch mode happened while in another vt, we
> -  * might not have a current drm_fb. In that case,
> -  * schedule a repaint and let drm_output_repaint
> -  * handle setting the mode. */
> - weston_output_schedule_repaint(>base);
> - continue;
> - }
> -
> - drm_mode = (struct drm_mode *) output->base.current_mode;
> - ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
> -  output->current->fb_id, 0, 0,
> -  >connector_id, 1,
> -  _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);
> - }
> - }
> -}
> -
> -static void
>  session_notify(struct wl_listener *listener, void *data)
>  {
>   struct weston_compositor *compositor = data;
> @@ -2866,7 +2834,6 @@ session_notify(struct wl_listener *listener, void *data)
>   if (compositor->session_active) {
>   weston_log("activating session\n");
>   compositor->state = b->prev_state;
> - drm_backend_set_modes(b);
>   weston_compositor_damage_all(compositor);
>   udev_input_enable(>input);
>   } else {
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 03/68] compositor-drm: Comment struct members

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> Clarify the difference between crtc_id (DRM object) and pipe (index into
> drmModeRes->crtcs array, possible_crtcs bitmask).
> 
> Signed-off-by: Daniel Stone 
> Reviewed-by: Quentin Glidic 
> Differential Revision: https://phabricator.freedesktop.org/D1405

Documenting structure members is always welcome.

Reviewed-by: Armin Krezović 

(this time it's me!)

> ---
>  libweston/compositor-drm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index a899213..268117d 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -155,8 +155,8 @@ struct drm_output {
>   struct weston_output base;
>   drmModeConnector *connector;
>  
> - uint32_t crtc_id;
> - int pipe;
> + uint32_t crtc_id; /* object ID to pass to DRM functions */
> + int pipe; /* index of CRTC in resource array / bitmasks */
>   uint32_t connector_id;
>   drmModeCrtcPtr original_crtc;
>   struct drm_edid edid;
> 




signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 02/68] meson: pixel-formats

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> Differential Revision: https://phabricator.freedesktop.org/D1512
> ---
>  libweston/meson.build | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/libweston/meson.build b/libweston/meson.build
> index d396c00..aee444a 100644
> --- a/libweston/meson.build
> +++ b/libweston/meson.build
> @@ -19,6 +19,7 @@ srcs_libweston = [
>   'noop-renderer.c',
>   'pixman-renderer.c',
>   'linux-dmabuf.c',
> + 'pixel-formats.c',
>   'screenshooter.c',
>   '../shared/file-util.c',
>   '../shared/matrix.c',
> 

Since when is meson supported? I don't see it in git master.



signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 01/68] libweston: Add pixel-format helpers

2016-12-09 Thread Armin Krezović
On 09.12.2016 20:57, Daniel Stone wrote:
> Rather than duplicating knowledge of pixel formats across several
> components, create a custom central repository.
> 

Hi,

> Signed-off-by: Daniel Stone 
> 
> Differential Revision: https://phabricator.freedesktop.org/D1511
> ---
>  libweston/pixel-formats.c | 398 
> ++
>  libweston/pixel-formats.h | 112 +
>  2 files changed, 510 insertions(+)
>  create mode 100644 libweston/pixel-formats.c
>  create mode 100644 libweston/pixel-formats.h
> 

Where are corresponding build system modifications?

> diff --git a/libweston/pixel-formats.c b/libweston/pixel-formats.c
> new file mode 100644
> index 000..9c70e73
> --- /dev/null
> +++ b/libweston/pixel-formats.c
> @@ -0,0 +1,398 @@
> +/*
> + * Copyright © 2016 Collabora, Ltd.
> + *
> + * 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.
> + *
> + * Author: Daniel Stone 
> + */
> +
> +#include "config.h"
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "helpers.h"
> +#include "wayland-util.h"
> +#include "pixel-formats.h"
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +

Is it supposed to work without EGL/GLESv2 enabled?

> +#include "weston-egl-ext.h"
> +
> +/**
> + * Table of DRM formats supported by Weston; RGB, ARGB and YUV formats are
> + * supported. Indexed/greyscale formats, and formats not containing complete
> + * colour channels, are not supported.
> + */

I expected something using this immediately. I suggest you squash it with 
something
else that uses this.



signature.asc
Description: OpenPGP digital signature
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH weston 61/68] compositor-drm: Ignore views on other outputs

2016-12-09 Thread Daniel Stone
When we come to assign_planes, try very hard to ignore views which are
only visible on other outputs, rather than forcibly moving them to the
primary plane, which causes damage all round and unnecessary repaints.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1530
---
 libweston/compositor-drm.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index be2b4ea..dc68768 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1409,10 +1409,6 @@ drm_fb_get_from_view(struct drm_output_state *state, 
struct weston_view *ev)
struct linux_dmabuf_buffer *dmabuf;
struct drm_fb *fb;
 
-   /* Don't import buffers which span multiple outputs. */
-   if (ev->output_mask != (1u << output->base.id))
-   return NULL;
-
if (ev->alpha != 1.0f)
return NULL;
 
@@ -2504,10 +2500,6 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
if (plane->state_cur->output && plane->state_cur->output != output)
return NULL;
 
-   /* Don't import buffers which span multiple outputs. */
-   if (ev->output_mask != (1u << output->base.id))
-   return NULL;
-
/* We use GBM to import SHM buffers. */
if (b->gbm == NULL)
return NULL;
@@ -2666,13 +2658,22 @@ drm_output_propose_state(struct weston_output 
*output_base)
wl_list_for_each(ev, _base->compositor->view_list, link) {
struct weston_plane *next_plane = NULL;
 
+   /* If this view doesn't touch our output at all, there's no
+* reason to do anything with it. */
+   if (!(ev->output_mask & (1u << output->base.id)))
+   continue;
+
+   /* We only assign planes to views which are exclusively present
+* on our output. */
+   if (ev->output_mask != (1u << output->base.id))
+   next_plane = primary;
+
/* Since we process views from top to bottom, we know that if
 * the view intersects the calculated renderer region, it must
 * be part of, or occluded by, it, and cannot go on a plane. */
pixman_region32_init(_overlap);
pixman_region32_intersect(_overlap, _region,
  >transform.boundingbox);
-
if (pixman_region32_not_empty(_overlap))
next_plane = primary;
pixman_region32_fini(_overlap);
@@ -2711,6 +2712,11 @@ drm_assign_planes(struct weston_output *output_base)
wl_list_for_each(ev, _base->compositor->view_list, link) {
struct drm_plane *target_plane = NULL;
 
+   /* If this view doesn't touch our output at all, there's no
+* reason to do anything with it. */
+   if (!(ev->output_mask & (1u << output->base.id)))
+   continue;
+
/* Test whether this buffer can ever go into a plane:
 * non-shm, or small enough to be a cursor.
 *
-- 
2.9.3

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


[PATCH weston 22/68] compositor-drm: Rename current/next FB members

2016-12-09 Thread Daniel Stone
'next' is used as a framebuffer which has either been rendered but not
had a configuration request (pageflip or CRTC set) applied to it, or
when for a framebuffer that has had configuration requested but not
applied (delayed pageflip where the event has not been applied).

'current' is used as the last framebuffer for which we know
configuration has been fully applied, i.e. CRTC set executed or pageflip
requested and event received.

Rename these members to fb_current and fb_pending.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1410
---
 libweston/compositor-drm.c | 86 +++---
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 557b97d..8071737 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -190,7 +190,7 @@ struct drm_output {
int current_cursor;
 
struct weston_plane fb_plane;
-   struct drm_fb *current, *next;
+   struct drm_fb *fb_current, *fb_pending;
struct backlight *backlight;
 
struct drm_fb *dumb[2];
@@ -211,7 +211,7 @@ struct drm_sprite {
 
struct weston_plane plane;
 
-   struct drm_fb *current, *next;
+   struct drm_fb *fb_current, *fb_pending;
struct drm_output *output;
struct drm_backend *backend;
 
@@ -604,13 +604,13 @@ drm_output_prepare_scanout_view(struct drm_output *output,
return NULL;
}
 
-   output->next = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
-   if (!output->next) {
+   output->fb_pending = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
+   if (!output->fb_pending) {
gbm_bo_destroy(bo);
return NULL;
}
 
-   drm_fb_set_buffer(output->next, buffer);
+   drm_fb_set_buffer(output->fb_pending, buffer);
 
return >fb_plane;
 }
@@ -630,14 +630,14 @@ drm_output_render_gl(struct drm_output *output, 
pixman_region32_t *damage)
return;
}
 
-   output->next = drm_fb_get_from_bo(bo, b, output->gbm_format,
- BUFFER_GBM_SURFACE);
-   if (!output->next) {
+   output->fb_pending = drm_fb_get_from_bo(bo, b, output->gbm_format,
+   BUFFER_GBM_SURFACE);
+   if (!output->fb_pending) {
weston_log("failed to get drm_fb for bo\n");
gbm_surface_release_buffer(output->gbm_surface, bo);
return;
}
-   output->next->gbm_surface = output->gbm_surface;
+   output->fb_pending->gbm_surface = output->gbm_surface;
 }
 
 static void
@@ -656,7 +656,7 @@ drm_output_render_pixman(struct drm_output *output, 
pixman_region32_t *damage)
 
output->current_image ^= 1;
 
-   output->next = drm_fb_ref(output->dumb[output->current_image]);
+   output->fb_pending = drm_fb_ref(output->dumb[output->current_image]);
pixman_renderer_output_set_buffer(>base,
  output->image[output->current_image]);
 
@@ -742,16 +742,16 @@ drm_output_repaint(struct weston_output *output_base,
if (output->disable_pending || output->destroy_pending)
return -1;
 
-   if (!output->next)
+   if (!output->fb_pending)
drm_output_render(output, damage);
-   if (!output->next)
+   if (!output->fb_pending)
return -1;
 
mode = container_of(output->base.current_mode, struct drm_mode, base);
-   if (!output->current ||
-   output->current->stride != output->next->stride) {
+   if (!output->fb_current ||
+   output->fb_current->stride != output->fb_pending->stride) {
ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
-output->next->fb_id, 0, 0,
+output->fb_pending->fb_id, 0, 0,
 >connector_id, 1,
 >mode_info);
if (ret) {
@@ -762,7 +762,7 @@ drm_output_repaint(struct weston_output *output_base,
}
 
if (drmModePageFlip(backend->drm.fd, output->crtc_id,
-   output->next->fb_id,
+   output->fb_pending->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
weston_log("queueing pageflip failed: %m\n");
goto err_pageflip;
@@ -782,12 +782,12 @@ drm_output_repaint(struct weston_output *output_base,
.request.sequence = 1,
};
 
-   if ((!s->current && !s->next) ||
+   if ((!s->fb_current && !s->fb_pending) ||
!drm_sprite_crtc_supported(output, s))
continue;
 
-   if (s->next && !backend->sprites_hidden)
-   

[PATCH weston 65/68] compositor-drm: Return plane state from plane preparation

2016-12-09 Thread Daniel Stone
Return a pointer to the plane state, rather than indirecting via a
weston_plane.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1534
---
 libweston/compositor-drm.c | 52 --
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 5db0a1a..e51a5b2 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1667,7 +1667,7 @@ enum drm_output_propose_state_mode {
DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY, /**< only assign to planes */
 };
 
-static struct weston_plane *
+static struct drm_plane_state *
 drm_output_prepare_scanout_view(struct drm_output_state *output_state,
struct weston_view *ev)
 {
@@ -1706,7 +1706,7 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
state->dest_h != (unsigned) output->base.current_mode->height)
goto err;
 
-   return _plane->base;
+   return state;
 
 err:
drm_plane_state_put_back(state);
@@ -2399,7 +2399,7 @@ atomic_flip_handler(int fd, unsigned int frame,
drm_output_update_complete(output, flags, sec, usec);
 }
 
-static struct weston_plane *
+static struct drm_plane_state *
 drm_output_prepare_overlay_view(struct drm_output_state *output_state,
struct weston_view *ev)
 {
@@ -2462,7 +2462,7 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
state->src_h != state->dest_h << 16)
goto err;
 
-   return >base;
+   return state;
 
 err:
drm_plane_state_put_back(state);
@@ -2506,7 +2506,7 @@ cursor_bo_update(struct drm_backend *b, struct gbm_bo *bo,
weston_log("failed update cursor: %m\n");
 }
 
-static struct weston_plane *
+static struct drm_plane_state *
 drm_output_prepare_cursor_view(struct drm_output_state *output_state,
   struct weston_view *ev)
 {
@@ -2595,7 +2595,7 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
if (needs_update)
cursor_bo_update(b, plane_state->fb->bo, ev);
 
-   return >base;
+   return plane_state;
 
 err:
drm_plane_state_put_back(plane_state);
@@ -2664,7 +2664,6 @@ drm_output_propose_state(struct weston_output 
*output_base,
struct drm_output_state *state;
struct weston_view *ev;
pixman_region32_t surface_overlap, renderer_region, occluded_region;
-   struct weston_plane *primary = _base->compositor->primary_plane;
bool renderer_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
bool planes_ok = !b->sprites_are_broken;
 
@@ -2691,7 +2690,8 @@ drm_output_propose_state(struct weston_output 
*output_base,
pixman_region32_init(_region);
 
wl_list_for_each(ev, _base->compositor->view_list, link) {
-   struct weston_plane *next_plane = NULL;
+   struct drm_plane_state *ps = NULL;
+   bool force_renderer = false;
bool occluded = false;
 
/* If this view doesn't touch our output at all, there's no
@@ -2702,7 +2702,7 @@ drm_output_propose_state(struct weston_output 
*output_base,
/* We only assign planes to views which are exclusively present
 * on our output. */
if (ev->output_mask != (1u << output->base.id))
-   next_plane = primary;
+   force_renderer = true;
 
/* Ignore views we know to be totally occluded. */
pixman_region32_init(_overlap);
@@ -2721,9 +2721,12 @@ drm_output_propose_state(struct weston_output 
*output_base,
pixman_region32_intersect(_overlap, _region,
  >transform.boundingbox);
if (pixman_region32_not_empty(_overlap))
-   next_plane = primary;
+   force_renderer = true;
pixman_region32_fini(_overlap);
 
+   if (force_renderer && !renderer_ok)
+   goto err;
+
if (drm_view_is_opaque(ev))
pixman_region32_union(_region,
  _region,
@@ -2732,24 +2735,23 @@ drm_output_propose_state(struct weston_output 
*output_base,
/* The cursor plane is 'special' in the sense that we can still
 * place it in the legacy API, and we gate that with a separate
 * cursors_are_broken flag. */
-   if (next_plane == NULL && !b->cursors_are_broken)
-   next_plane = drm_output_prepare_cursor_view(state, ev);
+   if (!force_renderer && !b->cursors_are_broken)
+   ps = drm_output_prepare_cursor_view(state, ev);
if (!planes_ok)
-  

[PATCH weston 34/68] compositor-drm: Introduce drm_plane_state structure

2016-12-09 Thread Daniel Stone
Track dynamic plane state (CRTC, FB, position) in separate structures,
rather than as part of the plane. This will make it easier to handle
state management later, and much more closely tracks what the kernel
does with atomic modesets.

The fb_last pointer previously used in drm_plane now becomes part of
output->state_last, and is not directly visible from the plane itself.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1412
---
 libweston/compositor-drm.c | 330 -
 1 file changed, 270 insertions(+), 60 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 106d851..43b36f8 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -230,6 +230,29 @@ struct drm_edid {
  */
 struct drm_output_state {
struct drm_output *output;
+
+   struct wl_list plane_list;
+};
+
+/**
+ * Plane state holds the dynamic state for a plane: where it is positioned,
+ * and which buffer it is currently displaying.
+ */
+struct drm_plane_state {
+   struct drm_plane *plane;
+   struct drm_output *output;
+   struct drm_output_state *output_state;
+
+   struct drm_fb *fb;
+
+   int32_t src_x, src_y;
+   uint32_t src_w, src_h;
+   uint32_t dest_x, dest_y;
+   uint32_t dest_w, dest_h;
+
+   bool complete;
+
+   struct wl_list link; /* drm_output_state::plane_list */
 };
 
 /**
@@ -248,14 +271,12 @@ struct drm_output_state {
  * are referred to as 'sprites'.
  */
 struct drm_plane {
-   struct wl_list link;
-
struct weston_plane base;
 
-   struct drm_fb *fb_current, *fb_pending, *fb_last;
-   struct drm_output *output;
struct drm_backend *backend;
 
+   struct drm_plane_state *state_cur;
+
enum wdrm_plane_type type;
struct plane_properties props;
 
@@ -263,10 +284,7 @@ struct drm_plane {
uint32_t plane_id;
uint32_t count_formats;
 
-   int32_t src_x, src_y;
-   uint32_t src_w, src_h;
-   uint32_t dest_x, dest_y;
-   uint32_t dest_w, dest_h;
+   struct wl_list link;
 
uint32_t formats[];
 };
@@ -936,6 +954,134 @@ drm_fb_unref(struct drm_fb *fb)
 }
 
 /**
+ * Allocate a new, empty, plane state.
+ */
+static struct drm_plane_state *
+drm_plane_state_alloc(struct drm_output_state *state_output,
+ struct drm_plane *plane)
+{
+   struct drm_plane_state *state = calloc(1, sizeof(*state));
+
+   assert(state);
+   state->output_state = state_output;
+   state->plane = plane;
+
+   /* Here we only add the plane state to the desired link, and not
+* set the member. Having an output pointer set means that the
+* plane will be displayed on the output; this won't be the case
+* when we go to disable a plane. In this case, it must be part of
+* the commit (and thus the output state), but the member must be
+* NULL, as it will not be on any output when the state takes
+* effect.
+*/
+   if (state_output)
+   wl_list_insert(_output->plane_list, >link);
+   else
+   wl_list_init(>link);
+
+   return state;
+}
+
+/**
+ * Free an existing plane state. As a special case, the state will not
+ * normally be freed if it is the current state; see drm_plane_set_state.
+ */
+static void
+drm_plane_state_free(struct drm_plane_state *state, bool force)
+{
+   if (!state)
+   return;
+
+   wl_list_remove(>link);
+   wl_list_init(>link);
+   state->output_state = NULL;
+
+   if (force || state != state->plane->state_cur) {
+   drm_fb_unref(state->fb);
+   free(state);
+   }
+}
+
+/**
+ * Duplicate an existing plane state into a new output state.
+ */
+static struct drm_plane_state *
+drm_plane_state_duplicate(struct drm_output_state *state_output,
+ struct drm_plane_state *src)
+{
+   struct drm_plane_state *dst = malloc(sizeof(*dst));
+   struct drm_plane_state *old, *tmp;
+
+   assert(src);
+   assert(dst);
+   memcpy(dst, src, sizeof(*dst));
+
+   wl_list_for_each_safe(old, tmp, _output->plane_list, link) {
+   if (old->plane == dst->plane)
+   drm_plane_state_free(old, false);
+   }
+
+   wl_list_insert(_output->plane_list, >link);
+   if (src->fb)
+   dst->fb = drm_fb_ref(src->fb);
+   dst->output_state = state_output;
+   dst->complete = false;
+
+   return dst;
+}
+
+/**
+ * Remove a plane state from an output state; if the plane was previously
+ * enabled, then replace it with a disabling state. This ensures that the
+ * output state was untouched from it was before the plane state was
+ * modified by the caller of this function.
+ *
+ * This is required as drm_output_state_get_plane may either allocate a
+ * new plane state, in which case this 

[PATCH weston 41/68] [XXX] compositor-drm: Don't restore original CRTC mode

2016-12-09 Thread Daniel Stone
When leaving Weston, don't attempt to restore the previous CRTC
settings. The framebuffer may well have disappeared, and in every
likelihood, whoever gets the KMS device afterwards will be repainting
anyway.

XXX: This breaks gamma. Need to work around that.

Differential Revision: https://phabricator.freedesktop.org/D1502

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 5959aed..2db48f1 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -297,7 +297,6 @@ struct drm_output {
uint32_t crtc_id; /* object ID to pass to DRM functions */
int pipe; /* index of CRTC in resource array / bitmasks */
uint32_t connector_id;
-   drmModeCrtcPtr original_crtc;
struct drm_edid edid;
drmModePropertyPtr dpms_prop;
uint32_t gbm_format;
@@ -1513,8 +1512,6 @@ drm_output_set_gamma(struct weston_output *output_base,
/* check */
if (output_base->gamma_size != size)
return;
-   if (!output->original_crtc)
-   return;
 
rc = drmModeCrtcSetGamma(backend->drm.fd,
 output->crtc_id,
@@ -3630,8 +3627,6 @@ drm_output_set_mode(struct weston_output *base,
output->base.serial_number = "unknown";
wl_list_init(>base.mode_list);
 
-   output->original_crtc = drmModeGetCrtc(b->drm.fd, output->crtc_id);
-
if (connector_get_current_mode(output->connector, b->drm.fd, 
_mode) < 0)
goto err_free;
 
@@ -3658,9 +3653,6 @@ drm_output_set_mode(struct weston_output *base,
return 0;
 
 err_free:
-   drmModeFreeCrtc(output->original_crtc);
-   output->original_crtc = NULL;
-
wl_list_for_each_safe(drm_mode, next, >base.mode_list,
base.link) {
wl_list_remove(_mode->base.link);
@@ -3741,7 +3733,7 @@ drm_output_enable(struct weston_output *base)
output->base.set_dpms = drm_set_dpms;
output->base.switch_mode = drm_output_switch_mode;
 
-   output->base.gamma_size = output->original_crtc->gamma_size;
+   output->base.gamma_size = 0; /* XXX */
output->base.set_gamma = drm_output_set_gamma;
 
output->base.subpixel = 
drm_subpixel_to_wayland(output->connector->subpixel);
@@ -3805,7 +3797,6 @@ drm_output_destroy(struct weston_output *base)
 {
struct drm_output *output = to_drm_output(base);
struct drm_backend *b = to_drm_backend(base->compositor);
-   drmModeCrtcPtr origcrtc = output->original_crtc;
 
if (output->page_flip_pending || output->vblank_pending) {
output->destroy_pending = 1;
@@ -3816,14 +3807,6 @@ drm_output_destroy(struct weston_output *base)
if (output->base.enabled)
drm_output_deinit(>base);
 
-   if (origcrtc) {
-   /* Restore original CRTC state */
-   drmModeSetCrtc(b->drm.fd, origcrtc->crtc_id, 
origcrtc->buffer_id,
-  origcrtc->x, origcrtc->y,
-  >connector_id, 1, >mode);
-   drmModeFreeCrtc(origcrtc);
-   }
-
weston_output_destroy(>base);
 
drmModeFreeConnector(output->connector);
@@ -3914,7 +3897,6 @@ create_output_for_connector(struct drm_backend *b,
 
output->destroy_pending = 0;
output->disable_pending = 0;
-   output->original_crtc = NULL;
 
output->state_cur = drm_output_state_alloc(output);
 
-- 
2.9.3

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


[PATCH weston 15/68] compositor-drm: Add explicit type member to drm_fb

2016-12-09 Thread Daniel Stone
Rather than magically trying to infer what the buffer is and what we
should do with it when we go to destroy it, add an explicit type
instead.

Differential Revision: https://phabricator.freedesktop.org/D1488

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 50 +-
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 4ef7343..217db32 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -129,11 +129,19 @@ struct drm_mode {
drmModeModeInfo mode_info;
 };
 
+enum drm_fb_type {
+   BUFFER_INVALID = 0, /**< never used */
+   BUFFER_CLIENT, /**< directly sourced from client */
+   BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
+   BUFFER_GBM_SURFACE, /**< internal EGL rendering */
+};
+
 struct drm_fb {
+   enum drm_fb_type type;
+
uint32_t fb_id, stride, handle, size;
int width, height;
int fd;
-   int is_client_buffer;
struct weston_buffer_reference buffer_ref;
 
/* Used by gbm fbs */
@@ -290,6 +298,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
if (ret)
goto err_fb;
 
+   fb->type = BUFFER_PIXMAN_DUMB;
fb->handle = create_arg.handle;
fb->stride = create_arg.pitch;
fb->size = create_arg.size;
@@ -352,6 +361,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
 {
struct drm_mode_destroy_dumb destroy_arg;
 
+   assert(fb->type == BUFFER_PIXMAN_DUMB);
+
if (!fb->map)
return;
 
@@ -370,8 +381,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
 }
 
 static struct drm_fb *
-drm_fb_get_from_bo(struct gbm_bo *bo,
-  struct drm_backend *backend, uint32_t format)
+drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
+  uint32_t format, enum drm_fb_type type)
 {
struct drm_fb *fb = gbm_bo_get_user_data(bo);
uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
@@ -384,6 +395,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
if (fb == NULL)
return NULL;
 
+   fb->type = type;
fb->bo = bo;
 
fb->width = gbm_bo_get_width(bo);
@@ -440,9 +452,6 @@ static void
 drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
 {
assert(fb->buffer_ref.buffer == NULL);
-
-   fb->is_client_buffer = 1;
-
weston_buffer_reference(>buffer_ref, buffer);
 }
 
@@ -452,15 +461,19 @@ drm_output_release_fb(struct drm_output *output, struct 
drm_fb *fb)
if (!fb)
return;
 
-   if (fb->map &&
-(fb != output->dumb[0] && fb != output->dumb[1])) {
-   drm_fb_destroy_dumb(fb);
-   } else if (fb->bo) {
-   if (fb->is_client_buffer)
-   gbm_bo_destroy(fb->bo);
-   else
-   gbm_surface_release_buffer(output->gbm_surface,
-  fb->bo);
+   switch (fb->type) {
+   case BUFFER_PIXMAN_DUMB:
+   /* nothing: pixman buffers are destroyed manually */
+   break;
+   case BUFFER_CLIENT:
+   gbm_bo_destroy(fb->bo);
+   break;
+   case BUFFER_GBM_SURFACE:
+   gbm_surface_release_buffer(output->gbm_surface, fb->bo);
+   break;
+   default:
+   assert(NULL);
+   break;
}
 }
 
@@ -559,7 +572,7 @@ drm_output_prepare_scanout_view(struct drm_output *output,
return NULL;
}
 
-   output->next = drm_fb_get_from_bo(bo, b, format);
+   output->next = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
if (!output->next) {
gbm_bo_destroy(bo);
return NULL;
@@ -585,7 +598,8 @@ drm_output_render_gl(struct drm_output *output, 
pixman_region32_t *damage)
return;
}
 
-   output->next = drm_fb_get_from_bo(bo, b, output->gbm_format);
+   output->next = drm_fb_get_from_bo(bo, b, output->gbm_format,
+ BUFFER_GBM_SURFACE);
if (!output->next) {
weston_log("failed to get drm_fb for bo\n");
gbm_surface_release_buffer(output->gbm_surface, bo);
@@ -1054,7 +1068,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
return NULL;
}
 
-   s->next = drm_fb_get_from_bo(bo, b, format);
+   s->next = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
if (!s->next) {
gbm_bo_destroy(bo);
return NULL;
-- 
2.9.3

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


[PATCH weston 07/68] compositor-drm: Simplify drm_sprite_crtc_supported

2016-12-09 Thread Daniel Stone
No need to walk the CRTC list every time looking for CRTC indices, when we
already have the CRTC index stashed away. Taking the plane as an argument
also simplifies things a little for callers, and future-proofs for a
potential future KMS API which passes a list of supported CRTC IDs rather
than a bitmask of supported CRTC indices.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1407
---
 libweston/compositor-drm.c | 20 
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index d577c05..2d5faa0 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -234,21 +234,9 @@ static void
 drm_output_update_msc(struct drm_output *output, unsigned int seq);
 
 static int
-drm_sprite_crtc_supported(struct drm_output *output, uint32_t supported)
+drm_sprite_crtc_supported(struct drm_output *output, struct drm_sprite *sprite)
 {
-   struct weston_compositor *ec = output->base.compositor;
-   struct drm_backend *b = to_drm_backend(ec);
-   int crtc;
-
-   for (crtc = 0; crtc < b->num_crtcs; crtc++) {
-   if (b->crtcs[crtc] != output->crtc_id)
-   continue;
-
-   if (supported & (1 << crtc))
-   return -1;
-   }
-
-   return 0;
+   return !!(sprite->possible_crtcs & (1 << output->pipe));
 }
 
 static void
@@ -716,7 +704,7 @@ drm_output_repaint(struct weston_output *output_base,
};
 
if ((!s->current && !s->next) ||
-   !drm_sprite_crtc_supported(output, s->possible_crtcs))
+   !drm_sprite_crtc_supported(output, s))
continue;
 
if (s->next && !backend->sprites_hidden)
@@ -991,7 +979,7 @@ drm_output_prepare_overlay_view(struct drm_output *output,
return NULL;
 
wl_list_for_each(s, >sprite_list, link) {
-   if (!drm_sprite_crtc_supported(output, s->possible_crtcs))
+   if (!drm_sprite_crtc_supported(output, s))
continue;
 
if (!s->next) {
-- 
2.9.3

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


[PATCH weston 64/68] compositor-drm: Add test-only mode to state application

2016-12-09 Thread Daniel Stone
The atomic API can allow us to test state before we apply it, to see if
it will be valid. Add support for this, which we will later use in
assign_planes to ensure our plane configuration is valid.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1533
---
 libweston/compositor-drm.c | 58 +-
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 6b5c7cb..5db0a1a 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1561,7 +1561,12 @@ drm_output_get_disable_state(struct drm_output *output)
return state;
 }
 
-static int drm_output_apply_state(struct drm_output_state *state);
+enum drm_output_apply_state_mode {
+   DRM_OUTPUT_APPLY_STATE_TEST,
+   DRM_OUTPUT_APPLY_STATE_REAL,
+};
+static int drm_output_apply_state(struct drm_output_state *state,
+ enum drm_output_apply_state_mode mode);
 
 /**
  * Mark a drm_output_state (the output's last state) as complete. This handles
@@ -1590,7 +1595,7 @@ drm_output_update_complete(struct drm_output *output, 
uint32_t flags,
goto out;
} else if (output->dpms_off_pending) {
os = drm_output_get_disable_state(output);
-   drm_output_apply_state(os);
+   drm_output_apply_state(os, DRM_OUTPUT_APPLY_STATE_REAL);
}
 
ts.tv_sec = sec;
@@ -1862,7 +1867,8 @@ drm_waitvblank_pipe(struct drm_output *output)
 }
 
 static int
-drm_output_apply_state_legacy(struct drm_output_state *state)
+drm_output_apply_state_legacy(struct drm_output_state *state,
+ enum drm_output_apply_state_mode mode)
 {
struct drm_output *output = state->output;
struct drm_backend *backend = to_drm_backend(output->base.compositor);
@@ -1870,9 +1876,14 @@ drm_output_apply_state_legacy(struct drm_output_state 
*state)
struct drm_plane_state *scanout_state;
struct drm_plane_state *ps;
struct drm_plane *p;
-   struct drm_mode *mode;
+   struct drm_mode *display_mode;
int ret = 0;
 
+   /* The legacy DRM API gives us no way to test commits without actually
+* applying them. */
+   if (mode == DRM_OUTPUT_APPLY_STATE_TEST)
+   return 0;
+
if (state->dpms != WESTON_DPMS_ON) {
wl_list_for_each(ps, >plane_list, link) {
p = ps->plane;
@@ -1922,7 +1933,7 @@ drm_output_apply_state_legacy(struct drm_output_state 
*state)
assert(scanout_state->src_w == scanout_state->dest_w << 16);
assert(scanout_state->src_h == scanout_state->dest_h << 16);
 
-   mode = to_drm_mode(output->base.current_mode);
+   display_mode = to_drm_mode(output->base.current_mode);
if (!scanout_plane->state_cur->fb ||
scanout_plane->state_cur->fb->strides[0] !=
scanout_state->fb->strides[0]) {
@@ -1930,7 +1941,7 @@ drm_output_apply_state_legacy(struct drm_output_state 
*state)
 scanout_state->fb->fb_id,
 0, 0,
 >connector_id, 1,
->mode_info);
+_mode->mode_info);
if (ret) {
weston_log("set mode failed: %m\n");
goto err;
@@ -2086,14 +2097,15 @@ drm_mode_ensure_blob(struct drm_backend *backend, 
struct drm_mode *mode)
 }
 
 static int
-drm_output_apply_state_atomic(struct drm_output_state *state)
+drm_output_apply_state_atomic(struct drm_output_state *state,
+ enum drm_output_apply_state_mode mode)
 {
struct drm_output *output = state->output;
struct drm_backend *backend = to_drm_backend(output->base.compositor);
struct drm_plane_state *plane_state;
drmModeAtomicReq *req = drmModeAtomicAlloc();
struct drm_mode *current_mode = to_drm_mode(output->base.current_mode);
-   uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
+   uint32_t flags = 0;
int ret = 0;
 
if (!req)
@@ -2154,7 +2166,16 @@ drm_output_apply_state_atomic(struct drm_output_state 
*state)
}
}
 
-   if (drmModeAtomicCommit(backend->drm.fd, req, flags, output) != 0) {
+   if (mode == DRM_OUTPUT_APPLY_STATE_TEST)
+   flags |= DRM_MODE_ATOMIC_TEST_ONLY;
+   else
+   flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
+
+   ret = drmModeAtomicCommit(backend->drm.fd, req, flags, output);
+   if (mode == DRM_OUTPUT_APPLY_STATE_TEST)
+   return ret;
+
+   if (ret != 0) {
weston_log("couldn't commit new state: %m\n");
goto err;
}
@@ -2171,16 +2192,17 @@ err:
 #endif
 
 static int

[PATCH weston 66/68] compositor-drm: Test plane states before application

2016-12-09 Thread Daniel Stone
Generate an output state in two stages. Firstly, attempt to run through
and generate a configuration with all views in planes. If this succeeds,
we can bypass the renderer completely.

If this fails, we know we need to have the renderer output used as a
base on the scanout plane, and can incrementally attempt to construct a
working state, by trying the combination of our old renderer state with
planes added one-by-one. If they pass the test commit stage, we can use
it, so we stash that state and continue on.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1535
---
 libweston/compositor-drm.c | 135 +
 1 file changed, 101 insertions(+), 34 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index e51a5b2..7c8b5d9 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1669,12 +1669,15 @@ enum drm_output_propose_state_mode {
 
 static struct drm_plane_state *
 drm_output_prepare_scanout_view(struct drm_output_state *output_state,
-   struct weston_view *ev)
+   struct weston_view *ev,
+   enum drm_output_propose_state_mode mode)
 {
struct drm_output *output = output_state->output;
struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_plane_state *state;
+   struct drm_plane_state *state_old = NULL;
struct drm_fb *fb;
+   int ret;
 
fb = drm_fb_get_from_view(output_state, ev);
if (!fb)
@@ -1687,7 +1690,16 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
}
 
state = drm_output_state_get_plane(output_state, scanout_plane);
-   if (state->fb) {
+
+   /* Check if we've already placed a buffer on this plane; if there's a
+* buffer there but it comes from GBM, then it's the result of
+* drm_output_propose_state placing it here for testing purposes. */
+   if (state->fb &&
+   (state->fb->type == BUFFER_GBM_SURFACE ||
+state->fb->type == BUFFER_PIXMAN_DUMB)) {
+   state_old = calloc(1, sizeof(*state_old));
+   memcpy(state_old, state, sizeof(*state_old));
+   } else if (state->fb) {
drm_fb_unref(fb);
return NULL;
}
@@ -1706,10 +1718,21 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
state->dest_h != (unsigned) output->base.current_mode->height)
goto err;
 
+   if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY)
+   return state;
+
+   ret = drm_output_apply_state(output_state, mode);
+   if (ret != 0)
+   goto err;
+
return state;
 
 err:
-   drm_plane_state_put_back(state);
+   drm_plane_state_free(state, false);
+   if (state_old) {
+   wl_list_insert(_state->plane_list, _old->link);
+   state_old->output_state = output_state;
+   }
return NULL;
 }
 
@@ -1780,7 +1803,9 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
 * want to render. */
scanout_state = drm_output_state_get_plane(output->state_pending,
   output->scanout_plane);
-   if (scanout_state->fb)
+   if (scanout_state->fb &&
+   scanout_state->fb->type != BUFFER_GBM_SURFACE &&
+   scanout_state->fb->type != BUFFER_PIXMAN_DUMB)
return;
 
if (!pixman_region32_not_empty(damage) &&
@@ -1803,6 +1828,7 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
return;
}
 
+   drm_fb_unref(scanout_state->fb);
scanout_state->fb = fb;
scanout_state->output = output;
 
@@ -2401,24 +2427,24 @@ atomic_flip_handler(int fd, unsigned int frame,
 
 static struct drm_plane_state *
 drm_output_prepare_overlay_view(struct drm_output_state *output_state,
-   struct weston_view *ev)
+   struct weston_view *ev,
+   enum drm_output_propose_state_mode mode)
 {
struct drm_output *output = output_state->output;
struct weston_compositor *ec = output->base.compositor;
struct drm_backend *b = to_drm_backend(ec);
struct drm_plane *p;
-   struct drm_plane_state *state = NULL;
struct drm_fb *fb;
unsigned int i;
-
-   if (b->sprites_are_broken)
-   return NULL;
+   int ret;
 
fb = drm_fb_get_from_view(output_state, ev);
if (!fb)
return NULL;
 
wl_list_for_each(p, >plane_list, link) {
+   struct drm_plane_state *state = NULL;
+
if (p->type != WDRM_PLANE_TYPE_OVERLAY)
continue;
 
@@ -2444,28 +2470,30 @@ drm_output_prepare_overlay_view(struct 

[PATCH weston 60/68] compositor-drm: Split drm_assign_planes in two

2016-12-09 Thread Daniel Stone
Move drm_assign_planes into two functions: one which proposes a plane
configuration, and another which applies that state to the Weston
internal structures. This will be used to try multiple configurations
and see which is supported.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1529
---
 libweston/compositor-drm.c | 106 ++---
 1 file changed, 72 insertions(+), 34 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 79f2941..be2b4ea 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -293,6 +293,8 @@ struct drm_plane_state {
 
struct drm_fb *fb;
 
+   struct weston_view *ev; /**< maintained for drm_assign_planes only */
+
int32_t src_x, src_y;
uint32_t src_w, src_h;
uint32_t dest_x, dest_y;
@@ -1685,6 +1687,7 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
}
 
state->fb = fb;
+   state->ev = ev;
state->output = output;
drm_plane_state_coords_for_view(state, ev);
 
@@ -2426,6 +2429,7 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
}
 
state->fb = fb;
+   state->ev = ev;
state->output = output;
 
drm_plane_state_coords_for_view(state, ev);
@@ -2562,6 +2566,7 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
}
 
output->cursor_view = ev;
+   plane_state->ev = ev;
 
plane_state->fb =
drm_fb_ref(output->gbm_cursor_fb[output->current_cursor]);
@@ -2629,16 +2634,14 @@ err:
drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
 }
 
-static void
-drm_assign_planes(struct weston_output *output_base)
+static struct drm_output_state *
+drm_output_propose_state(struct weston_output *output_base)
 {
-   struct drm_backend *b = to_drm_backend(output_base->compositor);
struct drm_output *output = to_drm_output(output_base);
struct drm_output_state *state;
-   struct drm_plane_state *plane_state;
struct weston_view *ev;
pixman_region32_t surface_overlap, renderer_region;
-   struct weston_plane *primary, *next_plane;
+   struct weston_plane *primary = _base->compositor->primary_plane;
 
assert(!output->state_last);
assert(!output->state_pending);
@@ -2659,35 +2662,21 @@ drm_assign_planes(struct weston_output *output_base)
 * as we do for flipping full screen surfaces.
 */
pixman_region32_init(_region);
-   primary = _base->compositor->primary_plane;
 
wl_list_for_each(ev, _base->compositor->view_list, link) {
-   struct weston_surface *es = ev->surface;
-
-   /* Test whether this buffer can ever go into a plane:
-* non-shm, or small enough to be a cursor.
-*
-* Also, keep a reference when using the pixman renderer.
-* That makes it possible to do a seamless switch to the GL
-* renderer and since the pixman renderer keeps a reference
-* to the buffer anyway, there is no side effects.
-*/
-   if (b->use_pixman ||
-   (es->buffer_ref.buffer &&
-   (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
-(ev->surface->width <= b->cursor_width &&
- ev->surface->height <= b->cursor_height
-   es->keep_buffer = true;
-   else
-   es->keep_buffer = false;
+   struct weston_plane *next_plane = NULL;
 
+   /* Since we process views from top to bottom, we know that if
+* the view intersects the calculated renderer region, it must
+* be part of, or occluded by, it, and cannot go on a plane. */
pixman_region32_init(_overlap);
pixman_region32_intersect(_overlap, _region,
  >transform.boundingbox);
 
-   next_plane = NULL;
if (pixman_region32_not_empty(_overlap))
next_plane = primary;
+   pixman_region32_fini(_overlap);
+
if (next_plane == NULL)
next_plane = drm_output_prepare_cursor_view(state, ev);
if (next_plane == NULL)
@@ -2697,17 +2686,69 @@ drm_assign_planes(struct weston_output *output_base)
if (next_plane == NULL)
next_plane = primary;
 
-   weston_view_move_to_plane(ev, next_plane);
-
if (next_plane == primary)
pixman_region32_union(_region,
  _region,
  >transform.boundingbox);
+   }
+   pixman_region32_fini(_region);
+
+   

[PATCH weston 56/68] compositor-drm: Avoid GBM for dmabuf import

2016-12-09 Thread Daniel Stone
From: Tomohito Esaki 

Rather than relying on GBM for dmabuf import, perform the import
directly through libdrm. This creates a specialised drm_fb type for
dmabufs.

This also supports multi-planar dmabuf.

[daniels: Rebased on top of recent drm_fb/drm_plane_state/etc.]

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1525
---
 configure.ac   |   3 --
 libweston/compositor-drm.c | 131 -
 2 files changed, 95 insertions(+), 39 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8fe48b6..54c6fcd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -207,9 +207,6 @@ if test x$enable_drm_compositor = xyes; then
   PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.62],
[AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic 
API])],
[AC_MSG_WARN([libdrm does not support atomic modesetting, 
will omit that capability])])
-  PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 10.2],
-   [AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports dmabuf 
import])],
-   [AC_MSG_WARN([gbm does not support dmabuf import, will omit 
that capability])])
 fi
 
 
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a2d4c8c..e6f94af 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -233,6 +233,7 @@ struct drm_mode {
 enum drm_fb_type {
BUFFER_INVALID = 0, /**< never used */
BUFFER_CLIENT, /**< directly sourced from client */
+   BUFFER_DMABUF, /**< imported from linux_dmabuf client */
BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
BUFFER_GBM_SURFACE, /**< internal EGL rendering */
BUFFER_CURSOR, /**< internal cursor buffer */
@@ -986,6 +987,82 @@ drm_fb_ref(struct drm_fb *fb)
return fb;
 }
 
+static void
+drm_fb_destroy_dmabuf(struct drm_fb *fb)
+{
+   unsigned int i;
+
+   /* Unlike GBM buffers, where destroying the BO also closes the GEM
+* handle, we fully control the handle lifetime for dmabuf buffers. */
+   for (i = 0; i < ARRAY_LENGTH(fb->handles); i++) {
+   struct drm_gem_close gem_close = { .handle = fb->handles[i] };
+   if (!gem_close.handle)
+   continue;
+   (void) drmIoctl(fb->fd, DRM_IOCTL_GEM_CLOSE, _close);
+   }
+
+   drm_fb_destroy(fb);
+}
+
+static struct drm_fb *
+drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
+  struct drm_backend *backend, bool is_opaque)
+{
+   struct drm_fb *fb;
+   int i, ret;
+
+   fb = zalloc(sizeof *fb);
+   if (fb == NULL)
+   return NULL;
+
+   fb->refcnt = 1;
+   fb->type = BUFFER_DMABUF;
+
+   fb->width = dmabuf->attributes.width;
+   fb->height = dmabuf->attributes.height;
+   memcpy(fb->strides, dmabuf->attributes.stride, sizeof(fb->strides));
+   memcpy(fb->offsets, dmabuf->attributes.offset, sizeof(fb->offsets));
+   fb->format = pixel_format_get_info(dmabuf->attributes.format);
+   fb->size = 0;
+   fb->fd = backend->drm.fd;
+
+   if (!fb->format) {
+   weston_log("couldn't look up format info for 0x%lx\n",
+  (unsigned long) fb->format);
+   goto err_free;
+   }
+
+   if (is_opaque)
+   fb->format = pixel_format_get_opaque_substitute(fb->format);
+
+   if (backend->min_width > fb->width ||
+   fb->width > backend->max_width ||
+   backend->min_height > fb->height ||
+   fb->height > backend->max_height) {
+   weston_log("bo geometry out of bounds\n");
+   goto err_free;
+   }
+
+   for (i = 0; i < dmabuf->attributes.n_planes; i++) {
+   ret = drmPrimeFDToHandle(backend->drm.fd,
+dmabuf->attributes.fd[i],
+>handles[i]);
+   if (ret)
+   goto err_free;
+   }
+
+   if (drm_fb_addfb(fb) != 0) {
+   weston_log("failed to create kms fb: %m\n");
+   goto err_free;
+   }
+
+   return fb;
+
+err_free:
+   drm_fb_destroy_dmabuf(fb);
+   return NULL;
+}
+
 static struct drm_fb *
 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
   bool is_opaque, enum drm_fb_type type)
@@ -1070,6 +1147,9 @@ drm_fb_unref(struct drm_fb *fb)
case BUFFER_GBM_SURFACE:
gbm_surface_release_buffer(fb->gbm_surface, fb->bo);
break;
+   case BUFFER_DMABUF:
+   drm_fb_destroy_dmabuf(fb);
+   break;
default:
assert(NULL);
break;
@@ -1300,9 +1380,9 @@ drm_fb_get_from_view(struct drm_output_state *state, 
struct weston_view *ev)
struct drm_output *output = state->output;

[PATCH weston 67/68] compositor-drm: Relax plane restrictions for atomic

2016-12-09 Thread Daniel Stone
Since we now incrementally test atomic state as we build it, we can
loosen restrictions on what we can do with planes, and let the kernel
tell us whether or not it's OK.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1536
---
 libweston/compositor-drm.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 7c8b5d9..e615eb5 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1673,6 +1673,7 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
enum drm_output_propose_state_mode mode)
 {
struct drm_output *output = output_state->output;
+   struct drm_backend *b = to_drm_backend(output->base.compositor);
struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_plane_state *state;
struct drm_plane_state *state_old = NULL;
@@ -1684,7 +1685,7 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
return NULL;
 
/* Can't change formats with just a pageflip */
-   if (fb->format->format != output->gbm_format) {
+   if (!b->atomic_modeset && fb->format->format != output->gbm_format) {
drm_fb_unref(fb);
return NULL;
}
@@ -1709,15 +1710,18 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
state->output = output;
drm_plane_state_coords_for_view(state, ev);
 
-   /* The legacy API does not let us perform cropping or scaling. */
-   if (state->src_x != 0 || state->src_y != 0 ||
-   state->src_w != state->dest_w << 16 ||
-   state->src_h != state->dest_h << 16 ||
-   state->dest_x != 0 || state->dest_y != 0 ||
+   if (state->dest_x != 0 || state->dest_y != 0 ||
state->dest_w != (unsigned) output->base.current_mode->width ||
state->dest_h != (unsigned) output->base.current_mode->height)
goto err;
 
+   /* The legacy API does not let us perform cropping or scaling. */
+   if (!b->atomic_modeset &&
+   (state->src_x != 0 || state->src_y != 0 ||
+state->src_w != state->dest_w << 16 ||
+state->src_h != state->dest_h << 16))
+   goto err;
+
if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY)
return state;
 
@@ -2475,8 +2479,9 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
state->output = output;
 
drm_plane_state_coords_for_view(state, ev);
-   if (state->src_w != state->dest_w << 16 ||
-   state->src_h != state->dest_h << 16) {
+   if (!b->atomic_modeset &&
+   (state->src_w != state->dest_w << 16 ||
+state->src_h != state->dest_h << 16)) {
drm_plane_state_put_back(state);
continue;
}
-- 
2.9.3

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


[PATCH weston 57/68] compositor-drm: Support modifiers for drm_fb

2016-12-09 Thread Daniel Stone
Use the new drmModeAddFB2WithModifiers interface to import buffers with
modifiers.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1526
---
 configure.ac   |  3 +++
 libweston/compositor-drm.c | 25 -
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 54c6fcd..74fe7cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -207,6 +207,9 @@ if test x$enable_drm_compositor = xyes; then
   PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.62],
[AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic 
API])],
[AC_MSG_WARN([libdrm does not support atomic modesetting, 
will omit that capability])])
+  PKG_CHECK_MODULES(DRM_COMPOSITOR_MODIFIERS, [libdrm >= 2.4.71],
+   [AC_DEFINE([HAVE_DRM_ADDFB2_MODIFIERS], 1, [libdrm supports 
modifiers])],
+   [AC_MSG_WARN([libdrm does not support AddFB2 with 
modifiers])])
 fi
 
 
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index e6f94af..a36d27c 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -249,6 +249,7 @@ struct drm_fb {
uint32_t strides[4];
uint32_t offsets[4];
const struct pixel_format_info *format;
+   uint64_t modifier;
int width, height;
int fd;
struct weston_buffer_reference buffer_ref;
@@ -882,7 +883,28 @@ drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
 static int
 drm_fb_addfb(struct drm_fb *fb)
 {
-   int ret;
+   int ret = -EINVAL;
+#ifdef HAVE_DRM_ADDFB2_MODIFIERS
+   uint64_t mods[4] = { };
+   int i;
+#endif
+
+   /* If we have a modifier set, we must only use the WithModifiers
+* entrypoint; we cannot import it through legacy ioctls. */
+   if (fb->modifier) {
+   /* KMS demands that if a modifier is set, it must be the same
+* for all planes. */
+#ifdef HAVE_DRM_ADDFB2_MODIFIERS
+   for (i = 0; fb->handles[i]; i++)
+   mods[i] = fb->modifier;
+   ret = drmModeAddFB2WithModifiers(fb->fd, fb->width, fb->height,
+fb->format->format,
+fb->handles, fb->strides,
+fb->offsets, mods, >fb_id,
+DRM_MODE_FB_MODIFIERS);
+#endif
+   return ret;
+   }
 
ret = drmModeAddFB2(fb->fd, fb->width, fb->height, fb->format->format,
fb->handles, fb->strides, fb->offsets, >fb_id,
@@ -1023,6 +1045,7 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
memcpy(fb->strides, dmabuf->attributes.stride, sizeof(fb->strides));
memcpy(fb->offsets, dmabuf->attributes.offset, sizeof(fb->offsets));
fb->format = pixel_format_get_info(dmabuf->attributes.format);
+   fb->modifier = dmabuf->attributes.modifier[0];
fb->size = 0;
fb->fd = backend->drm.fd;
 
-- 
2.9.3

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


[PATCH weston 49/68] compositor-drm: Use plane_state_coords_for_view for scanout

2016-12-09 Thread Daniel Stone
Use the shiny new helper we have for working through scanout as well.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1518
---
 libweston/compositor-drm.c | 66 --
 1 file changed, 23 insertions(+), 43 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index cd89083..202772b 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1505,13 +1505,6 @@ drm_output_assign_state(struct drm_output_state *state,
}
 }
 
-static int
-drm_view_transform_supported(struct weston_view *ev)
-{
-   return !ev->transform.enabled ||
-   (ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
-}
-
 static bool
 drm_view_is_opaque(struct weston_view *ev)
 {
@@ -1543,7 +1536,6 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_plane_state *state;
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
-   struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct gbm_bo *bo;
 
/* Don't import buffers which span multiple outputs. */
@@ -1559,67 +1551,55 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
if (wl_shm_buffer_get(buffer->resource))
return NULL;
 
-   /* Make sure our view is exactly compatible with the output. */
-   if (ev->geometry.x != output->base.x ||
-   ev->geometry.y != output->base.y)
-   return NULL;
-   if (buffer->width != output->base.current_mode->width ||
-   buffer->height != output->base.current_mode->height)
-   return NULL;
+   state = drm_output_state_get_plane(output_state, scanout_plane);
+   if (state->fb)
+   goto err;
 
-   if (ev->transform.enabled)
-   return NULL;
-   if (ev->geometry.scissor_enabled)
-   return NULL;
-   if (viewport->buffer.transform != output->base.transform)
-   return NULL;
-   if (viewport->buffer.scale != output->base.current_scale)
-   return NULL;
-   if (!drm_view_transform_supported(ev))
-   return NULL;
+   state->output = output;
+   drm_plane_state_coords_for_view(state, ev);
+
+   /* The legacy API does not let us perform cropping or scaling. */
+   if (state->src_x != 0 || state->src_y != 0 ||
+   state->src_w != state->dest_w << 16 ||
+   state->src_h != state->dest_h << 16 ||
+   state->dest_x != 0 || state->dest_y != 0 ||
+   state->dest_w != (unsigned) output->base.current_mode->width ||
+   state->dest_h != (unsigned) output->base.current_mode->height)
+   goto err;
 
if (ev->alpha != 1.0f)
-   return NULL;
+   goto err;
 
bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
   buffer->resource, GBM_BO_USE_SCANOUT);
 
/* Unable to use the buffer for scanout */
if (!bo)
-   return NULL;
+   goto err;
 
state = drm_output_state_get_plane(output_state, scanout_plane);
state->fb = drm_fb_get_from_bo(bo, b, drm_view_is_opaque(ev),
   BUFFER_CLIENT);
if (!state->fb) {
-   drm_plane_state_put_back(state);
+   /* We need to explicitly destroy the BO. */
gbm_bo_destroy(bo);
-   return NULL;
+   goto err;
}
 
/* Can't change formats with just a pageflip */
if (state->fb->format->format != output->gbm_format) {
/* No need to destroy the GBM BO here, as it's now owned
 * by the FB. */
-   drm_plane_state_put_back(state);
-   return NULL;
+   goto err;
}
 
drm_fb_set_buffer(state->fb, buffer);
 
-   state->output = output;
-
-   state->src_x = 0;
-   state->src_y = 0;
-   state->src_w = ev->surface->width << 16;
-   state->src_h = ev->surface->height << 16;
-
-   state->dest_x = 0;
-   state->dest_y = 0;
-   state->dest_w = output->base.width;
-   state->dest_h = output->base.height;
-
return _plane->base;
+
+err:
+   drm_plane_state_put_back(state);
+   return NULL;
 }
 
 static struct drm_fb *
-- 
2.9.3

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


[PATCH weston 53/68] compositor-drm: Remove no_addfb2 handling

2016-12-09 Thread Daniel Stone
If AddFB2 ever fails for any reason, we fall back to legacy AddFB, which
doesn't support the same swathe of formats, or multi-planar formats, or
modifiers.

This can happen with arbitrary client buffers, condemning us to the
fallback forever more. Remove this, at the cost of an unnecessary ioctl
for users on old kernels without AddFB2; unfortunately, we cannot detect
the complete absence of the ioctl, as the return here is -EINVAL rather
than -ENOTTY.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1522
---
 libweston/compositor-drm.c | 46 --
 1 file changed, 12 insertions(+), 34 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index ba305ad..5fff646 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -204,7 +204,6 @@ struct drm_backend {
 */
int min_width, max_width;
int min_height, max_height;
-   int no_addfb2;
 
struct wl_list plane_list;
int sprites_are_broken;
@@ -886,6 +885,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
struct drm_mode_create_dumb create_arg;
struct drm_mode_destroy_dumb destroy_arg;
struct drm_mode_map_dumb map_arg;
+   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
 
fb = zalloc(sizeof *fb);
if (!fb)
@@ -925,23 +925,12 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
 
ret = -1;
 
-   if (!b->no_addfb2) {
-   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 
0 };
-
-   handles[0] = fb->handle;
-   pitches[0] = fb->stride;
-   offsets[0] = 0;
-
-   ret = drmModeAddFB2(b->drm.fd, width, height,
-   fb->format->format,
-   handles, pitches, offsets,
-   >fb_id, 0);
-   if (ret) {
-   weston_log("addfb2 failed: %m\n");
-   b->no_addfb2 = 1;
-   }
-   }
+   handles[0] = fb->handle;
+   pitches[0] = fb->stride;
+   offsets[0] = 0;
 
+   ret = drmModeAddFB2(b->drm.fd, width, height, fb->format->format,
+   handles, pitches, offsets, >fb_id, 0);
if (ret) {
ret = drmModeAddFB(b->drm.fd, width, height,
   fb->format->depth, fb->format->bpp,
@@ -1026,24 +1015,13 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct 
drm_backend *backend,
goto err_free;
}
 
-   ret = -1;
-
-   if (!backend->no_addfb2) {
-   handles[0] = fb->handle;
-   pitches[0] = fb->stride;
-   offsets[0] = 0;
-
-   ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
-   fb->format->format,
-   handles, pitches, offsets,
-   >fb_id, 0);
-   if (ret) {
-   weston_log("addfb2 failed: %m\n");
-   backend->no_addfb2 = 1;
-   backend->sprites_are_broken = 1;
-   }
-   }
+   handles[0] = fb->handle;
+   pitches[0] = fb->stride;
+   offsets[0] = 0;
 
+   ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
+   fb->format->format, handles, pitches, offsets,
+   >fb_id, 0);
if (ret && fb->format->depth && fb->format->bpp)
ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
   fb->format->depth, fb->format->bpp,
-- 
2.9.3

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


[PATCH weston 62/68] compositor-drm: Ignore occluded views

2016-12-09 Thread Daniel Stone
When trying to assign planes, keep track of the areas which are
already occluded, and ignore views which are completely occluded. This
allows us to build a state using planes only, when there are occluded
views which cannot go into a plane behind views which can.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1531
---
 libweston/compositor-drm.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index dc68768..1eb1fbb 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2632,7 +2632,7 @@ drm_output_propose_state(struct weston_output 
*output_base)
struct drm_output *output = to_drm_output(output_base);
struct drm_output_state *state;
struct weston_view *ev;
-   pixman_region32_t surface_overlap, renderer_region;
+   pixman_region32_t surface_overlap, renderer_region, occluded_region;
struct weston_plane *primary = _base->compositor->primary_plane;
 
assert(!output->state_last);
@@ -2654,9 +2654,11 @@ drm_output_propose_state(struct weston_output 
*output_base)
 * as we do for flipping full screen surfaces.
 */
pixman_region32_init(_region);
+   pixman_region32_init(_region);
 
wl_list_for_each(ev, _base->compositor->view_list, link) {
struct weston_plane *next_plane = NULL;
+   bool occluded = false;
 
/* If this view doesn't touch our output at all, there's no
 * reason to do anything with it. */
@@ -2668,6 +2670,16 @@ drm_output_propose_state(struct weston_output 
*output_base)
if (ev->output_mask != (1u << output->base.id))
next_plane = primary;
 
+   /* Ignore views we know to be totally occluded. */
+   pixman_region32_init(_overlap);
+   pixman_region32_subtract(_overlap,
+>transform.boundingbox,
+_region);
+   occluded = !pixman_region32_not_empty(_overlap);
+   pixman_region32_fini(_overlap);
+   if (occluded)
+   continue;
+
/* Since we process views from top to bottom, we know that if
 * the view intersects the calculated renderer region, it must
 * be part of, or occluded by, it, and cannot go on a plane. */
@@ -2678,6 +2690,11 @@ drm_output_propose_state(struct weston_output 
*output_base)
next_plane = primary;
pixman_region32_fini(_overlap);
 
+   if (drm_view_is_opaque(ev))
+   pixman_region32_union(_region,
+ _region,
+ >transform.boundingbox);
+
if (next_plane == NULL)
next_plane = drm_output_prepare_cursor_view(state, ev);
if (next_plane == NULL)
@@ -2693,6 +2710,7 @@ drm_output_propose_state(struct weston_output 
*output_base)
  >transform.boundingbox);
}
pixman_region32_fini(_region);
+   pixman_region32_fini(_region);
 
return state;
 }
-- 
2.9.3

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


[PATCH weston 58/68] compositor-drm: Don't need safe view-list traversal

2016-12-09 Thread Daniel Stone
Nothing in this loop reorders views within the compositor's view_list.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1527
---
 libweston/compositor-drm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a36d27c..b7ebb2f 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2636,7 +2636,7 @@ drm_assign_planes(struct weston_output *output_base)
struct drm_output *output = to_drm_output(output_base);
struct drm_output_state *state;
struct drm_plane_state *plane_state;
-   struct weston_view *ev, *next;
+   struct weston_view *ev;
pixman_region32_t overlap, surface_overlap;
struct weston_plane *primary, *next_plane;
 
@@ -2661,7 +2661,7 @@ drm_assign_planes(struct weston_output *output_base)
pixman_region32_init();
primary = _base->compositor->primary_plane;
 
-   wl_list_for_each_safe(ev, next, _base->compositor->view_list, 
link) {
+   wl_list_for_each(ev, _base->compositor->view_list, link) {
struct weston_surface *es = ev->surface;
 
/* Test whether this buffer can ever go into a plane:
-- 
2.9.3

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


[PATCH weston 32/68] compositor-drm: Track all plane types

2016-12-09 Thread Daniel Stone
Retain drm_plane tracking objects for all actual DRM planes when using
universal planes, not just overlay planes. Rename uses of 'sprite' to
'plane' to make it clear that it can now be any kind of plane, not just
an overlay/sprite.

These are currently unused.

Differential Revision: https://phabricator.freedesktop.org/D1496

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 74 +-
 1 file changed, 41 insertions(+), 33 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 46fcf0a..3dd2924 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -152,7 +152,7 @@ struct drm_backend {
int min_height, max_height;
int no_addfb2;
 
-   struct wl_list sprite_list;
+   struct wl_list plane_list;
int sprites_are_broken;
int sprites_hidden;
 
@@ -1144,7 +1144,7 @@ drm_output_repaint(struct weston_output *output_base,
struct drm_output *output = to_drm_output(output_base);
struct drm_backend *backend =
to_drm_backend(output->base.compositor);
-   struct drm_plane *s;
+   struct drm_plane *p;
struct drm_mode *mode;
int ret = 0;
 
@@ -1190,26 +1190,31 @@ drm_output_repaint(struct weston_output *output_base,
/*
 * Now, update all the sprite surfaces
 */
-   wl_list_for_each(s, >sprite_list, link) {
+   wl_list_for_each(p, >plane_list, link) {
uint32_t flags = 0, fb_id = 0;
drmVBlank vbl = {
.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
.request.sequence = 1,
};
 
-   if ((!s->fb_current && !s->fb_pending) ||
-   !drm_plane_crtc_supported(output, s))
+   if (p->type != WDRM_PLANE_TYPE_OVERLAY)
+   continue;
+
+   /* XXX: Set output much earlier, so we don't attempt to place
+*  planes on entirely the wrong output. */
+   if ((!p->fb_current && !p->fb_pending) ||
+   !drm_plane_crtc_supported(output, p))
continue;
 
-   if (s->fb_pending && !backend->sprites_hidden)
-   fb_id = s->fb_pending->fb_id;
+   if (p->fb_pending && !backend->sprites_hidden)
+   fb_id = p->fb_pending->fb_id;
 
-   ret = drmModeSetPlane(backend->drm.fd, s->plane_id,
+   ret = drmModeSetPlane(backend->drm.fd, p->plane_id,
  output->crtc_id, fb_id, flags,
- s->dest_x, s->dest_y,
- s->dest_w, s->dest_h,
- s->src_x, s->src_y,
- s->src_w, s->src_h);
+ p->dest_x, p->dest_y,
+ p->dest_w, p->dest_h,
+ p->src_x, p->src_y,
+ p->src_w, p->src_h);
if (ret)
weston_log("setplane failed: %d: %s\n",
ret, strerror(errno));
@@ -1220,17 +1225,17 @@ drm_output_repaint(struct weston_output *output_base,
 * Queue a vblank signal so we know when the surface
 * becomes active on the display or has been replaced.
 */
-   vbl.request.signal = (unsigned long)s;
+   vbl.request.signal = (unsigned long) p;
ret = drmWaitVBlank(backend->drm.fd, );
if (ret) {
weston_log("vblank event request failed: %d: %s\n",
ret, strerror(errno));
}
 
-   s->output = output;
-   s->fb_last = s->fb_current;
-   s->fb_current = s->fb_pending;
-   s->fb_pending = NULL;
+   p->output = output;
+   p->fb_last = p->fb_current;
+   p->fb_current = p->fb_pending;
+   p->fb_pending = NULL;
output->vblank_pending++;
}
 
@@ -1469,7 +1474,10 @@ drm_output_prepare_overlay_view(struct drm_output 
*output,
if (ev->alpha != 1.0f)
return NULL;
 
-   wl_list_for_each(p, >sprite_list, link) {
+   wl_list_for_each(p, >plane_list, link) {
+   if (p->type != WDRM_PLANE_TYPE_OVERLAY)
+   continue;
+
if (!drm_plane_crtc_supported(output, p))
continue;
 
@@ -2136,7 +2144,7 @@ drm_plane_create(struct drm_backend *b, const 
drmModePlane *kplane)
plane->type = WDRM_PLANE_TYPE_OVERLAY;
 
weston_plane_init(>base, b->compositor, 0, 0);
-   wl_list_insert(>sprite_list, >link);
+   wl_list_insert(>plane_list, >link);
 

[PATCH weston 52/68] compositor-drm: Use plane FB-import helper for scanout

2016-12-09 Thread Daniel Stone
Use the same codepath, which has the added advantage of being able to
import dmabufs.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1521
---
 libweston/compositor-drm.c | 54 +++---
 1 file changed, 12 insertions(+), 42 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 59a764d..ba305ad 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1603,29 +1603,27 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
struct weston_view *ev)
 {
struct drm_output *output = output_state->output;
-   struct drm_backend *b = to_drm_backend(output->base.compositor);
struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_plane_state *state;
-   struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
-   struct gbm_bo *bo;
-
-   /* Don't import buffers which span multiple outputs. */
-   if (ev->output_mask != (1u << output->base.id))
-   return NULL;
+   struct drm_fb *fb;
 
-   /* We use GBM to import buffers. */
-   if (b->gbm == NULL)
+   fb = drm_fb_get_from_view(output_state, ev);
+   if (!fb)
return NULL;
 
-   if (buffer == NULL)
-   return NULL;
-   if (wl_shm_buffer_get(buffer->resource))
+   /* Can't change formats with just a pageflip */
+   if (fb->format->format != output->gbm_format) {
+   drm_fb_unref(fb);
return NULL;
+   }
 
state = drm_output_state_get_plane(output_state, scanout_plane);
-   if (state->fb)
-   goto err;
+   if (state->fb) {
+   drm_fb_unref(fb);
+   return NULL;
+   }
 
+   state->fb = fb;
state->output = output;
drm_plane_state_coords_for_view(state, ev);
 
@@ -1638,34 +1636,6 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
state->dest_h != (unsigned) output->base.current_mode->height)
goto err;
 
-   if (ev->alpha != 1.0f)
-   goto err;
-
-   bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
-  buffer->resource, GBM_BO_USE_SCANOUT);
-
-   /* Unable to use the buffer for scanout */
-   if (!bo)
-   goto err;
-
-   state = drm_output_state_get_plane(output_state, scanout_plane);
-   state->fb = drm_fb_get_from_bo(bo, b, drm_view_is_opaque(ev),
-  BUFFER_CLIENT);
-   if (!state->fb) {
-   /* We need to explicitly destroy the BO. */
-   gbm_bo_destroy(bo);
-   goto err;
-   }
-
-   /* Can't change formats with just a pageflip */
-   if (state->fb->format->format != output->gbm_format) {
-   /* No need to destroy the GBM BO here, as it's now owned
-* by the FB. */
-   goto err;
-   }
-
-   drm_fb_set_buffer(state->fb, buffer);
-
return _plane->base;
 
 err:
-- 
2.9.3

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


[PATCH weston 68/68] compositor-drm: Enable planes for atomic

2016-12-09 Thread Daniel Stone
Now that we can sensibly test proposed plane configurations with atomic,
sprites are not broken.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1537
---
 libweston/compositor-drm.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index e615eb5..d1f7f0f 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -3111,6 +3111,17 @@ init_drm(struct drm_backend *b, struct udev_device 
*device)
weston_log("DRM: %s atomic modesetting\n",
   b->atomic_modeset ? "supports" : "does not support");
 
+   /*
+* KMS support for hardware planes cannot properly synchronize
+* without nuclear page flip. Without nuclear/atomic, hw plane
+* and cursor plane updates would either tear or cause extra
+* waits for vblanks which means dropping the compositor framerate
+* to a fraction. For cursors, it's not so bad, so they are
+* enabled.
+*/
+   if (!b->atomic_modeset)
+   b->sprites_are_broken = 1;
+
return 0;
 }
 
@@ -4972,17 +4983,6 @@ drm_backend_create(struct weston_compositor *compositor,
if (b == NULL)
return NULL;
 
-   /*
-* KMS support for hardware planes cannot properly synchronize
-* without nuclear page flip. Without nuclear/atomic, hw plane
-* and cursor plane updates would either tear or cause extra
-* waits for vblanks which means dropping the compositor framerate
-* to a fraction. For cursors, it's not so bad, so they are
-* enabled.
-*
-* These can be enabled again when nuclear/atomic support lands.
-*/
-   b->sprites_are_broken = 1;
b->compositor = compositor;
b->use_pixman = config->use_pixman;
b->use_current_mode = config->use_current_mode;
-- 
2.9.3

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


[PATCH weston 46/68] compositor-drm: Make alpha-to-opaque handling common

2016-12-09 Thread Daniel Stone
Rather than a hardcoded ARGB -> XRGB translation inside a
GBM-specific helper, just determine whether or not the view is opaque,
and use the generic helpers to implement the format translation.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1515
---
 libweston/compositor-drm.c | 114 +
 1 file changed, 43 insertions(+), 71 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 2f9415c..893fdbd 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -984,7 +984,7 @@ drm_fb_ref(struct drm_fb *fb)
 
 static struct drm_fb *
 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
-  uint32_t format, enum drm_fb_type type)
+  bool is_opaque, enum drm_fb_type type)
 {
struct drm_fb *fb = gbm_bo_get_user_data(bo);
uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
@@ -1005,16 +1005,19 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct 
drm_backend *backend,
fb->height = gbm_bo_get_height(bo);
fb->stride = gbm_bo_get_stride(bo);
fb->handle = gbm_bo_get_handle(bo).u32;
-   fb->format = pixel_format_get_info(format);
+   fb->format = pixel_format_get_info(gbm_bo_get_format(bo));
fb->size = fb->stride * fb->height;
fb->fd = backend->drm.fd;
 
if (!fb->format) {
weston_log("couldn't look up format 0x%lx\n",
-  (unsigned long) format);
+  (unsigned long) gbm_bo_get_format(bo));
goto err_free;
}
 
+   if (is_opaque)
+   fb->format = pixel_format_get_opaque_substitute(fb->format);
+
if (backend->min_width > fb->width ||
fb->width > backend->max_width ||
backend->min_height > fb->height ||
@@ -1025,13 +1028,14 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct 
drm_backend *backend,
 
ret = -1;
 
-   if (format && !backend->no_addfb2) {
+   if (!backend->no_addfb2) {
handles[0] = fb->handle;
pitches[0] = fb->stride;
offsets[0] = 0;
 
ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
-   format, handles, pitches, offsets,
+   fb->format->format,
+   handles, pitches, offsets,
>fb_id, 0);
if (ret) {
weston_log("addfb2 failed: %m\n");
@@ -1422,34 +1426,26 @@ drm_view_transform_supported(struct weston_view *ev)
(ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
 }
 
-static uint32_t
-drm_output_check_scanout_format(struct drm_output *output,
-   struct weston_surface *es, struct gbm_bo *bo)
+static bool
+drm_view_is_opaque(struct weston_view *ev)
 {
-   uint32_t format;
pixman_region32_t r;
+   bool ret = false;
 
-   format = gbm_bo_get_format(bo);
-
-   if (format == GBM_FORMAT_ARGB) {
-   /* We can scanout an ARGB buffer if the surface's
-* opaque region covers the whole output, but we have
-* to use XRGB as the KMS format code. */
-   pixman_region32_init_rect(, 0, 0,
- output->base.width,
- output->base.height);
-   pixman_region32_subtract(, , >opaque);
+   /* We can scanout an ARGB buffer if the surface's
+* opaque region covers the whole output, but we have
+* to use XRGB as the KMS format code. */
+   pixman_region32_init_rect(, 0, 0,
+ ev->surface->width,
+ ev->surface->height);
+   pixman_region32_subtract(, , >surface->opaque);
 
-   if (!pixman_region32_not_empty())
-   format = GBM_FORMAT_XRGB;
-
-   pixman_region32_fini();
-   }
+   if (!pixman_region32_not_empty())
+   ret = true;
 
-   if (output->gbm_format == format)
-   return format;
+   pixman_region32_fini();
 
-   return 0;
+   return ret;
 }
 
 static struct weston_plane *
@@ -1463,7 +1459,6 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct gbm_bo *bo;
-   uint32_t format;
 
/* Don't import buffers which span multiple outputs. */
if (ev->output_mask != (1u << output->base.id))
@@ -1507,17 +1502,20 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
if (!bo)
return NULL;
 
-   format = 

[PATCH weston 36/68] compositor-drm: Use drm_plane for scanout plane

2016-12-09 Thread Daniel Stone
Use a real drm_plane to back the scanout plane, displacing
output->fb_{last,cur,pending} to their plane-tracked equivalents.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1416
---
 libweston/compositor-drm.c | 132 +
 1 file changed, 87 insertions(+), 45 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 36468b9..e575429 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -315,8 +315,8 @@ struct drm_output {
int current_cursor;
 
/* Plane currently being directly displayed by KMS */
-   struct weston_plane scanout_plane;
-   struct drm_fb *fb_current, *fb_pending, *fb_last;
+   struct drm_plane *scanout_plane;
+
struct backlight *backlight;
 
struct drm_output_state *state_last;
@@ -1242,6 +1242,8 @@ drm_output_assign_state(struct drm_output_state *state,
 
if (plane->type == WDRM_PLANE_TYPE_OVERLAY)
output->vblank_pending++;
+   else if (plane->type == WDRM_PLANE_TYPE_PRIMARY)
+   output->page_flip_pending = 1;
}
 }
 
@@ -1289,6 +1291,8 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
 {
struct drm_output *output = output_state->output;
struct drm_backend *b = to_drm_backend(output->base.compositor);
+   struct drm_plane *scanout_plane = output->scanout_plane;
+   struct drm_plane_state *state;
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct gbm_bo *bo;
@@ -1342,15 +1346,29 @@ drm_output_prepare_scanout_view(struct drm_output_state 
*output_state,
return NULL;
}
 
-   output->fb_pending = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
-   if (!output->fb_pending) {
+   state = drm_output_state_get_plane(output_state, scanout_plane);
+   state->fb = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
+   if (!state->fb) {
+   drm_plane_state_put_back(state);
gbm_bo_destroy(bo);
return NULL;
}
 
-   drm_fb_set_buffer(output->fb_pending, buffer);
+   drm_fb_set_buffer(state->fb, buffer);
+
+   state->output = output;
+
+   state->src_x = 0;
+   state->src_y = 0;
+   state->src_w = ev->surface->width << 16;
+   state->src_h = ev->surface->height << 16;
 
-   return >scanout_plane;
+   state->dest_x = 0;
+   state->dest_y = 0;
+   state->dest_w = output->base.width;
+   state->dest_h = output->base.height;
+
+   return _plane->base;
 }
 
 static struct drm_fb *
@@ -1411,12 +1429,15 @@ static void
 drm_output_render(struct drm_output *output, pixman_region32_t *damage)
 {
struct weston_compositor *c = output->base.compositor;
+   struct drm_plane_state *scanout_state;
struct drm_backend *b = to_drm_backend(c);
struct drm_fb *fb;
 
/* If we already have a client buffer promoted to scanout, then we don't
 * want to render. */
-   if (output->fb_pending)
+   scanout_state = drm_output_state_get_plane(output->state_pending,
+  output->scanout_plane);
+   if (scanout_state->fb)
return;
 
if (b->use_pixman)
@@ -1424,9 +1445,24 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
else
fb = drm_output_render_gl(output, damage);
 
-   if (!fb)
+   if (!fb) {
+   drm_plane_state_put_back(scanout_state);
return;
-   output->fb_pending = fb;
+   }
+
+   scanout_state->fb = fb;
+   scanout_state->output = output;
+
+   scanout_state->src_x = 0;
+   scanout_state->src_y = 0;
+   scanout_state->src_w = output->base.current_mode->width << 16;
+   scanout_state->src_h = output->base.current_mode->height << 16;
+
+   scanout_state->dest_x = 0;
+   scanout_state->dest_y = 0;
+   scanout_state->dest_w = scanout_state->src_w >> 16;
+   scanout_state->dest_h = scanout_state->src_h >> 16;
+
 
pixman_region32_subtract(>primary_plane.damage,
 >primary_plane.damage, damage);
@@ -1486,6 +1522,8 @@ drm_output_repaint(struct weston_output *output_base,
struct drm_output *output = to_drm_output(output_base);
struct drm_backend *backend =
to_drm_backend(output->base.compositor);
+   struct drm_plane *scanout_plane = output->scanout_plane;
+   struct drm_plane_state *scanout_state;
struct drm_plane_state *ps;
struct drm_plane *p;
struct drm_mode *mode;
@@ -1500,17 +1538,31 @@ drm_output_repaint(struct weston_output *output_base,

[PATCH weston 45/68] compositor-drm: Atomic modesetting support

2016-12-09 Thread Daniel Stone
Add support for using the atomic-modesetting API to apply output state.
Unlike previous series, this commit does not unflip sprites_are_broken,
until further work has been done with assign_planes to make it reliable.

Differential Revision: https://phabricator.freedesktop.org/D1507

Signed-off-by: Daniel Stone 
Co-authored-by: Pekka Paalanen 
Co-authored-by: Louis-Francis Ratté-Boulianne 

Co-authored-by: Derek Foreman 
---
 libweston/compositor-drm.c | 208 +++--
 1 file changed, 203 insertions(+), 5 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index b33d519..2f9415c 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -349,6 +349,7 @@ struct drm_output {
 
int vblank_pending;
int page_flip_pending;
+   int atomic_complete_pending;
int destroy_pending;
int disable_pending;
int dpms_off_pending;
@@ -1376,6 +1377,7 @@ drm_output_assign_state(struct drm_output_state *state,
enum drm_output_state_update_mode mode)
 {
struct drm_output *output = state->output;
+   struct drm_backend *b = to_drm_backend(output->base.compositor);
struct drm_plane_state *plane_state;
 
assert(!output->state_last);
@@ -1388,6 +1390,9 @@ drm_output_assign_state(struct drm_output_state *state,
output->state_cur = state;
output->state_pending = NULL;
 
+   if (b->atomic_modeset && mode == DRM_OUTPUT_STATE_UPDATE_ASYNCHRONOUS)
+   output->atomic_complete_pending = 1;
+
/* Replace state_cur on each affected plane with the new state, being
 * careful to dispose of orphaned (but only orphaned) previous state.
 * If the previous state is not orphaned (still has an output_state
@@ -1399,7 +1404,8 @@ drm_output_assign_state(struct drm_output_state *state,
drm_plane_state_free(plane->state_cur, true);
plane->state_cur = plane_state;
 
-   if (mode != DRM_OUTPUT_STATE_UPDATE_ASYNCHRONOUS)
+   if (mode != DRM_OUTPUT_STATE_UPDATE_ASYNCHRONOUS ||
+   b->atomic_modeset)
continue;
 
if (plane->type == WDRM_PLANE_TYPE_OVERLAY)
@@ -1686,7 +1692,7 @@ drm_waitvblank_pipe(struct drm_output *output)
 }
 
 static int
-drm_output_apply_state(struct drm_output_state *state)
+drm_output_apply_state_legacy(struct drm_output_state *state)
 {
struct drm_output *output = state->output;
struct drm_backend *backend = to_drm_backend(output->base.compositor);
@@ -1844,6 +1850,168 @@ err:
return -1;
 }
 
+#ifdef HAVE_DRM_ATOMIC
+static int
+crtc_add_prop(drmModeAtomicReq *req, struct drm_output *output,
+ enum wdrm_crtc_property prop, uint64_t val)
+{
+   struct property_item *item = >props_crtc.item[prop];
+   int ret;
+
+   if (!item)
+   return -1;
+
+   ret = drmModeAtomicAddProperty(req, output->crtc_id,
+  item->drm_prop->prop_id, val);
+   return (ret <= 0) ? -1 : 0;
+}
+
+static int
+connector_add_prop(drmModeAtomicReq *req, struct drm_output *output,
+  enum wdrm_connector_property prop, uint64_t val)
+{
+   struct property_item *item = >props_conn.item[prop];
+   int ret;
+
+   if (!item)
+   return -1;
+
+   ret = drmModeAtomicAddProperty(req, output->connector_id,
+  item->drm_prop->prop_id, val);
+   return (ret <= 0) ? -1 : 0;
+}
+
+static int
+plane_add_prop(drmModeAtomicReq *req, struct drm_plane *plane,
+  enum wdrm_plane_property prop, uint64_t val)
+{
+   struct property_item *item = >props.item[prop];
+   int ret;
+
+   if (!item)
+   return -1;
+
+   ret = drmModeAtomicAddProperty(req, plane->plane_id,
+  item->drm_prop->prop_id, val);
+   return (ret <= 0) ? -1 : 0;
+}
+
+static int
+drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode)
+{
+   int ret;
+
+   if (mode->blob_id)
+   return 0;
+
+   ret = drmModeCreatePropertyBlob(backend->drm.fd,
+   >mode_info,
+   sizeof(mode->mode_info),
+   >blob_id);
+   if (ret != 0)
+   weston_log("failed to create mode property blob: %m\n");
+
+   return ret;
+}
+
+static int
+drm_output_apply_state_atomic(struct drm_output_state *state)
+{
+   struct drm_output *output = state->output;
+   struct drm_backend *backend = to_drm_backend(output->base.compositor);
+   struct drm_plane_state *plane_state;
+   drmModeAtomicReq *req = drmModeAtomicAlloc();
+   struct 

[PATCH weston 48/68] compositor-drm: Only disallow scaling for overlay planes

2016-12-09 Thread Daniel Stone
Now we have a more comprehensive overview of the transform we're going
to apply, use this to explicitly disallow scaling and rotation.

XXX: This does not actually disallow rotation for square surfaces.
 We would have to build up a full buffer->view->output transform
 matrix, and then analyse that.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1517
---
 libweston/compositor-drm.c | 27 ---
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index b57e2ee..cd89083 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2294,7 +2294,6 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
 {
struct drm_output *output = output_state->output;
struct weston_compositor *ec = output->base.compositor;
-   struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct drm_backend *b = to_drm_backend(ec);
struct wl_resource *buffer_resource;
struct drm_plane *p;
@@ -2320,13 +2319,6 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
if (wl_shm_buffer_get(buffer_resource))
return NULL;
 
-   if (viewport->buffer.transform != output->base.transform)
-   return NULL;
-   if (viewport->buffer.scale != output->base.current_scale)
-   return NULL;
-   if (!drm_view_transform_supported(ev))
-   return NULL;
-
if (ev->alpha != 1.0f)
return NULL;
 
@@ -2355,6 +2347,12 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
if (!state)
return NULL;
 
+   state->output = output;
+   drm_plane_state_coords_for_view(state, ev);
+   if (state->src_w != state->dest_w << 16 ||
+   state->src_h != state->dest_h << 16)
+   goto err;
+
if ((dmabuf = linux_dmabuf_buffer_get(buffer_resource))) {
 #ifdef HAVE_GBM_FD_IMPORT
/* XXX: TODO:
@@ -2373,7 +2371,7 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
};
 
if (dmabuf->attributes.n_planes != 1 || 
dmabuf->attributes.offset[0] != 0)
-   return NULL;
+   goto err;
 
bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_FD, _dmabuf,
   GBM_BO_USE_SCANOUT);
@@ -2389,8 +2387,12 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
 
state->fb = drm_fb_get_from_bo(bo, b, drm_view_is_opaque(ev),
   BUFFER_CLIENT);
-   if (!state->fb)
+   if (!state->fb) {
+   /* Destroy the BO as we've allocated it, but it won't yet
+* be deallocated by the state. */
+   gbm_bo_destroy(bo);
goto err;
+   }
 
/* Check whether the format is supported */
for (i = 0; i < p->count_formats; i++)
@@ -2401,15 +2403,10 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
 
drm_fb_set_buffer(state->fb, ev->surface->buffer_ref.buffer);
 
-   state->output = output;
-   drm_plane_state_coords_for_view(state, ev);
-
return >base;
 
 err:
drm_plane_state_put_back(state);
-   if (bo)
-   gbm_bo_destroy(bo);
return NULL;
 }
 
-- 
2.9.3

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


[PATCH weston 30/68] compositor-drm: Rename fb_plane to scanout_plane

2016-12-09 Thread Daniel Stone
All planes being displayed have a framebuffer. What makes 'fb_plane'
special is that it's being displayed as the primary plane by KMS.

Previous patchsets renamed this to 'primary_plane' to match the KMS
terminology, namely the CRTC's base plane, which is controlled by
drmModeSetCrtc in the legacy API, and identified by PLANE_TYPE ==
"Primary" in the universal-plane API.

However, Weston uses 'primary_plane' internally to refer to the case
where client content is _not_ directly displayed on a plane, but
composited via the renderer, with the result of the compositing then
shown.

Rename to 'scanout_plane' as our least-ambiguous name, and document it a
bit.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1415
---
 libweston/compositor-drm.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 9a27f03..e4d6743 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -225,7 +225,8 @@ struct drm_output {
struct weston_view *cursor_view;
int current_cursor;
 
-   struct weston_plane fb_plane;
+   /* Plane currently being directly displayed by KMS */
+   struct weston_plane scanout_plane;
struct drm_fb *fb_current, *fb_pending, *fb_last;
struct backlight *backlight;
 
@@ -623,7 +624,7 @@ drm_output_prepare_scanout_view(struct drm_output *output,
 
drm_fb_set_buffer(output->fb_pending, buffer);
 
-   return >fb_plane;
+   return >scanout_plane;
 }
 
 static struct drm_fb *
@@ -2656,10 +2657,10 @@ drm_output_enable(struct weston_output *base)
 
weston_plane_init(>cursor_plane, b->compositor,
  INT32_MIN, INT32_MIN);
-   weston_plane_init(>fb_plane, b->compositor, 0, 0);
+   weston_plane_init(>scanout_plane, b->compositor, 0, 0);
 
weston_compositor_stack_plane(b->compositor, >cursor_plane, 
NULL);
-   weston_compositor_stack_plane(b->compositor, >fb_plane,
+   weston_compositor_stack_plane(b->compositor, >scanout_plane,
  >compositor->primary_plane);
 
weston_log("Output %s, (connector %d, crtc %d)\n",
@@ -2693,7 +2694,7 @@ drm_output_deinit(struct weston_output *base)
else
drm_output_fini_egl(output);
 
-   weston_plane_release(>fb_plane);
+   weston_plane_release(>scanout_plane);
weston_plane_release(>cursor_plane);
 
drmModeFreeProperty(output->dpms_prop);
-- 
2.9.3

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


[PATCH weston 51/68] compositor-drm: Extract overlay FB import to helper

2016-12-09 Thread Daniel Stone
... in order to be able to use it from scanout as well.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1520
---
 libweston/compositor-drm.c | 200 -
 1 file changed, 109 insertions(+), 91 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 1dc63c8..59a764d 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1293,6 +1293,99 @@ drm_plane_state_coords_for_view(struct drm_plane_state 
*state,
pixman_region32_fini(_rect);
 }
 
+static bool
+drm_view_is_opaque(struct weston_view *ev)
+{
+   pixman_region32_t r;
+   bool ret = false;
+
+   /* We can scanout an ARGB buffer if the surface's
+* opaque region covers the whole output, but we have
+* to use XRGB as the KMS format code. */
+   pixman_region32_init_rect(, 0, 0,
+ ev->surface->width,
+ ev->surface->height);
+   pixman_region32_subtract(, , >surface->opaque);
+
+   if (!pixman_region32_not_empty())
+   ret = true;
+
+   pixman_region32_fini();
+
+   return ret;
+}
+
+static struct drm_fb *
+drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
+{
+   struct drm_output *output = state->output;
+   struct drm_backend *b = to_drm_backend(output->base.compositor);
+   struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
+   struct linux_dmabuf_buffer *dmabuf;
+   struct drm_fb *fb;
+   struct gbm_bo *bo;
+
+   /* Don't import buffers which span multiple outputs. */
+   if (ev->output_mask != (1u << output->base.id))
+   return NULL;
+
+   if (ev->alpha != 1.0f)
+   return NULL;
+
+   if (!buffer)
+   return NULL;
+
+   if (wl_shm_buffer_get(buffer->resource))
+   return NULL;
+
+   if (!b->gbm)
+   return NULL;
+
+   dmabuf = linux_dmabuf_buffer_get(buffer->resource);
+   if (dmabuf) {
+#ifdef HAVE_GBM_FD_IMPORT
+   /* XXX: TODO:
+*
+* Use AddFB2 directly, do not go via GBM.
+* Add support for multiplanar formats.
+* Both require refactoring in the DRM-backend to
+* support a mix of gbm_bos and drmfbs.
+*/
+struct gbm_import_fd_data gbm_dmabuf = {
+.fd = dmabuf->attributes.fd[0],
+.width = dmabuf->attributes.width,
+.height = dmabuf->attributes.height,
+.stride = dmabuf->attributes.stride[0],
+.format = dmabuf->attributes.format
+};
+
+   if (dmabuf->attributes.n_planes != 1 ||
+   dmabuf->attributes.offset[0])
+   return NULL;
+
+   bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_FD, _dmabuf,
+  GBM_BO_USE_SCANOUT);
+#else
+   return NULL;
+#endif
+   } else {
+   bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
+  buffer->resource, GBM_BO_USE_SCANOUT);
+   }
+
+   if (!bo)
+   return NULL;
+
+   fb = drm_fb_get_from_bo(bo, b, drm_view_is_opaque(ev), BUFFER_CLIENT);
+   if (!fb) {
+   gbm_bo_destroy(bo);
+   return NULL;
+   }
+
+   drm_fb_set_buffer(fb, buffer);
+   return fb;
+}
+
 /**
  * Return a plane state from a drm_output_state.
  */
@@ -1505,28 +1598,6 @@ drm_output_assign_state(struct drm_output_state *state,
}
 }
 
-static bool
-drm_view_is_opaque(struct weston_view *ev)
-{
-   pixman_region32_t r;
-   bool ret = false;
-
-   /* We can scanout an ARGB buffer if the surface's
-* opaque region covers the whole output, but we have
-* to use XRGB as the KMS format code. */
-   pixman_region32_init_rect(, 0, 0,
- ev->surface->width,
- ev->surface->height);
-   pixman_region32_subtract(, , >surface->opaque);
-
-   if (!pixman_region32_not_empty())
-   ret = true;
-
-   pixman_region32_fini();
-
-   return ret;
-}
-
 static struct weston_plane *
 drm_output_prepare_scanout_view(struct drm_output_state *output_state,
struct weston_view *ev)
@@ -2275,31 +2346,16 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
struct drm_output *output = output_state->output;
struct weston_compositor *ec = output->base.compositor;
struct drm_backend *b = to_drm_backend(ec);
-   struct wl_resource *buffer_resource;
struct drm_plane *p;
struct drm_plane_state *state = NULL;
-   struct linux_dmabuf_buffer *dmabuf;
-   struct gbm_bo 

[PATCH weston 59/68] compositor-drm: Rename region variable

2016-12-09 Thread Daniel Stone
Make it a bit more clear what the purpose of the variable is.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1528
---
 libweston/compositor-drm.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index b7ebb2f..79f2941 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2637,7 +2637,7 @@ drm_assign_planes(struct weston_output *output_base)
struct drm_output_state *state;
struct drm_plane_state *plane_state;
struct weston_view *ev;
-   pixman_region32_t overlap, surface_overlap;
+   pixman_region32_t surface_overlap, renderer_region;
struct weston_plane *primary, *next_plane;
 
assert(!output->state_last);
@@ -2658,7 +2658,7 @@ drm_assign_planes(struct weston_output *output_base)
 * the client buffer can be used directly for the sprite surface
 * as we do for flipping full screen surfaces.
 */
-   pixman_region32_init();
+   pixman_region32_init(_region);
primary = _base->compositor->primary_plane;
 
wl_list_for_each(ev, _base->compositor->view_list, link) {
@@ -2682,7 +2682,7 @@ drm_assign_planes(struct weston_output *output_base)
es->keep_buffer = false;
 
pixman_region32_init(_overlap);
-   pixman_region32_intersect(_overlap, ,
+   pixman_region32_intersect(_overlap, _region,
  >transform.boundingbox);
 
next_plane = NULL;
@@ -2700,7 +2700,8 @@ drm_assign_planes(struct weston_output *output_base)
weston_view_move_to_plane(ev, next_plane);
 
if (next_plane == primary)
-   pixman_region32_union(, ,
+   pixman_region32_union(_region,
+ _region,
  >transform.boundingbox);
 
if (next_plane == primary ||
@@ -2717,7 +2718,7 @@ drm_assign_planes(struct weston_output *output_base)
 
pixman_region32_fini(_overlap);
}
-   pixman_region32_fini();
+   pixman_region32_fini(_region);
 
/* We rely on ev->cursor_view being both an accurate reflection of the
 * cursor plane's state, but also being maintained across repaints to
-- 
2.9.3

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


[PATCH weston 54/68] compositor-drm: Extract drm_fb_addfb into a helper

2016-12-09 Thread Daniel Stone
We currently do the same thing in two places, and will soon have a
third.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1523
---
 libweston/compositor-drm.c | 63 +++---
 1 file changed, 31 insertions(+), 32 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 5fff646..72337a6 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -875,6 +875,33 @@ drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
drm_fb_destroy(fb);
 }
 
+static int
+drm_fb_addfb(struct drm_fb *fb)
+{
+   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
+   int ret;
+
+   handles[0] = fb->handle;
+   pitches[0] = fb->stride;
+   offsets[0] = 0;
+
+   ret = drmModeAddFB2(fb->fd, fb->width, fb->height,
+   fb->format->format, handles, pitches,
+   offsets, >fb_id, 0);
+   if (ret == 0)
+   return 0;
+
+   /* Legacy AddFB can't always infer the format from depth/bpp alone, so
+* check if our format is one of the lucky ones. */
+   if (!fb->format->depth || !fb->format->bpp)
+   return ret;
+
+   ret = drmModeAddFB(fb->fd, fb->width, fb->height,
+  fb->format->depth, fb->format->bpp,
+  fb->stride, fb->handle, >fb_id);
+   return ret;
+}
+
 static struct drm_fb *
 drm_fb_create_dumb(struct drm_backend *b, int width, int height,
   uint32_t format)
@@ -885,12 +912,10 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
struct drm_mode_create_dumb create_arg;
struct drm_mode_destroy_dumb destroy_arg;
struct drm_mode_map_dumb map_arg;
-   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
 
fb = zalloc(sizeof *fb);
if (!fb)
return NULL;
-
fb->refcnt = 1;
 
fb->format = pixel_format_get_info(format);
@@ -923,22 +948,10 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
fb->height = height;
fb->fd = b->drm.fd;
 
-   ret = -1;
-
-   handles[0] = fb->handle;
-   pitches[0] = fb->stride;
-   offsets[0] = 0;
-
-   ret = drmModeAddFB2(b->drm.fd, width, height, fb->format->format,
-   handles, pitches, offsets, >fb_id, 0);
-   if (ret) {
-   ret = drmModeAddFB(b->drm.fd, width, height,
-  fb->format->depth, fb->format->bpp,
-  fb->stride, fb->handle, >fb_id);
-   }
-
-   if (ret)
+   if (drm_fb_addfb(fb) != 0) {
+   weston_log("failed to create kms fb: %m\n");
goto err_bo;
+   }
 
memset(_arg, 0, sizeof map_arg);
map_arg.handle = fb->handle;
@@ -976,8 +989,6 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
*backend,
   bool is_opaque, enum drm_fb_type type)
 {
struct drm_fb *fb = gbm_bo_get_user_data(bo);
-   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
-   int ret;
 
if (fb)
return drm_fb_ref(fb);
@@ -1015,19 +1026,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
*backend,
goto err_free;
}
 
-   handles[0] = fb->handle;
-   pitches[0] = fb->stride;
-   offsets[0] = 0;
-
-   ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
-   fb->format->format, handles, pitches, offsets,
-   >fb_id, 0);
-   if (ret && fb->format->depth && fb->format->bpp)
-   ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
-  fb->format->depth, fb->format->bpp,
-  fb->stride, fb->handle, >fb_id);
-
-   if (ret) {
+   if (drm_fb_addfb(fb) != 0) {
weston_log("failed to create kms fb: %m\n");
goto err_free;
}
-- 
2.9.3

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


[PATCH weston 63/68] compositor-drm: Add modes to drm_output_propose_state

2016-12-09 Thread Daniel Stone
Add support for multiple modes: toggling whether or not the renderer
and/or planes are acceptable. This will be used to implement a smarter
plane-placement heuristic when we have support for testing output
states.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1532
---
 libweston/compositor-drm.c | 37 +++--
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 1eb1fbb..6b5c7cb 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1657,6 +1657,11 @@ drm_output_assign_state(struct drm_output_state *state,
}
 }
 
+enum drm_output_propose_state_mode {
+   DRM_OUTPUT_PROPOSE_STATE_MIXED, /**< mix renderer & planes */
+   DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY, /**< only assign to planes */
+};
+
 static struct weston_plane *
 drm_output_prepare_scanout_view(struct drm_output_state *output_state,
struct weston_view *ev)
@@ -2627,13 +2632,17 @@ err:
 }
 
 static struct drm_output_state *
-drm_output_propose_state(struct weston_output *output_base)
+drm_output_propose_state(struct weston_output *output_base,
+enum drm_output_propose_state_mode mode)
 {
struct drm_output *output = to_drm_output(output_base);
+   struct drm_backend *b = to_drm_backend(output_base->compositor);
struct drm_output_state *state;
struct weston_view *ev;
pixman_region32_t surface_overlap, renderer_region, occluded_region;
struct weston_plane *primary = _base->compositor->primary_plane;
+   bool renderer_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
+   bool planes_ok = !b->sprites_are_broken;
 
assert(!output->state_last);
assert(!output->state_pending);
@@ -2643,6 +2652,7 @@ drm_output_propose_state(struct weston_output 
*output_base)
/*
 * Find a surface for each sprite in the output using some heuristics:
 * 1) size
+
 * 2) frequency of update
 * 3) opacity (though some hw might support alpha blending)
 * 4) clipping (this can be fixed with color keys)
@@ -2695,24 +2705,38 @@ drm_output_propose_state(struct weston_output 
*output_base)
  _region,
  >transform.boundingbox);
 
-   if (next_plane == NULL)
+   /* The cursor plane is 'special' in the sense that we can still
+* place it in the legacy API, and we gate that with a separate
+* cursors_are_broken flag. */
+   if (next_plane == NULL && !b->cursors_are_broken)
next_plane = drm_output_prepare_cursor_view(state, ev);
+   if (!planes_ok)
+   next_plane = primary;
+
if (next_plane == NULL)
next_plane = drm_output_prepare_scanout_view(state, ev);
if (next_plane == NULL)
next_plane = drm_output_prepare_overlay_view(state, ev);
-   if (next_plane == NULL)
-   next_plane = primary;
 
-   if (next_plane == primary)
+   if (!next_plane || next_plane == primary) {
+   if (!renderer_ok)
+   goto err;
+
pixman_region32_union(_region,
  _region,
  >transform.boundingbox);
+   }
}
pixman_region32_fini(_region);
pixman_region32_fini(_region);
 
return state;
+
+err:
+   pixman_region32_fini(_region);
+   pixman_region32_fini(_region);
+   drm_output_state_free(state);
+   return NULL;
 }
 
 static void
@@ -2725,7 +2749,8 @@ drm_assign_planes(struct weston_output *output_base)
struct weston_view *ev;
struct weston_plane *primary = _base->compositor->primary_plane;
 
-   state = drm_output_propose_state(output_base);
+   state = drm_output_propose_state(output_base,
+DRM_OUTPUT_PROPOSE_STATE_MIXED);
 
wl_list_for_each(ev, _base->compositor->view_list, link) {
struct drm_plane *target_plane = NULL;
-- 
2.9.3

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


[PATCH weston 24/68] compositor-drm: Return FB directly from render

2016-12-09 Thread Daniel Stone
Instead of setting state members directly in the drm_output_render
functions (to paint using Pixman or GL), just return a drm_fb, and let
the core function place it in state.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1419
---
 libweston/compositor-drm.c | 30 +++---
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 08634cd..5909239 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -615,11 +615,12 @@ drm_output_prepare_scanout_view(struct drm_output *output,
return >fb_plane;
 }
 
-static void
+static struct drm_fb *
 drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
 {
struct drm_backend *b = to_drm_backend(output->base.compositor);
struct gbm_bo *bo;
+   struct drm_fb *ret;
 
output->base.compositor->renderer->repaint_output(>base,
  damage);
@@ -627,20 +628,21 @@ drm_output_render_gl(struct drm_output *output, 
pixman_region32_t *damage)
bo = gbm_surface_lock_front_buffer(output->gbm_surface);
if (!bo) {
weston_log("failed to lock front buffer: %m\n");
-   return;
+   return NULL;
}
 
-   output->fb_pending = drm_fb_get_from_bo(bo, b, output->gbm_format,
-   BUFFER_GBM_SURFACE);
-   if (!output->fb_pending) {
+   ret = drm_fb_get_from_bo(bo, b, output->gbm_format, BUFFER_GBM_SURFACE);
+   if (!ret) {
weston_log("failed to get drm_fb for bo\n");
gbm_surface_release_buffer(output->gbm_surface, bo);
-   return;
+   return NULL;
}
-   output->fb_pending->gbm_surface = output->gbm_surface;
+   ret->gbm_surface = output->gbm_surface;
+
+   return ret;
 }
 
-static void
+static struct drm_fb *
 drm_output_render_pixman(struct drm_output *output, pixman_region32_t *damage)
 {
struct weston_compositor *ec = output->base.compositor;
@@ -656,7 +658,6 @@ drm_output_render_pixman(struct drm_output *output, 
pixman_region32_t *damage)
 
output->current_image ^= 1;
 
-   output->fb_pending = drm_fb_ref(output->dumb[output->current_image]);
pixman_renderer_output_set_buffer(>base,
  output->image[output->current_image]);
 
@@ -664,6 +665,8 @@ drm_output_render_pixman(struct drm_output *output, 
pixman_region32_t *damage)
 
pixman_region32_fini(_damage);
pixman_region32_fini(_damage);
+
+   return drm_fb_ref(output->dumb[output->current_image]);
 }
 
 static void
@@ -671,6 +674,7 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
 {
struct weston_compositor *c = output->base.compositor;
struct drm_backend *b = to_drm_backend(c);
+   struct drm_fb *fb;
 
/* If we already have a client buffer promoted to scanout, then we don't
 * want to render. */
@@ -678,9 +682,13 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
return;
 
if (b->use_pixman)
-   drm_output_render_pixman(output, damage);
+   fb = drm_output_render_pixman(output, damage);
else
-   drm_output_render_gl(output, damage);
+   fb = drm_output_render_gl(output, damage);
+
+   if (!fb)
+   return;
+   output->fb_pending = fb;
 
pixman_region32_subtract(>primary_plane.damage,
 >primary_plane.damage, damage);
-- 
2.9.3

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


[PATCH weston 42/68] compositor-drm: Discover atomic properties

2016-12-09 Thread Daniel Stone
From: Pekka Paalanen 

Set the atomic client cap, where it exists, and use this to discover the
plane/CRTC/connector properties we require for atomic modesetting.

Differential Revision: https://phabricator.freedesktop.org/D1503

Signed-off-by: Daniel Stone 
Co-authored-by: Pekka Paalanen 
---
 configure.ac   |   3 +
 libweston/compositor-drm.c | 142 +
 2 files changed, 145 insertions(+)

diff --git a/configure.ac b/configure.ac
index 7d5eaa1..8fe48b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,6 +204,9 @@ AM_CONDITIONAL(ENABLE_DRM_COMPOSITOR, test 
x$enable_drm_compositor = xyes)
 if test x$enable_drm_compositor = xyes; then
   AC_DEFINE([BUILD_DRM_COMPOSITOR], [1], [Build the DRM compositor])
   PKG_CHECK_MODULES(DRM_COMPOSITOR, [libudev >= 136 libdrm >= 2.4.30 gbm mtdev 
>= 1.1.0])
+  PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.62],
+   [AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic 
API])],
+   [AC_MSG_WARN([libdrm does not support atomic modesetting, 
will omit that capability])])
   PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 10.2],
[AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports dmabuf 
import])],
[AC_MSG_WARN([gbm does not support dmabuf import, will omit 
that capability])])
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 2db48f1..7874c35 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -99,6 +99,16 @@ struct property_item {
  */
 enum wdrm_plane_property {
WDRM_PLANE_TYPE = 0,
+   WDRM_PLANE_SRC_X,
+   WDRM_PLANE_SRC_Y,
+   WDRM_PLANE_SRC_W,
+   WDRM_PLANE_SRC_H,
+   WDRM_PLANE_CRTC_X,
+   WDRM_PLANE_CRTC_Y,
+   WDRM_PLANE_CRTC_W,
+   WDRM_PLANE_CRTC_H,
+   WDRM_PLANE_FB_ID,
+   WDRM_PLANE_CRTC_ID,
WDRM_PLANE__COUNT
 };
 
@@ -122,6 +132,37 @@ struct plane_properties {
 };
 
 /**
+ * List of properties attached to DRM CRTCs
+ */
+enum wdrm_crtc_property {
+   WDRM_CRTC_MODE_ID = 0,
+   WDRM_CRTC_ACTIVE,
+   WDRM_CRTC__COUNT
+};
+
+/**
+ * List of properties attached to DRM connectors
+ */
+enum wdrm_connector_property {
+   WDRM_CONNECTOR_CRTC_ID = 0,
+   WDRM_CONNECTOR__COUNT
+};
+
+/**
+ * Holding structure for CRTC properties.
+ */
+struct crtc_properties {
+   struct property_item item[WDRM_CRTC__COUNT];
+};
+
+/**
+ * Holding structure for CRTC properties.
+ */
+struct connector_properties {
+   struct property_item item[WDRM_CONNECTOR__COUNT];
+};
+
+/**
  * Mode for drm_output_state_duplicate.
  */
 enum drm_output_state_duplicate_mode {
@@ -172,6 +213,7 @@ struct drm_backend {
int cursors_are_broken;
 
bool universal_planes;
+   bool atomic_modeset;
 
int use_pixman;
 
@@ -301,6 +343,9 @@ struct drm_output {
drmModePropertyPtr dpms_prop;
uint32_t gbm_format;
 
+   struct crtc_properties props_crtc;
+   struct connector_properties props_conn;
+
int vblank_pending;
int page_flip_pending;
int destroy_pending;
@@ -591,6 +636,16 @@ plane_properties_init(struct drm_plane *plane)
 {
static const char * const plane_property_names[] = {
[WDRM_PLANE_TYPE] = "type",
+   [WDRM_PLANE_SRC_X] = "SRC_X",
+   [WDRM_PLANE_SRC_Y] = "SRC_Y",
+   [WDRM_PLANE_SRC_W] = "SRC_W",
+   [WDRM_PLANE_SRC_H] = "SRC_H",
+   [WDRM_PLANE_CRTC_X] = "CRTC_X",
+   [WDRM_PLANE_CRTC_Y] = "CRTC_Y",
+   [WDRM_PLANE_CRTC_W] = "CRTC_W",
+   [WDRM_PLANE_CRTC_H] = "CRTC_H",
+   [WDRM_PLANE_FB_ID] = "FB_ID",
+   [WDRM_PLANE_CRTC_ID] = "CRTC_ID",
};
static const char * const plane_type_names[] = {
[WDRM_PLANE_TYPE_PRIMARY] = "Primary",
@@ -683,6 +738,84 @@ drm_plane_get_type(struct drm_plane *plane)
return WDRM_PLANE_TYPE_OVERLAY;
 }
 
+/**
+ * Initialise DRM properties for CRTC and connector
+ *
+ * Set up the holding structures to track DRM object properties set on the CRTC
+ * and connector associated with an output.
+ * Free the memory allocated here with output_properties_release.
+ *
+ * @param b DRM backend
+ * @param output Output to configure
+ */
+static bool output_properties_init(struct drm_backend *b,
+  struct drm_output *output)
+{
+   static const char * const crtc_property_names[] = {
+   [WDRM_CRTC_MODE_ID] = "MODE_ID",
+   [WDRM_CRTC_ACTIVE] = "ACTIVE",
+   };
+   static const char * const connector_property_names[] = {
+   [WDRM_CONNECTOR_CRTC_ID] = "CRTC_ID",
+   };
+   uint32_t valid_mask, required_mask;
+
+   static_assert(ARRAY_LENGTH(crtc_property_names) == WDRM_CRTC__COUNT,
+ 

[PATCH weston 55/68] compositor-drm: Support multi-planar drm_fb

2016-12-09 Thread Daniel Stone
Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1524
---
 libweston/compositor-drm.c | 45 -
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 72337a6..a2d4c8c 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -243,7 +243,10 @@ struct drm_fb {
 
int refcnt;
 
-   uint32_t fb_id, stride, handle, size;
+   uint32_t fb_id, size;
+   uint32_t handles[4];
+   uint32_t strides[4];
+   uint32_t offsets[4];
const struct pixel_format_info *format;
int width, height;
int fd;
@@ -859,7 +862,7 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
munmap(fb->map, fb->size);
 
memset(_arg, 0, sizeof(destroy_arg));
-   destroy_arg.handle = fb->handle;
+   destroy_arg.handle = fb->handles[0];
drmIoctl(fb->fd, DRM_IOCTL_MODE_DESTROY_DUMB, _arg);
 
drm_fb_destroy(fb);
@@ -878,16 +881,11 @@ drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
 static int
 drm_fb_addfb(struct drm_fb *fb)
 {
-   uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
int ret;
 
-   handles[0] = fb->handle;
-   pitches[0] = fb->stride;
-   offsets[0] = 0;
-
-   ret = drmModeAddFB2(fb->fd, fb->width, fb->height,
-   fb->format->format, handles, pitches,
-   offsets, >fb_id, 0);
+   ret = drmModeAddFB2(fb->fd, fb->width, fb->height, fb->format->format,
+   fb->handles, fb->strides, fb->offsets, >fb_id,
+   0);
if (ret == 0)
return 0;
 
@@ -896,9 +894,13 @@ drm_fb_addfb(struct drm_fb *fb)
if (!fb->format->depth || !fb->format->bpp)
return ret;
 
+   /* Cannot fall back to AddFB for multi-planar formats either. */
+   if (fb->handles[1] || fb->handles[2] || fb->handles[3])
+   return ret;
+
ret = drmModeAddFB(fb->fd, fb->width, fb->height,
   fb->format->depth, fb->format->bpp,
-  fb->stride, fb->handle, >fb_id);
+  fb->strides[0], fb->handles[0], >fb_id);
return ret;
 }
 
@@ -941,8 +943,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
goto err_fb;
 
fb->type = BUFFER_PIXMAN_DUMB;
-   fb->handle = create_arg.handle;
-   fb->stride = create_arg.pitch;
+   fb->handles[0] = create_arg.handle;
+   fb->strides[0] = create_arg.pitch;
fb->size = create_arg.size;
fb->width = width;
fb->height = height;
@@ -954,7 +956,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
}
 
memset(_arg, 0, sizeof map_arg);
-   map_arg.handle = fb->handle;
+   map_arg.handle = fb->handles[0];
ret = drmIoctl(fb->fd, DRM_IOCTL_MODE_MAP_DUMB, _arg);
if (ret)
goto err_add_fb;
@@ -1003,10 +1005,10 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct 
drm_backend *backend,
 
fb->width = gbm_bo_get_width(bo);
fb->height = gbm_bo_get_height(bo);
-   fb->stride = gbm_bo_get_stride(bo);
-   fb->handle = gbm_bo_get_handle(bo).u32;
+   fb->strides[0] = gbm_bo_get_stride(bo);
+   fb->handles[0] = gbm_bo_get_handle(bo).u32;
fb->format = pixel_format_get_info(gbm_bo_get_format(bo));
-   fb->size = fb->stride * fb->height;
+   fb->size = fb->strides[0] * fb->height;
fb->fd = backend->drm.fd;
 
if (!fb->format) {
@@ -1836,7 +1838,8 @@ drm_output_apply_state_legacy(struct drm_output_state 
*state)
 
mode = to_drm_mode(output->base.current_mode);
if (!scanout_plane->state_cur->fb ||
-   scanout_plane->state_cur->fb->stride != scanout_state->fb->stride) {
+   scanout_plane->state_cur->fb->strides[0] !=
+   scanout_state->fb->strides[0]) {
ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
 scanout_state->fb->fb_id,
 0, 0,
@@ -3515,7 +3518,7 @@ drm_output_init_pixman(struct drm_output *output, struct 
drm_backend *b)
output->image[i] =
pixman_image_create_bits(pixman_format, w, h,
 output->dumb[i]->map,
-output->dumb[i]->stride);
+output->dumb[i]->strides[0]);
if (!output->image[i])
goto err;
}
@@ -4539,7 +4542,7 @@ recorder_frame_notify(struct wl_listener *listener, void 
*data)
return;
 
ret = drmPrimeHandleToFD(b->drm.fd,
-output->scanout_plane->state_cur->fb->handle,
+   

[PATCH weston 47/68] compositor-drm: Extract buffer->plane co-ord translation

2016-12-09 Thread Daniel Stone
Pull this into a helper function, so we can use it everywhere.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1516
---
 libweston/compositor-drm.c | 157 +
 1 file changed, 88 insertions(+), 69 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 893fdbd..b57e2ee 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1208,6 +1208,92 @@ drm_plane_state_put_back(struct drm_plane_state *state)
 }
 
 /**
+ * Given a weston_view, fill the drm_plane_state's co-ordinates to display on
+ * a given plane.
+ */
+static void
+drm_plane_state_coords_for_view(struct drm_plane_state *state,
+   struct weston_view *ev)
+{
+   struct drm_output *output = state->output;
+   struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
+   pixman_region32_t dest_rect, src_rect;
+   pixman_box32_t *box, tbox;
+   wl_fixed_t sx1, sy1, sx2, sy2;
+
+   /* Update the base weston_plane co-ordinates. */
+   box = pixman_region32_extents(>transform.boundingbox);
+   state->plane->base.x = box->x1;
+   state->plane->base.y = box->y1;
+
+   /* First calculate the destination co-ordinates by taking the
+* area of the view which is visible on this output, performing any
+* transforms to account for output rotation and scale as necessary. */
+   pixman_region32_init(_rect);
+   pixman_region32_intersect(_rect, >transform.boundingbox,
+ >base.region);
+   pixman_region32_translate(_rect, -output->base.x, -output->base.y);
+   box = pixman_region32_extents(_rect);
+   tbox = weston_transformed_rect(output->base.width,
+  output->base.height,
+  output->base.transform,
+  output->base.current_scale,
+  *box);
+   state->dest_x = tbox.x1;
+   state->dest_y = tbox.y1;
+   state->dest_w = tbox.x2 - tbox.x1;
+   state->dest_h = tbox.y2 - tbox.y1;
+   pixman_region32_fini(_rect);
+
+   /* Now calculate the source rectangle, by finding the points in the
+* view and working backwards to source co-ordinates. */
+   pixman_region32_init(_rect);
+   pixman_region32_intersect(_rect, >transform.boundingbox,
+ >base.region);
+   box = pixman_region32_extents(_rect);
+
+   /* Accounting for any transformations made to this particular surface
+* view, find the source rectangle to use. */
+   weston_view_from_global_fixed(ev,
+ wl_fixed_from_int(box->x1),
+ wl_fixed_from_int(box->y1),
+ , );
+   weston_view_from_global_fixed(ev,
+ wl_fixed_from_int(box->x2),
+ wl_fixed_from_int(box->y2),
+ , );
+
+   /* XXX: How is this possible ... ? */
+   if (sx1 < 0)
+   sx1 = 0;
+   if (sy1 < 0)
+   sy1 = 0;
+   if (sx2 > wl_fixed_from_int(ev->surface->width))
+   sx2 = wl_fixed_from_int(ev->surface->width);
+   if (sy2 > wl_fixed_from_int(ev->surface->height))
+   sy2 = wl_fixed_from_int(ev->surface->height);
+
+   tbox.x1 = sx1;
+   tbox.y1 = sy1;
+   tbox.x2 = sx2;
+   tbox.y2 = sy2;
+
+   /* Apply viewport transforms in reverse, to get the source co-ordinates
+* in buffer space. */
+   tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width),
+  wl_fixed_from_int(ev->surface->height),
+  viewport->buffer.transform,
+  viewport->buffer.scale,
+  tbox);
+
+   state->src_x = tbox.x1 << 8;
+   state->src_y = tbox.y1 << 8;
+   state->src_w = (tbox.x2 - tbox.x1) << 8;
+   state->src_h = (tbox.y2 - tbox.y1) << 8;
+   pixman_region32_fini(_rect);
+}
+
+/**
  * Return a plane state from a drm_output_state.
  */
 static struct drm_plane_state *
@@ -2208,16 +2294,13 @@ drm_output_prepare_overlay_view(struct drm_output_state 
*output_state,
 {
struct drm_output *output = output_state->output;
struct weston_compositor *ec = output->base.compositor;
-   struct drm_backend *b = to_drm_backend(ec);
struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
+   struct drm_backend *b = to_drm_backend(ec);
struct wl_resource *buffer_resource;
struct drm_plane *p;
struct drm_plane_state *state = NULL;
struct linux_dmabuf_buffer *dmabuf;
struct gbm_bo *bo;
-   

[PATCH weston 19/68] compositor-drm: Refcount drm_fb

2016-12-09 Thread Daniel Stone
Sometimes we need to duplicate an existing drm_fb, e.g. when
pageflipping to the same buffer to kickstart the repaint loop. To handle
situations like these, and simplify resource management for dumb and
cursor buffers, refcount drm_fb.

Differential Revision: https://phabricator.freedesktop.org/D1491

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index eb735b2..a684ac9 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -140,6 +140,8 @@ enum drm_fb_type {
 struct drm_fb {
enum drm_fb_type type;
 
+   int refcnt;
+
uint32_t fb_id, stride, handle, size;
const struct pixel_format_info *format;
int width, height;
@@ -302,6 +304,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
if (!fb)
return NULL;
 
+   fb->refcnt = 1;
+
fb->format = pixel_format_get_info(format);
if (!fb->format) {
weston_log("failed to look up format 0x%lx\n",
@@ -312,6 +316,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
if (!fb->format->depth || !fb->format->bpp) {
weston_log("format 0x%lx is not compatible with dumb buffers\n",
   (unsigned long) format);
+   goto err_fb;
}
 
memset(_arg, 0, sizeof create_arg);
@@ -384,6 +389,13 @@ err_fb:
 }
 
 static struct drm_fb *
+drm_fb_ref(struct drm_fb *fb)
+{
+   fb->refcnt++;
+   return fb;
+}
+
+static struct drm_fb *
 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
   uint32_t format, enum drm_fb_type type)
 {
@@ -392,13 +404,14 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
*backend,
int ret;
 
if (fb)
-   return fb;
+   return drm_fb_ref(fb);
 
fb = zalloc(sizeof *fb);
if (fb == NULL)
return NULL;
 
fb->type = type;
+   fb->refcnt = 1;
fb->bo = bo;
 
fb->width = gbm_bo_get_width(bo);
@@ -472,6 +485,10 @@ drm_fb_unref(struct drm_fb *fb)
if (!fb)
return;
 
+   assert(fb->refcnt > 0);
+   if (--fb->refcnt > 0)
+   return;
+
switch (fb->type) {
case BUFFER_PIXMAN_DUMB:
/* nothing: pixman buffers are destroyed manually */
-- 
2.9.3

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


[PATCH weston 29/68] compositor-drm: Refactor sprite create/destroy into helpers

2016-12-09 Thread Daniel Stone
From: Pekka Paalanen 

This moves the single sprite creation code from create_sprites() into a
new function. The readability clean-up is small, but my intention is to
write an alternate version of create_sprites(), and sharing the single
sprite creation code is useful.

[daniels: Genericised from drm_sprite to drm_plane, moving some of the
  logic back into create_sprites(), also symmetrical
  drm_plane_destroy.]

Signed-off-by: Pekka Paalanen 
Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1409
---
 libweston/compositor-drm.c | 188 -
 1 file changed, 117 insertions(+), 71 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 1b123b5..9a27f03 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1703,6 +1703,123 @@ init_pixman(struct drm_backend *b)
 }
 
 /**
+ * Create a drm_plane for a hardware plane
+ *
+ * Creates one drm_plane structure for a hardware plane, and initialises its
+ * properties and formats.
+ *
+ * This function does not add the plane to the list of usable planes in Weston
+ * itself; the caller is responsible for this.
+ *
+ * Call drm_plane_destroy to clean up the plane.
+ *
+ * @param ec Compositor to create plane for
+ * @param kplane DRM plane to create
+ */
+static struct drm_plane *
+drm_plane_create(struct drm_backend *b, const drmModePlane *kplane)
+{
+   struct drm_plane *plane;
+
+   plane = zalloc(sizeof(*plane) + ((sizeof(uint32_t)) *
+ kplane->count_formats));
+   if (!plane) {
+   weston_log("%s: out of memory\n", __func__);
+   return NULL;
+   }
+
+   plane->backend = b;
+   plane->possible_crtcs = kplane->possible_crtcs;
+   plane->plane_id = kplane->plane_id;
+   plane->count_formats = kplane->count_formats;
+   memcpy(plane->formats, kplane->formats,
+  kplane->count_formats * sizeof(kplane->formats[0]));
+
+   weston_plane_init(>base, b->compositor, 0, 0);
+   wl_list_insert(>sprite_list, >link);
+
+   return plane;
+}
+
+/**
+ * Destroy one DRM plane
+ *
+ * Destroy a DRM plane, removing it from screen and releasing its retained
+ * buffers in the process. The counterpart to drm_plane_create.
+ *
+ * @param plane Plane to deallocate (will be freed)
+ */
+static void
+drm_plane_destroy(struct drm_plane *plane)
+{
+   drmModeSetPlane(plane->backend->drm.fd, plane->plane_id, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0);
+   drm_fb_unref(plane->fb_last);
+   drm_fb_unref(plane->fb_current);
+   assert(!plane->fb_pending);
+   weston_plane_release(>base);
+   wl_list_remove(>link);
+   free(plane);
+}
+
+/**
+ * Initialise sprites (overlay planes)
+ *
+ * Walk the list of provided DRM planes, and add overlay planes.
+ *
+ * Call destroy_sprites to free these planes.
+ *
+ * @param ec Compositor to create sprites for.
+ */
+static void
+create_sprites(struct drm_backend *b)
+{
+   drmModePlaneRes *kplane_res;
+   drmModePlane *kplane;
+   struct drm_plane *drm_plane;
+   uint32_t i;
+
+   kplane_res = drmModeGetPlaneResources(b->drm.fd);
+   if (!kplane_res) {
+   weston_log("failed to get plane resources: %s\n",
+   strerror(errno));
+   return;
+   }
+
+   for (i = 0; i < kplane_res->count_planes; i++) {
+   kplane = drmModeGetPlane(b->drm.fd, kplane_res->planes[i]);
+   if (!kplane)
+   continue;
+
+   drm_plane = drm_plane_create(b, kplane);
+   drmModeFreePlane(kplane);
+   if (!drm_plane)
+   continue;
+
+   weston_compositor_stack_plane(b->compositor, _plane->base,
+ >compositor->primary_plane);
+   }
+
+   drmModeFreePlaneResources(kplane_res);
+}
+
+/**
+ * Clean up sprites (overlay planes)
+ *
+ * The counterpart to create_sprites.
+ *
+ * @param compositor Compositor to deallocate sprites for.
+ */
+static void
+destroy_sprites(struct drm_backend *backend)
+{
+   struct drm_plane *plane, *next;
+
+   wl_list_for_each_safe(plane, next, >sprite_list, link)
+   drm_plane_destroy(plane);
+}
+
+/**
  * Add a mode to output's mode list
  *
  * Copy the supplied DRM mode into a Weston mode structure, and add it to the
@@ -2703,77 +2820,6 @@ create_output_for_connector(struct drm_backend *b,
return 0;
 }
 
-static void
-create_sprites(struct drm_backend *b)
-{
-   struct drm_plane *plane;
-   drmModePlaneRes *kplane_res;
-   drmModePlane *kplane;
-   uint32_t i;
-
-   kplane_res = drmModeGetPlaneResources(b->drm.fd);
-   if (!kplane_res) {
-   weston_log("failed to 

[PATCH weston 33/68] compositor-drm: Introduce drm_output_state structure

2016-12-09 Thread Daniel Stone
Currently this doesn't actually really do anything, but will be used in
the future to track the state for both modeset and repaint requests.
Completion of the request gives us a single request-completion path for
both pageflip and vblank events.

Differential Revision: https://phabricator.freedesktop.org/D1497

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 229 ++---
 1 file changed, 196 insertions(+), 33 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 3dd2924..106d851 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -121,6 +121,19 @@ struct plane_properties {
uint64_t value;
 };
 
+/**
+ * Mode for drm_output_state_duplicate.
+ */
+enum drm_output_state_duplicate_mode {
+   DRM_OUTPUT_STATE_CLEAR_PLANES, /**< reset all planes to off */
+   DRM_OUTPUT_STATE_PRESERVE_PLANES, /**< preserve plane state */
+};
+
+enum drm_output_state_update_mode {
+   DRM_OUTPUT_STATE_UPDATE_SYNCHRONOUS, /**< state already applied */
+   DRM_OUTPUT_STATE_UPDATE_ASYNCHRONOUS, /**< pending event delivery */
+};
+
 struct drm_backend {
struct weston_backend base;
struct weston_compositor *compositor;
@@ -210,6 +223,16 @@ struct drm_edid {
 };
 
 /**
+ * Output state holds the dynamic state for one Weston output, i.e. a KMS CRTC,
+ * plus >= 1 each of encoder/connector/plane. Since everything but the planes
+ * is currently statically assigned per-output, we mainly use this to track
+ * plane state.
+ */
+struct drm_output_state {
+   struct drm_output *output;
+};
+
+/**
  * A plane represents one buffer, positioned within a CRTC, and stacked
  * relative to other planes on the same CRTC.
  *
@@ -278,6 +301,10 @@ struct drm_output {
struct drm_fb *fb_current, *fb_pending, *fb_last;
struct backlight *backlight;
 
+   struct drm_output_state *state_last;
+   struct drm_output_state *state_cur;
+   struct drm_output_state *state_pending;
+
struct drm_fb *dumb[2];
pixman_image_t *image[2];
int current_image;
@@ -645,6 +672,9 @@ drm_output_set_cursor(struct drm_output *output);
 static void
 drm_output_update_msc(struct drm_output *output, unsigned int seq);
 
+static void
+drm_output_destroy(struct weston_output *output_base);
+
 static int
 drm_plane_crtc_supported(struct drm_output *output, struct drm_plane *plane)
 {
@@ -905,6 +935,112 @@ drm_fb_unref(struct drm_fb *fb)
}
 }
 
+/**
+ * Allocate a new, empty drm_output_state. This should not generally be used
+ * in the repaint cycle; see drm_output_state_duplicate.
+ */
+static struct drm_output_state *
+drm_output_state_alloc(struct drm_output *output)
+{
+   struct drm_output_state *state = calloc(1, sizeof(*state));
+
+   state->output = output;
+
+   return state;
+}
+
+/**
+ * Duplicate an existing drm_output_state into a new one. This is generally
+ * used during the repaint cycle, to capture the existing state of an output
+ * and modify it to create a new state to be used.
+ *
+ * The mode determines whether the output will be reset to an a blank state,
+ * or an exact mirror of the current state.
+ */
+static struct drm_output_state *
+drm_output_state_duplicate(struct drm_output_state *src,
+  enum drm_output_state_duplicate_mode plane_mode)
+{
+   struct drm_output_state *dst = malloc(sizeof(*dst));
+
+   assert(dst);
+   memcpy(dst, src, sizeof(*dst));
+
+   return dst;
+}
+
+/**
+ * Free an unused drm_output_state.
+ */
+static void
+drm_output_state_free(struct drm_output_state *state)
+{
+   if (!state)
+   return;
+
+   free(state);
+}
+
+/**
+ * Mark a drm_output_state (the output's last state) as complete. This handles
+ * any post-completion actions such as updating the repaint timer, disabling 
the
+ * output, and finally freeing the state.
+ */
+static void
+drm_output_update_complete(struct drm_output *output, uint32_t flags,
+  unsigned int sec, unsigned int usec)
+{
+   struct timespec ts;
+
+   drm_output_state_free(output->state_last);
+   output->state_last = NULL;
+
+   if (output->destroy_pending) {
+   drm_output_destroy(>base);
+   goto out;
+   } else if (output->disable_pending) {
+   weston_output_disable(>base);
+   goto out;
+   }
+
+   ts.tv_sec = sec;
+   ts.tv_nsec = usec * 1000;
+   weston_output_finish_frame(>base, , flags);
+
+   /* We can't call this from frame_notify, because the output's
+* repaint needed flag is cleared just after that */
+   if (output->recorder)
+   weston_output_schedule_repaint(>base);
+
+out:
+   output->destroy_pending = 0;
+   output->disable_pending = 0;
+}
+
+/**
+ * Mark an output state as current on the output, i.e. it has been
+ * submitted to the 

[PATCH weston 38/68] compositor-drm: Split repaint into helper

2016-12-09 Thread Daniel Stone
We can separate repainting into two phases: one performing the actual
repaint (essentially drm_output_render) and populating the plane state
that wasn't already populated by drm_output_assign_planes, and another
applying this state to the device.

Differential Revision: https://phabricator.freedesktop.org/D1500

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 58 +-
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index f0a13e1..f1f9bcb 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1527,12 +1527,10 @@ drm_waitvblank_pipe(struct drm_output *output)
 }
 
 static int
-drm_output_repaint(struct weston_output *output_base,
-  pixman_region32_t *damage)
+drm_output_apply_state(struct drm_output_state *state)
 {
-   struct drm_output *output = to_drm_output(output_base);
-   struct drm_backend *backend =
-   to_drm_backend(output->base.compositor);
+   struct drm_output *output = state->output;
+   struct drm_backend *backend = to_drm_backend(output->base.compositor);
struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_plane_state *scanout_state;
struct drm_plane_state *ps;
@@ -1540,20 +1538,7 @@ drm_output_repaint(struct weston_output *output_base,
struct drm_mode *mode;
int ret = 0;
 
-   if (output->disable_pending || output->destroy_pending)
-   goto err;
-
-   assert(!output->state_last);
-   if (!output->state_pending)
-   output->state_pending =
-   drm_output_state_duplicate(output->state_cur,
-  
DRM_OUTPUT_STATE_CLEAR_PLANES);
-
-   drm_output_render(output, damage);
-   scanout_state = drm_output_state_get_plane(output->state_pending,
-  scanout_plane);
-   if (!scanout_state || !scanout_state->fb)
-   goto err;
+   scanout_state = drm_output_state_get_plane(state, scanout_plane);
 
/* The legacy SetCrtc API doesn't allow us to do scaling, and the
 * legacy PageFlip API doesn't allow us to do clipping either. */
@@ -1580,7 +1565,7 @@ drm_output_repaint(struct weston_output *output_base,
weston_log("set mode failed: %m\n");
goto err;
}
-   output_base->set_dpms(output_base, WESTON_DPMS_ON);
+   output->base.set_dpms(>base, WESTON_DPMS_ON);
}
 
if (drmModePageFlip(backend->drm.fd, output->crtc_id,
@@ -1592,7 +1577,7 @@ drm_output_repaint(struct weston_output *output_base,
 
assert(!output->page_flip_pending);
 
-   drm_output_set_cursor(output->state_pending);
+   drm_output_set_cursor(state);
 
/*
 * Now, update all the sprite surfaces
@@ -1655,6 +1640,37 @@ err:
return -1;
 }
 
+static int
+drm_output_repaint(struct weston_output *output_base,
+  pixman_region32_t *damage)
+{
+   struct drm_output *output = to_drm_output(output_base);
+   struct drm_plane_state *scanout_state;
+
+   if (output->disable_pending || output->destroy_pending)
+   goto err;
+
+   assert(!output->state_last);
+   if (!output->state_pending)
+   output->state_pending =
+   drm_output_state_duplicate(output->state_cur,
+  
DRM_OUTPUT_STATE_CLEAR_PLANES);
+
+   drm_output_render(output, damage);
+   scanout_state = drm_output_state_get_plane(output->state_pending,
+  output->scanout_plane);
+   if (!scanout_state || !scanout_state->fb)
+   goto err;
+
+   return drm_output_apply_state(output->state_pending);
+
+err:
+   drm_output_state_free(output->state_pending);
+   output->state_pending = NULL;
+   return -1;
+}
+
+
 static void
 drm_output_start_repaint_loop(struct weston_output *output_base)
 {
-- 
2.9.3

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


[PATCH weston 39/68] compositor-drm: Move DPMS into output state

2016-12-09 Thread Daniel Stone
Extend drm_output_state to also cover DPMS, so we can use it to enable
and disable outputs, and always keep a coherent state.

Differential Revision: https://phabricator.freedesktop.org/D1501

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 139 +
 1 file changed, 114 insertions(+), 25 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index f1f9bcb..ec8db31 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -231,6 +231,7 @@ struct drm_edid {
 struct drm_output_state {
struct drm_output *output;
 
+   enum dpms_enum dpms;
struct wl_list plane_list;
 };
 
@@ -301,12 +302,11 @@ struct drm_output {
drmModePropertyPtr dpms_prop;
uint32_t gbm_format;
 
-   enum dpms_enum dpms;
-
int vblank_pending;
int page_flip_pending;
int destroy_pending;
int disable_pending;
+   int dpms_off_pending;
 
struct gbm_surface *gbm_surface;
struct drm_fb *gbm_cursor_fb[2];
@@ -1107,6 +1107,7 @@ drm_output_state_alloc(struct drm_output *output)
struct drm_output_state *state = calloc(1, sizeof(*state));
 
state->output = output;
+   state->dpms = WESTON_DPMS_OFF;
wl_list_init(>plane_list);
 
return state;
@@ -1163,6 +1164,23 @@ drm_output_state_free(struct drm_output_state *state)
free(state);
 }
 
+static struct drm_output_state *
+drm_output_get_disable_state(struct drm_output *output)
+{
+   struct drm_output_state *state;
+
+   if (!output->state_cur)
+   state = drm_output_state_alloc(output);
+   else
+   state = drm_output_state_duplicate(output->state_cur,
+  
DRM_OUTPUT_STATE_CLEAR_PLANES);
+   state->dpms = WESTON_DPMS_OFF;
+
+   return state;
+}
+
+static int drm_output_apply_state(struct drm_output_state *state);
+
 /**
  * Mark a drm_output_state (the output's last state) as complete. This handles
  * any post-completion actions such as updating the repaint timer, disabling 
the
@@ -1173,6 +1191,7 @@ drm_output_update_complete(struct drm_output *output, 
uint32_t flags,
   unsigned int sec, unsigned int usec)
 {
struct drm_plane_state *ps;
+   struct drm_output_state *os;
struct timespec ts;
 
wl_list_for_each(ps, >state_cur->plane_list, link)
@@ -1187,6 +1206,9 @@ drm_output_update_complete(struct drm_output *output, 
uint32_t flags,
} else if (output->disable_pending) {
weston_output_disable(>base);
goto out;
+   } else if (output->dpms_off_pending) {
+   os = drm_output_get_disable_state(output);
+   drm_output_apply_state(os);
}
 
ts.tv_sec = sec;
@@ -1201,6 +1223,7 @@ drm_output_update_complete(struct drm_output *output, 
uint32_t flags,
 out:
output->destroy_pending = 0;
output->disable_pending = 0;
+   output->dpms_off_pending = 0;
 }
 
 /**
@@ -1247,7 +1270,6 @@ drm_output_assign_state(struct drm_output_state *state,
}
 }
 
-
 static int
 drm_view_transform_supported(struct weston_view *ev)
 {
@@ -1538,7 +1560,41 @@ drm_output_apply_state(struct drm_output_state *state)
struct drm_mode *mode;
int ret = 0;
 
-   scanout_state = drm_output_state_get_plane(state, scanout_plane);
+   if (state->dpms != WESTON_DPMS_ON) {
+   wl_list_for_each(ps, >plane_list, link) {
+   p = ps->plane;
+   assert(ps->fb == NULL);
+   assert(ps->output == NULL);
+
+   if (p->type != WDRM_PLANE_TYPE_OVERLAY)
+   continue;
+
+   ret = drmModeSetPlane(backend->drm.fd, p->plane_id,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+   if (ret)
+   weston_log("drmModeSetPlane failed disable: 
%m\n");
+   }
+
+   if (output->cursor_plane) {
+   ret = drmModeSetCursor(backend->drm.fd, output->crtc_id,
+  0, 0, 0);
+   if (ret)
+   weston_log("drmModeSetCursor failed disable: 
%m\n");
+   }
+
+   ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id, 0, 0, 0,
+>connector_id, 0, NULL);
+   if (ret)
+   weston_log("drmModeSetCrtc failed disabling: %m\n");
+
+   drm_output_assign_state(state,
+   DRM_OUTPUT_STATE_UPDATE_SYNCHRONOUS);
+
+   return 0;
+   }
+
+   scanout_state =
+   drm_output_state_get_existing_plane(state, scanout_plane);
 
/* The legacy SetCrtc API doesn't 

[PATCH weston 20/68] compositor-drm: Use refcounted FBs for Pixman

2016-12-09 Thread Daniel Stone
When using the Pixman renderer, use drm_fb refcounting explicitly.

Differential Revision: https://phabricator.freedesktop.org/D1492

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a684ac9..950c265 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -491,7 +491,7 @@ drm_fb_unref(struct drm_fb *fb)
 
switch (fb->type) {
case BUFFER_PIXMAN_DUMB:
-   /* nothing: pixman buffers are destroyed manually */
+   drm_fb_destroy_dumb(fb);
break;
case BUFFER_CLIENT:
gbm_bo_destroy(fb->bo);
@@ -652,7 +652,7 @@ drm_output_render_pixman(struct drm_output *output, 
pixman_region32_t *damage)
 
output->current_image ^= 1;
 
-   output->next = output->dumb[output->current_image];
+   output->next = drm_fb_ref(output->dumb[output->current_image]);
pixman_renderer_output_set_buffer(>base,
  output->image[output->current_image]);
 
@@ -1973,7 +1973,7 @@ drm_output_init_pixman(struct drm_output *output, struct 
drm_backend *b)
 err:
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
if (output->dumb[i])
-   drm_fb_destroy_dumb(output->dumb[i]);
+   drm_fb_unref(output->dumb[i]);
if (output->image[i])
pixman_image_unref(output->image[i]);
 
@@ -1993,8 +1993,8 @@ drm_output_fini_pixman(struct drm_output *output)
pixman_region32_fini(>previous_damage);
 
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
-   drm_fb_destroy_dumb(output->dumb[i]);
pixman_image_unref(output->image[i]);
+   drm_fb_unref(output->dumb[i]);
output->dumb[i] = NULL;
output->image[i] = NULL;
}
-- 
2.9.3

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


[PATCH weston 37/68] compositor-drm: Don't repaint if no damage

2016-12-09 Thread Daniel Stone
If we don't have any damage for the primary plane, then don't force a
repaint; simply reuse the old buffer we already have.

Differential Revision: https://phabricator.freedesktop.org/D1499

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index e575429..f0a13e1 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1430,6 +1430,7 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
 {
struct weston_compositor *c = output->base.compositor;
struct drm_plane_state *scanout_state;
+   struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_backend *b = to_drm_backend(c);
struct drm_fb *fb;
 
@@ -1440,10 +1441,20 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
if (scanout_state->fb)
return;
 
-   if (b->use_pixman)
+   if (!pixman_region32_not_empty(damage) &&
+   scanout_plane->state_cur->fb &&
+   (scanout_plane->state_cur->fb->type == BUFFER_GBM_SURFACE ||
+scanout_plane->state_cur->fb->type == BUFFER_PIXMAN_DUMB) &&
+   scanout_plane->state_cur->fb->width ==
+   output->base.current_mode->width &&
+   scanout_plane->state_cur->fb->height ==
+   output->base.current_mode->height) {
+   fb = drm_fb_ref(scanout_plane->state_cur->fb);
+   } else if (b->use_pixman) {
fb = drm_output_render_pixman(output, damage);
-   else
+   } else {
fb = drm_output_render_gl(output, damage);
+   }
 
if (!fb) {
drm_plane_state_put_back(scanout_state);
-- 
2.9.3

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


[PATCH weston 06/68] Remove DPMS-on when going offscreen

2016-12-09 Thread Daniel Stone
Forcing DPMS on when we lose our session may force an expensive modeset
operation, which is pointless if the next consumer (another compositor,
or the console) is going to do a modeset. These should force DPMS on
regardless.

This actively causes problems for the DRM backend, in that it may
actually require a repaint to set coherent state for DPMS off -> DPMS on
transitions, which is very much not what we want when going offscreen.

As DRM is the only backend which actually implements DPMS, just remove
this call.

Differential Revision: https://phabricator.freedesktop.org/D1483

Signed-off-by: Daniel Stone 
---
 libweston/compositor.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/libweston/compositor.c b/libweston/compositor.c
index ad59156..895a040 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -3933,10 +3933,9 @@ weston_compositor_wake(struct weston_compositor 
*compositor)
 
switch (old_state) {
case WESTON_COMPOSITOR_SLEEPING:
-   weston_compositor_dpms(compositor, WESTON_DPMS_ON);
-   /* fall through */
case WESTON_COMPOSITOR_IDLE:
case WESTON_COMPOSITOR_OFFSCREEN:
+   weston_compositor_dpms(compositor, WESTON_DPMS_ON);
wl_signal_emit(>wake_signal, compositor);
/* fall through */
default:
@@ -3952,10 +3951,6 @@ weston_compositor_wake(struct weston_compositor 
*compositor)
  * This is used for example to prevent further rendering while the
  * compositor is shutting down.
  *
- * \note When offscreen state is entered, outputs will be powered
- * back on if they were sleeping (in DPMS off mode), even though
- * no rendering will be performed.
- *
  * Stops the idle timer.
  */
 WL_EXPORT void
@@ -3965,8 +3960,6 @@ weston_compositor_offscreen(struct weston_compositor 
*compositor)
case WESTON_COMPOSITOR_OFFSCREEN:
return;
case WESTON_COMPOSITOR_SLEEPING:
-   weston_compositor_dpms(compositor, WESTON_DPMS_ON);
-   /* fall through */
default:
compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
wl_event_source_timer_update(compositor->idle_source, 0);
-- 
2.9.3

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


[PATCH weston 40/68] compositor-drm: Use apply_state for starting repaint

2016-12-09 Thread Daniel Stone
Rather than open-coding it ourselves, use the new apply_state helper in
drm_output_start_repaint.

Signed-off-by: Daniel Stone 
Reported-by: Fabien DESSENNE 

Differential Revision: https://phabricator.freedesktop.org/D1514
---
 libweston/compositor-drm.c | 27 ---
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index ec8db31..5959aed 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1743,12 +1743,9 @@ static void
 drm_output_start_repaint_loop(struct weston_output *output_base)
 {
struct drm_output *output = to_drm_output(output_base);
-   struct drm_output_state *output_state;
-   struct drm_plane_state *plane_state;
struct drm_plane *scanout_plane = output->scanout_plane;
struct drm_backend *backend =
to_drm_backend(output_base->compositor);
-   uint32_t fb_id;
struct timespec ts, tnow;
struct timespec vbl2now;
int64_t refresh_nsec;
@@ -1798,37 +1795,21 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
/* Immediate query didn't provide valid timestamp.
 * Use pageflip fallback.
 */
-   fb_id = scanout_plane->state_cur->fb->fb_id;
 
assert(!output->page_flip_pending);
assert(!output->state_last);
assert(!output->state_pending);
 
-   output_state =
+   output->state_pending =
drm_output_state_duplicate(output->state_cur,
   DRM_OUTPUT_STATE_PRESERVE_PLANES);
 
-   if (drmModePageFlip(backend->drm.fd, output->crtc_id, fb_id,
-   DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
-   weston_log("queueing pageflip failed: %m\n");
-   drm_output_state_free(output_state);
+   ret = drm_output_apply_state(output->state_pending);
+   if (ret != 0) {
+   weston_log("applying repaint-start state failed: %m\n");
goto finish_frame;
}
 
-   wl_list_for_each(plane_state, _state->plane_list, link) {
-   if (plane_state->plane->type != WDRM_PLANE_TYPE_OVERLAY)
-   continue;
-
-   vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
-   vbl.request.type |= drm_waitvblank_pipe(output);
-   vbl.request.sequence = 1;
-   vbl.request.signal = (unsigned long) plane_state;
-   drmWaitVBlank(backend->drm.fd, );
-   }
-
-   drm_output_assign_state(output_state,
-   DRM_OUTPUT_STATE_UPDATE_ASYNCHRONOUS);
-
return;
 
 finish_frame:
-- 
2.9.3

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


[PATCH weston 44/68] compositor-drm: Add to_drm_mode helper

2016-12-09 Thread Daniel Stone
Much like we already have to_drm_output and to_drm_backend.

Differential Revision: https://phabricator.freedesktop.org/D1505

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index c98ba25..b33d519 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -393,6 +393,12 @@ to_drm_backend(struct weston_compositor *base)
return container_of(base->backend, struct drm_backend, base);
 }
 
+static inline struct drm_mode *
+to_drm_mode(struct weston_mode *base)
+{
+   return container_of(base, struct drm_mode, base);
+}
+
 /**
  * Return a string describing the type of a DRM object
  */
@@ -1740,7 +1746,7 @@ drm_output_apply_state(struct drm_output_state *state)
assert(scanout_state->src_w == scanout_state->dest_w << 16);
assert(scanout_state->src_h == scanout_state->dest_h << 16);
 
-   mode = container_of(output->base.current_mode, struct drm_mode, base);
+   mode = to_drm_mode(output->base.current_mode);
if (!scanout_plane->state_cur->fb ||
scanout_plane->state_cur->fb->stride != scanout_state->fb->stride) {
ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
-- 
2.9.3

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


[PATCH weston 31/68] compositor-drm: Add universal plane awareness

2016-12-09 Thread Daniel Stone
From: Pekka Paalanen 

Add awareness of, rather than support for, universal planes. Activate
the client cap when we start if possible, and if this is activated,
studiously ignore non-overlay planes. For now.

[daniels: Rebased, split up, otherwise modified.]

Differential Revision: https://phabricator.freedesktop.org/D1495

Signed-off-by: Daniel Stone 
Co-authored-by: Pekka Paalanen 
Co-authored-by: Louis-Francis Ratté-Boulianne 

---
 libweston/compositor-drm.c | 406 +
 1 file changed, 406 insertions(+)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index e4d6743..46fcf0a 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -62,10 +62,18 @@
 #include "presentation-time-server-protocol.h"
 #include "linux-dmabuf.h"
 
+#ifndef static_assert
+#define static_assert(cond, msg) assert((cond) && msg)
+#endif
+
 #ifndef DRM_CAP_TIMESTAMP_MONOTONIC
 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
 #endif
 
+#ifndef DRM_CLIENT_CAP_UNIVERSAL_PLANES
+#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+#endif
+
 #ifndef DRM_CAP_CURSOR_WIDTH
 #define DRM_CAP_CURSOR_WIDTH 0x8
 #endif
@@ -78,6 +86,41 @@
 #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
 #endif
 
+/**
+ * Holding structure for one DRM property.
+ */
+struct property_item {
+   drmModePropertyRes *drm_prop;
+   uint64_t value;
+};
+
+/**
+ * List of properties attached to DRM planes
+ */
+enum wdrm_plane_property {
+   WDRM_PLANE_TYPE = 0,
+   WDRM_PLANE__COUNT
+};
+
+/**
+ * Possible values for the WDRM_PLANE_TYPE property.
+ */
+enum wdrm_plane_type {
+   WDRM_PLANE_TYPE_PRIMARY = 0,
+   WDRM_PLANE_TYPE_CURSOR,
+   WDRM_PLANE_TYPE_OVERLAY,
+   WDRM_PLANE_TYPE__COUNT
+};
+
+/**
+ * Holding structure for plane properties.
+ */
+struct plane_properties {
+   struct property_item item[WDRM_PLANE__COUNT];
+   uint64_t typemap[WDRM_PLANE_TYPE__COUNT]; /**< map for type enum */
+   uint64_t value;
+};
+
 struct drm_backend {
struct weston_backend base;
struct weston_compositor *compositor;
@@ -115,6 +158,8 @@ struct drm_backend {
 
int cursors_are_broken;
 
+   bool universal_planes;
+
int use_pixman;
 
struct udev_input input;
@@ -188,6 +233,9 @@ struct drm_plane {
struct drm_output *output;
struct drm_backend *backend;
 
+   enum wdrm_plane_type type;
+   struct plane_properties props;
+
uint32_t possible_crtcs;
uint32_t plane_id;
uint32_t count_formats;
@@ -255,6 +303,342 @@ to_drm_backend(struct weston_compositor *base)
return container_of(base->backend, struct drm_backend, base);
 }
 
+/**
+ * Return a string describing the type of a DRM object
+ */
+static const char *
+drm_object_type_str(uint32_t obj_type)
+{
+   switch (obj_type) {
+   case DRM_MODE_OBJECT_CRTC:  return "crtc";
+   case DRM_MODE_OBJECT_CONNECTOR: return "connector";
+   case DRM_MODE_OBJECT_ENCODER:   return "encoder";
+   case DRM_MODE_OBJECT_MODE:  return "mode";
+   case DRM_MODE_OBJECT_PROPERTY:  return "property";
+   case DRM_MODE_OBJECT_FB:return "fb";
+   case DRM_MODE_OBJECT_BLOB:  return "blob";
+   case DRM_MODE_OBJECT_PLANE: return "plane";
+   default: return "???";
+   }
+}
+
+/**
+ * Cache a mapping from static values to a DRM property enum
+ *
+ * DRM property enum values are dynamic at runtime; the user must query the
+ * property to find out the desired runtime value for a requested string
+ * name. Using  the 'type' field on planes as an example, there is no single
+ * hardcoded constant for primary plane types; instead, the property must be
+ * queried at runtime to find the value associated with the string "Primary".
+ *
+ * This helper queries and caches the enum values, to allow us to use a set
+ * of compile-time-constant enums portably across various implementations.
+ * The values given in enum_names are searched for, and stored in the
+ * same-indexed field of the map array.
+ *
+ * For example, if the DRM driver exposes 'Foo' as value 7 and 'Bar' as value
+ * 19, passing in enum_names containing 'Foo' and 'Bar' in that order, will
+ * populate map with 7 and 19, in that order.
+ *
+ * This should always be used with static C enums to represent each value, e.g.
+ * WDRM_PLANE_MISC_FOO, WDRM_PLANE_MISC_BAR.
+ *
+ * Property lookup is not mandatory and may fail; users should carefully
+ * check the return value, which is a bitmask populated with the indices
+ * of properties which were successfully looked up. Values not successfully
+ * looked up may return 0, which may represent a false positive.
+ *
+ * @param prop DRM enum property to cache map for
+ * @param map Array for enum values; each entry is written for the 
corresponding
+ *

[PATCH weston 27/68] compositor-drm: Clean up page_flip_pending path

2016-12-09 Thread Daniel Stone
page_flip_pending is set when we do a no-effect pageflip, and thus don't
need to release the buffer as we don't have a new one pending.

Now we have last/cur/pending properly broken out, we can just use these
consistently, and test if last != current (the effect), rather than the
specific path which triggered it.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1417
---
 libweston/compositor-drm.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 382c8e2..bd6170a 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -786,6 +786,7 @@ drm_output_repaint(struct weston_output *output_base,
output->fb_current = output->fb_pending;
output->fb_pending = NULL;
 
+   assert(!output->page_flip_pending);
output->page_flip_pending = 1;
 
drm_output_set_cursor(output);
@@ -907,12 +908,18 @@ drm_output_start_repaint_loop(struct weston_output 
*output_base)
 */
fb_id = output->fb_current->fb_id;
 
+   assert(!output->page_flip_pending);
+   assert(!output->fb_last);
+
if (drmModePageFlip(backend->drm.fd, output->crtc_id, fb_id,
DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
weston_log("queueing pageflip failed: %m\n");
goto finish_frame;
}
 
+   output->fb_last = drm_fb_ref(output->fb_current);
+   output->page_flip_pending = 1;
+
return;
 
 finish_frame:
@@ -973,16 +980,12 @@ page_flip_handler(int fd, unsigned int frame,
 
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 */
-   if (output->page_flip_pending) {
-   drm_fb_unref(output->fb_last);
-   output->fb_last = NULL;
-   }
-
+   assert(output->page_flip_pending);
output->page_flip_pending = 0;
 
+   drm_fb_unref(output->fb_last);
+   output->fb_last = NULL;
+
if (output->destroy_pending)
drm_output_destroy(>base);
else if (output->disable_pending)
-- 
2.9.3

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


[PATCH weston 26/68] compositor-drm: Turn vblank_pending from bool to refcount

2016-12-09 Thread Daniel Stone
vblank_pending is currently a bool, which is reset on every vblank
requests (i.e. sprite pageflip). This can occur more than once per
frame, so turn it into a callback, so we only fire frame-done when we've
collected all the events.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1418
---
 libweston/compositor-drm.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 0d3ca35..382c8e2 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -836,7 +836,7 @@ drm_output_repaint(struct weston_output *output_base,
s->fb_last = s->fb_current;
s->fb_current = s->fb_pending;
s->fb_pending = NULL;
-   output->vblank_pending = 1;
+   output->vblank_pending++;
}
 
return 0;
@@ -944,13 +944,14 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
 WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
 
drm_output_update_msc(output, frame);
-   output->vblank_pending = 0;
+   output->vblank_pending--;
+   assert(output->vblank_pending >= 0);
 
assert(s->fb_last || s->fb_current);
drm_fb_unref(s->fb_last);
s->fb_last = NULL;
 
-   if (!output->page_flip_pending) {
+   if (!output->page_flip_pending && !output->vblank_pending) {
ts.tv_sec = sec;
ts.tv_nsec = usec * 1000;
weston_output_finish_frame(>base, , flags);
-- 
2.9.3

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


[PATCH weston 50/68] compositor-drm: Use plane_coords_for_view for cursor

2016-12-09 Thread Daniel Stone
Use the new helper to populate the cursor state as well, with some
special-case handling to account for how we always upload a full-size
BO.

Signed-off-by: Daniel Stone 
Reported-by: Derek Foreman 

Differential Revision: https://phabricator.freedesktop.org/D1519
---
 libweston/compositor-drm.c | 48 +++---
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 202772b..1dc63c8 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2435,10 +2435,8 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
struct drm_backend *b = to_drm_backend(output->base.compositor);
struct drm_plane *plane = output->cursor_plane;
struct drm_plane_state *plane_state;
-   struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct wl_shm_buffer *shmbuf;
bool needs_update = false;
-   float x, y;
 
if (!plane)
return NULL;
@@ -2468,16 +2466,6 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
if (wl_shm_buffer_get_format(shmbuf) != WL_SHM_FORMAT_ARGB)
return NULL;
 
-   if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
-   return NULL;
-   if (ev->transform.enabled &&
-   (ev->transform.matrix.type > WESTON_MATRIX_TRANSFORM_TRANSLATE))
-   return NULL;
-   if (viewport->buffer.scale != output->base.current_scale)
-   return NULL;
-   if (ev->geometry.scissor_enabled)
-   return NULL;
-
if (ev->surface->width > b->cursor_width ||
ev->surface->height > b->cursor_height)
return NULL;
@@ -2488,6 +2476,26 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
if (plane_state && plane_state->fb)
return NULL;
 
+   /* We can't scale with the legacy API, and we don't try to account for
+* simple cropping/translation in cursor_bo_update. */
+   plane_state->output = output;
+   drm_plane_state_coords_for_view(plane_state, ev);
+   if (plane_state->src_x != 0 || plane_state->src_y != 0 ||
+   plane_state->src_w > (unsigned) b->cursor_width << 16 ||
+   plane_state->src_h > (unsigned) b->cursor_height << 16 ||
+   plane_state->src_w != plane_state->dest_w << 16 ||
+   plane_state->src_h != plane_state->dest_h << 16)
+   goto err;
+
+   /* The cursor API is somewhat special: in cursor_bo_update(), we upload
+* a buffer which is always cursor_width x cursor_height, even if the
+* surface we want to promote is actually smaller than this. Manually
+* mangle the plane state to deal with this. */
+   plane_state->src_w = b->cursor_width << 16;
+   plane_state->src_h = b->cursor_height << 16;
+   plane_state->dest_w = b->cursor_width;
+   plane_state->dest_h = b->cursor_height;
+
/* Since we're setting plane state up front, we need to work out
 * whether or not we need to upload a new cursor. We can't use the
 * plane damage, since the planes haven't actually been calculated
@@ -2504,26 +2512,18 @@ drm_output_prepare_cursor_view(struct drm_output_state 
*output_state,
}
 
output->cursor_view = ev;
-   weston_view_to_global_float(ev, 0, 0, , );
-   plane->base.x = x;
-   plane->base.y = y;
 
plane_state->fb =
drm_fb_ref(output->gbm_cursor_fb[output->current_cursor]);
-   plane_state->output = output;
-   plane_state->src_x = 0;
-   plane_state->src_y = 0;
-   plane_state->src_w = b->cursor_width << 16;
-   plane_state->src_h = b->cursor_height << 16;
-   plane_state->dest_x = (x - output->base.x) * output->base.current_scale;
-   plane_state->dest_y = (y - output->base.y) * output->base.current_scale;
-   plane_state->dest_w = b->cursor_width;
-   plane_state->dest_h = b->cursor_height;
 
if (needs_update)
cursor_bo_update(b, plane_state->fb->bo, ev);
 
return >base;
+
+err:
+   drm_plane_state_put_back(plane_state);
+   return NULL;
 }
 
 static void
-- 
2.9.3

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


[PATCH weston 14/68] compositor-drm: Store width and height inside drm_fb

2016-12-09 Thread Daniel Stone
This will be used so we can later determine the compatibility of drm_fbs
without needing to introspect external state.

Differential Revision: https://phabricator.freedesktop.org/D1487

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a5052b9..4ef7343 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -131,6 +131,7 @@ struct drm_mode {
 
 struct drm_fb {
uint32_t fb_id, stride, handle, size;
+   int width, height;
int fd;
int is_client_buffer;
struct weston_buffer_reference buffer_ref;
@@ -292,6 +293,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
fb->handle = create_arg.handle;
fb->stride = create_arg.pitch;
fb->size = create_arg.size;
+   fb->width = width;
+   fb->height = height;
fb->fd = b->drm.fd;
 
ret = -1;
@@ -371,7 +374,6 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
   struct drm_backend *backend, uint32_t format)
 {
struct drm_fb *fb = gbm_bo_get_user_data(bo);
-   int width, height;
uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
int ret;
 
@@ -384,17 +386,17 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
 
fb->bo = bo;
 
-   width = gbm_bo_get_width(bo);
-   height = gbm_bo_get_height(bo);
+   fb->width = gbm_bo_get_width(bo);
+   fb->height = gbm_bo_get_height(bo);
fb->stride = gbm_bo_get_stride(bo);
fb->handle = gbm_bo_get_handle(bo).u32;
-   fb->size = fb->stride * height;
+   fb->size = fb->stride * fb->height;
fb->fd = backend->drm.fd;
 
-   if (backend->min_width > width ||
-   width > backend->max_width ||
-   backend->min_height > height ||
-   height > backend->max_height) {
+   if (backend->min_width > fb->width ||
+   fb->width > backend->max_width ||
+   backend->min_height > fb->height ||
+   fb->height > backend->max_height) {
weston_log("bo geometry out of bounds\n");
goto err_free;
}
@@ -406,7 +408,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
pitches[0] = fb->stride;
offsets[0] = 0;
 
-   ret = drmModeAddFB2(backend->drm.fd, width, height,
+   ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
format, handles, pitches, offsets,
>fb_id, 0);
if (ret) {
@@ -417,8 +419,8 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
}
 
if (ret)
-   ret = drmModeAddFB(backend->drm.fd, width, height, 24, 32,
-  fb->stride, fb->handle, >fb_id);
+   ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
+  24, 32, fb->stride, fb->handle, >fb_id);
 
if (ret) {
weston_log("failed to create kms fb: %m\n");
-- 
2.9.3

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


[PATCH weston 18/68] compositor-drm: Drop output from release_fb

2016-12-09 Thread Daniel Stone
We only need it for the GBM surface the FB was originally created
against; a mismatch here is very bad indeed, so no reason to pass it in
explictly every time rather than store it.

Differential Revision: https://phabricator.freedesktop.org/D1490

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 7dbfc6b..eb735b2 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -148,6 +148,7 @@ struct drm_fb {
 
/* Used by gbm fbs */
struct gbm_bo *bo;
+   struct gbm_surface *gbm_surface;
 
/* Used by dumb fbs */
void *map;
@@ -466,7 +467,7 @@ drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer 
*buffer)
 }
 
 static void
-drm_output_release_fb(struct drm_output *output, struct drm_fb *fb)
+drm_fb_unref(struct drm_fb *fb)
 {
if (!fb)
return;
@@ -479,7 +480,7 @@ drm_output_release_fb(struct drm_output *output, struct 
drm_fb *fb)
gbm_bo_destroy(fb->bo);
break;
case BUFFER_GBM_SURFACE:
-   gbm_surface_release_buffer(output->gbm_surface, fb->bo);
+   gbm_surface_release_buffer(fb->gbm_surface, fb->bo);
break;
default:
assert(NULL);
@@ -615,6 +616,7 @@ drm_output_render_gl(struct drm_output *output, 
pixman_region32_t *damage)
gbm_surface_release_buffer(output->gbm_surface, bo);
return;
}
+   output->next->gbm_surface = output->gbm_surface;
 }
 
 static void
@@ -798,7 +800,7 @@ drm_output_repaint(struct weston_output *output_base,
 err_pageflip:
output->cursor_view = NULL;
if (output->next) {
-   drm_output_release_fb(output, output->next);
+   drm_fb_unref(output->next);
output->next = NULL;
}
 
@@ -900,7 +902,7 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
drm_output_update_msc(output, frame);
output->vblank_pending = 0;
 
-   drm_output_release_fb(output, s->current);
+   drm_fb_unref(s->current);
s->current = s->next;
s->next = NULL;
 
@@ -930,7 +932,7 @@ page_flip_handler(int fd, unsigned int frame,
 * we just want to page flip to the current buffer to get an accurate
 * timestamp */
if (output->page_flip_pending) {
-   drm_output_release_fb(output, output->current);
+   drm_fb_unref(output->current);
output->current = output->next;
output->next = NULL;
}
@@ -1452,8 +1454,8 @@ drm_output_switch_mode(struct weston_output *output_base, 
struct weston_mode *mo
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
 
/* reset rendering stuff. */
-   drm_output_release_fb(output, output->current);
-   drm_output_release_fb(output, output->next);
+   drm_fb_unref(output->current);
+   drm_fb_unref(output->next);
output->current = output->next = NULL;
 
if (b->use_pixman) {
@@ -2672,8 +2674,8 @@ destroy_sprites(struct drm_backend *backend)
sprite->plane_id,
output->crtc_id, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0);
-   drm_output_release_fb(output, sprite->current);
-   drm_output_release_fb(output, sprite->next);
+   drm_fb_unref(sprite->current);
+   drm_fb_unref(sprite->next);
weston_plane_release(>plane);
free(sprite);
}
-- 
2.9.3

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


[PATCH weston 01/68] libweston: Add pixel-format helpers

2016-12-09 Thread Daniel Stone
Rather than duplicating knowledge of pixel formats across several
components, create a custom central repository.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1511
---
 libweston/pixel-formats.c | 398 ++
 libweston/pixel-formats.h | 112 +
 2 files changed, 510 insertions(+)
 create mode 100644 libweston/pixel-formats.c
 create mode 100644 libweston/pixel-formats.h

diff --git a/libweston/pixel-formats.c b/libweston/pixel-formats.c
new file mode 100644
index 000..9c70e73
--- /dev/null
+++ b/libweston/pixel-formats.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright © 2016 Collabora, Ltd.
+ *
+ * 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.
+ *
+ * Author: Daniel Stone 
+ */
+
+#include "config.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "helpers.h"
+#include "wayland-util.h"
+#include "pixel-formats.h"
+
+#include 
+#include 
+#include 
+#include 
+
+#include "weston-egl-ext.h"
+
+/**
+ * Table of DRM formats supported by Weston; RGB, ARGB and YUV formats are
+ * supported. Indexed/greyscale formats, and formats not containing complete
+ * colour channels, are not supported.
+ */
+static const struct pixel_format_info pixel_format_table[] = {
+   {
+   .format = DRM_FORMAT_XRGB,
+   },
+   {
+   .format = DRM_FORMAT_ARGB,
+   .opaque_substitute = DRM_FORMAT_XRGB,
+   },
+   {
+   .format = DRM_FORMAT_XBGR,
+   },
+   {
+   .format = DRM_FORMAT_ABGR,
+   .opaque_substitute = DRM_FORMAT_XBGR,
+   },
+   {
+   .format = DRM_FORMAT_RGBX,
+   .gl_format = GL_RGBA,
+   .gl_type = GL_UNSIGNED_SHORT_4_4_4_4,
+   },
+   {
+   .format = DRM_FORMAT_RGBA,
+   .opaque_substitute = DRM_FORMAT_RGBX,
+   .gl_format = GL_RGBA,
+   .gl_type = GL_UNSIGNED_SHORT_4_4_4_4,
+   },
+   {
+   .format = DRM_FORMAT_BGRX,
+   .gl_format = GL_BGRA_EXT,
+   .gl_type = GL_UNSIGNED_SHORT_4_4_4_4,
+   },
+   {
+   .format = DRM_FORMAT_BGRA,
+   .opaque_substitute = DRM_FORMAT_BGRX,
+   .gl_format = GL_BGRA_EXT,
+   .gl_type = GL_UNSIGNED_SHORT_4_4_4_4,
+   },
+   {
+   .format = DRM_FORMAT_XRGB1555,
+   .depth = 15,
+   .bpp = 16,
+   },
+   {
+   .format = DRM_FORMAT_ARGB1555,
+   .opaque_substitute = DRM_FORMAT_XRGB1555,
+   },
+   {
+   .format = DRM_FORMAT_XBGR1555,
+   },
+   {
+   .format = DRM_FORMAT_ABGR1555,
+   .opaque_substitute = DRM_FORMAT_XBGR1555,
+   },
+   {
+   .format = DRM_FORMAT_RGBX5551,
+   .gl_format = GL_RGBA,
+   .gl_type = GL_UNSIGNED_SHORT_5_5_5_1,
+   },
+   {
+   .format = DRM_FORMAT_RGBA5551,
+   .opaque_substitute = DRM_FORMAT_RGBX5551,
+   .gl_format = GL_RGBA,
+   .gl_type = GL_UNSIGNED_SHORT_5_5_5_1,
+   },
+   {
+   .format = DRM_FORMAT_BGRX5551,
+   .gl_format = GL_BGRA_EXT,
+   .gl_type = GL_UNSIGNED_SHORT_5_5_5_1,
+   },
+   {
+   .format = DRM_FORMAT_BGRA5551,
+   .opaque_substitute = DRM_FORMAT_BGRX5551,
+   .gl_format = GL_BGRA_EXT,
+   .gl_type = GL_UNSIGNED_SHORT_5_5_5_1,
+   },
+   {
+   .format = DRM_FORMAT_RGB565,
+   .depth = 16,
+   .bpp = 16,
+   .gl_type = GL_RGB,
+   .gl_type = GL_UNSIGNED_SHORT_5_6_5,
+   },
+   {
+   .format = 

[PATCH weston 16/68] compositor-drm: Store format in drm_fb

2016-12-09 Thread Daniel Stone
This uses the new pixel-format helpers, so we can also replace depth/bpp
with these.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1513
---
 libweston/compositor-drm.c | 43 +++
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 217db32..af43a15 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -54,6 +54,7 @@
 #include "gl-renderer.h"
 #include "weston-egl-ext.h"
 #include "pixman-renderer.h"
+#include "pixel-formats.h"
 #include "libbacklight.h"
 #include "libinput-seat.h"
 #include "launcher-util.h"
@@ -140,6 +141,7 @@ struct drm_fb {
enum drm_fb_type type;
 
uint32_t fb_id, stride, handle, size;
+   const struct pixel_format_info *format;
int width, height;
int fd;
struct weston_buffer_reference buffer_ref;
@@ -267,7 +269,6 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
 {
struct drm_fb *fb;
int ret;
-   uint32_t bpp, depth;
 
struct drm_mode_create_dumb create_arg;
struct drm_mode_destroy_dumb destroy_arg;
@@ -277,20 +278,20 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
if (!fb)
return NULL;
 
-   switch (format) {
-   case GBM_FORMAT_XRGB:
-   bpp = 32;
-   depth = 24;
-   break;
-   case GBM_FORMAT_RGB565:
-   bpp = depth = 16;
-   break;
-   default:
-   return NULL;
+   fb->format = pixel_format_get_info(format);
+   if (!fb->format) {
+   weston_log("failed to look up format 0x%lx\n",
+  (unsigned long) format);
+   goto err_fb;
+   }
+
+   if (!fb->format->depth || !fb->format->bpp) {
+   weston_log("format 0x%lx is not compatible with dumb buffers\n",
+  (unsigned long) format);
}
 
memset(_arg, 0, sizeof create_arg);
-   create_arg.bpp = bpp;
+   create_arg.bpp = fb->format->bpp;
create_arg.width = width;
create_arg.height = height;
 
@@ -316,7 +317,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
offsets[0] = 0;
 
ret = drmModeAddFB2(b->drm.fd, width, height,
-   format, handles, pitches, offsets,
+   fb->format->format,
+   handles, pitches, offsets,
>fb_id, 0);
if (ret) {
weston_log("addfb2 failed: %m\n");
@@ -325,7 +327,8 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
height,
}
 
if (ret) {
-   ret = drmModeAddFB(b->drm.fd, width, height, depth, bpp,
+   ret = drmModeAddFB(b->drm.fd, width, height,
+  fb->format->depth, fb->format->bpp,
   fb->stride, fb->handle, >fb_id);
}
 
@@ -402,9 +405,16 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
*backend,
fb->height = gbm_bo_get_height(bo);
fb->stride = gbm_bo_get_stride(bo);
fb->handle = gbm_bo_get_handle(bo).u32;
+   fb->format = pixel_format_get_info(format);
fb->size = fb->stride * fb->height;
fb->fd = backend->drm.fd;
 
+   if (!fb->format) {
+   weston_log("couldn't look up format 0x%lx\n",
+  (unsigned long) format);
+   goto err_free;
+   }
+
if (backend->min_width > fb->width ||
fb->width > backend->max_width ||
backend->min_height > fb->height ||
@@ -430,9 +440,10 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
*backend,
}
}
 
-   if (ret)
+   if (ret && fb->format->depth && fb->format->bpp)
ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
-  24, 32, fb->stride, fb->handle, >fb_id);
+  fb->format->depth, fb->format->bpp,
+  fb->stride, fb->handle, >fb_id);
 
if (ret) {
weston_log("failed to create kms fb: %m\n");
-- 
2.9.3

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


[PATCH weston 10/68] compositor-drm: Make scanout view preparation more stringent

2016-12-09 Thread Daniel Stone
Don't import buffers which span multiple outputs, short-cut any attempt
to import SHM buffers, and ignore buffers with a global alpha set.

I'm not convinced all of these conditions entirely make sense, but this
at least makes them equally nonsensical.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1414
---
 libweston/compositor-drm.c | 35 ---
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 8cd9d5a..e22d792 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -462,6 +462,13 @@ drm_output_release_fb(struct drm_output *output, struct 
drm_fb *fb)
}
 }
 
+static int
+drm_view_transform_supported(struct weston_view *ev)
+{
+   return !ev->transform.enabled ||
+   (ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
+}
+
 static uint32_t
 drm_output_check_scanout_format(struct drm_output *output,
struct weston_surface *es, struct gbm_bo *bo)
@@ -502,27 +509,40 @@ drm_output_prepare_scanout_view(struct drm_output *output,
struct gbm_bo *bo;
uint32_t format;
 
+   /* Don't import buffers which span multiple outputs. */
+   if (ev->output_mask != (1u << output->base.id))
+   return NULL;
+
/* We use GBM to import buffers. */
if (b->gbm == NULL)
return NULL;
 
if (buffer == NULL)
return NULL;
+   if (wl_shm_buffer_get(buffer->resource))
+   return NULL;
 
/* Make sure our view is exactly compatible with the output. */
if (ev->geometry.x != output->base.x ||
ev->geometry.y != output->base.y)
return NULL;
+   if (buffer->width != output->base.current_mode->width ||
+   buffer->height != output->base.current_mode->height)
+   return NULL;
+
if (ev->transform.enabled)
return NULL;
if (ev->geometry.scissor_enabled)
return NULL;
-
-   if (buffer->width != output->base.current_mode->width ||
-   buffer->height != output->base.current_mode->height)
-   return NULL;
if (viewport->buffer.transform != output->base.transform)
return NULL;
+   if (viewport->buffer.scale != output->base.current_scale)
+   return NULL;
+   if (!drm_view_transform_supported(ev))
+   return NULL;
+
+   if (ev->alpha != 1.0f)
+   return NULL;
 
bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
   buffer->resource, GBM_BO_USE_SCANOUT);
@@ -936,13 +956,6 @@ drm_output_check_sprite_format(struct drm_sprite *s,
return 0;
 }
 
-static int
-drm_view_transform_supported(struct weston_view *ev)
-{
-   return !ev->transform.enabled ||
-   (ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
-}
-
 static struct weston_plane *
 drm_output_prepare_overlay_view(struct drm_output *output,
struct weston_view *ev)
-- 
2.9.3

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


[PATCH weston 25/68] compositor-drm: Introduce fb_last member

2016-12-09 Thread Daniel Stone
Clean up some ambiguity around current/next: current could previously
have referred to a buffer which was being displayed, or the last buffer
being displayed whilst we waited for a configuration we'd requested to
take effect.

Introduce a new variable, fb_last, which exclusively holds the latter
case, thus leaving us with three unambiguous members: fb_pending is used
as a scratch space for a buffer we're about to post, fb_current holds
the buffer we last requested to display (whether active yet or not), and
fb_last is again scratch space for a buffer which is no longer being
displayed after a previous configuration reqeust.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1411
---
 libweston/compositor-drm.c | 42 ++
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 5909239..0d3ca35 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -190,7 +190,7 @@ struct drm_output {
int current_cursor;
 
struct weston_plane fb_plane;
-   struct drm_fb *fb_current, *fb_pending;
+   struct drm_fb *fb_current, *fb_pending, *fb_last;
struct backlight *backlight;
 
struct drm_fb *dumb[2];
@@ -211,7 +211,7 @@ struct drm_sprite {
 
struct weston_plane plane;
 
-   struct drm_fb *fb_current, *fb_pending;
+   struct drm_fb *fb_current, *fb_pending, *fb_last;
struct drm_output *output;
struct drm_backend *backend;
 
@@ -755,6 +755,8 @@ drm_output_repaint(struct weston_output *output_base,
if (output->disable_pending || output->destroy_pending)
return -1;
 
+   assert(!output->fb_last);
+
drm_output_render(output, damage);
if (!output->fb_pending)
return -1;
@@ -780,6 +782,10 @@ drm_output_repaint(struct weston_output *output_base,
goto err_pageflip;
}
 
+   output->fb_last = output->fb_current;
+   output->fb_current = output->fb_pending;
+   output->fb_pending = NULL;
+
output->page_flip_pending = 1;
 
drm_output_set_cursor(output);
@@ -794,6 +800,8 @@ drm_output_repaint(struct weston_output *output_base,
.request.sequence = 1,
};
 
+   /* XXX: Set output much earlier, so we don't attempt to place
+*  planes on entirely the wrong output. */
if ((!s->fb_current && !s->fb_pending) ||
!drm_sprite_crtc_supported(output, s))
continue;
@@ -825,6 +833,9 @@ drm_output_repaint(struct weston_output *output_base,
}
 
s->output = output;
+   s->fb_last = s->fb_current;
+   s->fb_current = s->fb_pending;
+   s->fb_pending = NULL;
output->vblank_pending = 1;
}
 
@@ -935,9 +946,9 @@ vblank_handler(int fd, unsigned int frame, unsigned int 
sec, unsigned int usec,
drm_output_update_msc(output, frame);
output->vblank_pending = 0;
 
-   drm_fb_unref(s->fb_current);
-   s->fb_current = s->fb_pending;
-   s->fb_pending = NULL;
+   assert(s->fb_last || s->fb_current);
+   drm_fb_unref(s->fb_last);
+   s->fb_last = NULL;
 
if (!output->page_flip_pending) {
ts.tv_sec = sec;
@@ -965,9 +976,8 @@ page_flip_handler(int fd, unsigned int frame,
 * we just want to page flip to the current buffer to get an accurate
 * timestamp */
if (output->page_flip_pending) {
-   drm_fb_unref(output->fb_current);
-   output->fb_current = output->fb_pending;
-   output->fb_pending = NULL;
+   drm_fb_unref(output->fb_last);
+   output->fb_last = NULL;
}
 
output->page_flip_pending = 0;
@@ -1486,10 +1496,16 @@ drm_output_switch_mode(struct weston_output 
*output_base, struct weston_mode *mo
output->base.current_mode->flags =
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
 
-   /* reset rendering stuff. */
+   /* XXX: This drops our current buffer too early, before we've started
+*  displaying it. Ideally this should be much more atomic and
+*  integrated with a full repaint cycle, rather than doing a
+*  sledgehammer modeswitch first, and only later showing new
+*  content.
+*/
drm_fb_unref(output->fb_current);
-   drm_fb_unref(output->fb_pending);
-   output->fb_current = output->fb_pending = NULL;
+   assert(!output->fb_last);
+   assert(!output->fb_pending);
+   output->fb_last = output->fb_current = NULL;
 
if (b->use_pixman) {
drm_output_fini_pixman(output);
@@ -2705,6 +2721,7 @@ create_sprites(struct drm_backend *b)
 
sprite->possible_crtcs = 

[PATCH weston 11/68] compositor-drm: Calculate more cursor state up front

2016-12-09 Thread Daniel Stone
Make drm_output_set_cursor more deterministic, by calculating more state
and performing more plane manipulation, inside
drm_output_prepare_cursor_view.

Differential Revision: https://phabricator.freedesktop.org/D1485

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 39 ---
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index e22d792..3276ed0 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1135,6 +1135,7 @@ drm_output_prepare_cursor_view(struct drm_output *output,
struct drm_backend *b = to_drm_backend(output->base.compositor);
struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct wl_shm_buffer *shmbuf;
+   float x, y;
 
if (b->cursors_are_broken)
return NULL;
@@ -1173,6 +1174,9 @@ drm_output_prepare_cursor_view(struct drm_output *output,
return NULL;
 
output->cursor_view = ev;
+   weston_view_to_global_float(ev, 0, 0, , );
+   output->cursor_plane.x = x;
+   output->cursor_plane.y = y;
 
return >cursor_plane;
 }
@@ -1218,24 +1222,17 @@ static void
 drm_output_set_cursor(struct drm_output *output)
 {
struct weston_view *ev = output->cursor_view;
-   struct weston_buffer *buffer;
struct drm_backend *b = to_drm_backend(output->base.compositor);
EGLint handle;
struct gbm_bo *bo;
float x, y;
 
-   output->cursor_view = NULL;
if (ev == NULL) {
drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
-   output->cursor_plane.x = INT32_MIN;
-   output->cursor_plane.y = INT32_MIN;
return;
}
 
-   buffer = ev->surface->buffer_ref.buffer;
-
-   if (buffer &&
-   pixman_region32_not_empty(>cursor_plane.damage)) {
+   if (pixman_region32_not_empty(>cursor_plane.damage)) {
pixman_region32_fini(>cursor_plane.damage);
pixman_region32_init(>cursor_plane.damage);
output->current_cursor ^= 1;
@@ -1250,22 +1247,14 @@ drm_output_set_cursor(struct drm_output *output)
}
}
 
-   weston_view_to_global_float(ev, 0, 0, , );
-
-   /* From global to output space, output transform is guaranteed to be
-* NORMAL by drm_output_prepare_cursor_view().
-*/
-   x = (x - output->base.x) * output->base.current_scale;
-   y = (y - output->base.y) * output->base.current_scale;
+   x = (output->cursor_plane.x - output->base.x) *
+   output->base.current_scale;
+   y = (output->cursor_plane.y - output->base.y) *
+   output->base.current_scale;
 
-   if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
-   if (drmModeMoveCursor(b->drm.fd, output->crtc_id, x, y)) {
-   weston_log("failed to move cursor: %m\n");
-   b->cursors_are_broken = 1;
-   }
-
-   output->cursor_plane.x = x;
-   output->cursor_plane.y = y;
+   if (drmModeMoveCursor(b->drm.fd, output->crtc_id, x, y)) {
+   weston_log("failed to move cursor: %m\n");
+   b->cursors_are_broken = 1;
}
 }
 
@@ -1294,6 +1283,10 @@ drm_assign_planes(struct weston_output *output_base)
pixman_region32_init();
primary = _base->compositor->primary_plane;
 
+   output->cursor_view = NULL;
+   output->cursor_plane.x = INT32_MIN;
+   output->cursor_plane.y = INT32_MIN;
+
wl_list_for_each_safe(ev, next, _base->compositor->view_list, 
link) {
struct weston_surface *es = ev->surface;
 
-- 
2.9.3

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


[PATCH weston 21/68] compositor-drm: Use drm_fb for cursor buffers

2016-12-09 Thread Daniel Stone
Now that we have better types in drm_fb, use it for cursor buffers as
well.

Differential Revision: https://phabricator.freedesktop.org/D1493

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 73 +-
 1 file changed, 53 insertions(+), 20 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 950c265..557b97d 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -135,6 +135,7 @@ enum drm_fb_type {
BUFFER_CLIENT, /**< directly sourced from client */
BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
BUFFER_GBM_SURFACE, /**< internal EGL rendering */
+   BUFFER_CURSOR, /**< internal cursor buffer */
 };
 
 struct drm_fb {
@@ -183,11 +184,12 @@ struct drm_output {
int disable_pending;
 
struct gbm_surface *gbm_surface;
-   struct gbm_bo *gbm_cursor_bo[2];
+   struct drm_fb *gbm_cursor_fb[2];
struct weston_plane cursor_plane;
-   struct weston_plane fb_plane;
struct weston_view *cursor_view;
int current_cursor;
+
+   struct weston_plane fb_plane;
struct drm_fb *current, *next;
struct backlight *backlight;
 
@@ -285,7 +287,8 @@ drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
 {
struct drm_fb *fb = data;
 
-   assert(fb->type == BUFFER_GBM_SURFACE || fb->type == BUFFER_CLIENT);
+   assert(fb->type == BUFFER_GBM_SURFACE || fb->type == BUFFER_CLIENT ||
+  fb->type == BUFFER_CURSOR);
drm_fb_destroy(fb);
 }
 
@@ -493,6 +496,7 @@ drm_fb_unref(struct drm_fb *fb)
case BUFFER_PIXMAN_DUMB:
drm_fb_destroy_dumb(fb);
break;
+   case BUFFER_CURSOR:
case BUFFER_CLIENT:
gbm_bo_destroy(fb->bo);
break;
@@ -1281,7 +1285,7 @@ drm_output_set_cursor(struct drm_output *output)
pixman_region32_fini(>cursor_plane.damage);
pixman_region32_init(>cursor_plane.damage);
output->current_cursor ^= 1;
-   bo = output->gbm_cursor_bo[output->current_cursor];
+   bo = output->gbm_cursor_fb[output->current_cursor]->bo;
 
cursor_bo_update(b, bo, ev);
handle = gbm_bo_get_handle(bo).s32;
@@ -1867,6 +1871,48 @@ find_crtc_for_connector(struct drm_backend *b,
return -1;
 }
 
+static void drm_output_fini_cursor_egl(struct drm_output *output)
+{
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
+   drm_fb_unref(output->gbm_cursor_fb[i]);
+   output->gbm_cursor_fb[i] = NULL;
+   }
+}
+
+static int
+drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
+{
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
+   struct gbm_bo *bo;
+
+   bo = gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
+  GBM_FORMAT_ARGB,
+  GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+   if (!bo)
+   goto err;
+
+   output->gbm_cursor_fb[i] =
+   drm_fb_get_from_bo(bo, b, GBM_FORMAT_ARGB,
+  BUFFER_CURSOR);
+   if (!output->gbm_cursor_fb[i]) {
+   gbm_bo_destroy(bo);
+   goto err;
+   }
+   }
+
+   return 0;
+
+err:
+   weston_log("cursor buffers unavailable, using gl cursors\n");
+   b->cursors_are_broken = 1;
+   drm_output_fini_cursor_egl(output);
+   return -1;
+}
+
 /* Init output state that depends on gl or gbm */
 static int
 drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
@@ -1875,7 +1921,7 @@ drm_output_init_egl(struct drm_output *output, struct 
drm_backend *b)
output->gbm_format,
fallback_format_for(output->gbm_format),
};
-   int i, flags, n_formats = 1;
+   int n_formats = 1;
 
output->gbm_surface = gbm_surface_create(b->gbm,
 output->base.current_mode->width,
@@ -1901,21 +1947,7 @@ drm_output_init_egl(struct drm_output *output, struct 
drm_backend *b)
return -1;
}
 
-   flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE;
-
-   for (i = 0; i < 2; i++) {
-   if (output->gbm_cursor_bo[i])
-   continue;
-
-   output->gbm_cursor_bo[i] =
-   gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
-   GBM_FORMAT_ARGB, flags);
-   }
-
-   if (output->gbm_cursor_bo[0] == NULL || output->gbm_cursor_bo[1] == 
NULL) {
-   weston_log("cursor buffers unavailable, using gl cursors\n");
-   b->cursors_are_broken = 1;
-   }
+   

[PATCH weston 23/68] compositor-drm: Reshuffle drm_output_render

2016-12-09 Thread Daniel Stone
Call drm_output_render unconditionally, doing an early exit if we're
already rendering a client buffer on the primary plane, and asserting
for damage on the way out.

Differential Revision: https://phabricator.freedesktop.org/D1494

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 8071737..08634cd 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -672,6 +672,11 @@ drm_output_render(struct drm_output *output, 
pixman_region32_t *damage)
struct weston_compositor *c = output->base.compositor;
struct drm_backend *b = to_drm_backend(c);
 
+   /* If we already have a client buffer promoted to scanout, then we don't
+* want to render. */
+   if (output->fb_pending)
+   return;
+
if (b->use_pixman)
drm_output_render_pixman(output, damage);
else
@@ -742,8 +747,7 @@ drm_output_repaint(struct weston_output *output_base,
if (output->disable_pending || output->destroy_pending)
return -1;
 
-   if (!output->fb_pending)
-   drm_output_render(output, damage);
+   drm_output_render(output, damage);
if (!output->fb_pending)
return -1;
 
-- 
2.9.3

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


[PATCH weston 17/68] compositor-drm: Refactor destroy drm_fb function

2016-12-09 Thread Daniel Stone
From: Tomohito Esaki 

The drm_fb destroy callback to mostly the same thing regardless of
whether the buffer is a dumb buffer or gbm buffer. This patch refactors
the common parts into a new function that can be called for both cases.

[daniels: Rebased on top of fb->fd changes, cosmetic changes.]

Differential Revision: https://phabricator.freedesktop.org/D1489

Signed-off-by: Tomohito Esaki 
Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 61 +++---
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index af43a15..7dbfc6b 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -251,16 +251,39 @@ drm_sprite_crtc_supported(struct drm_output *output, 
struct drm_sprite *sprite)
 }
 
 static void
-drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
+drm_fb_destroy(struct drm_fb *fb)
 {
-   struct drm_fb *fb = data;
+   drmModeRmFB(fb->fd, fb->fb_id);
+   weston_buffer_reference(>buffer_ref, NULL);
+   free(fb);
+}
+
+static void
+drm_fb_destroy_dumb(struct drm_fb *fb)
+{
+   struct drm_mode_destroy_dumb destroy_arg;
 
-   if (fb->fb_id)
-   drmModeRmFB(fb->fd, fb->fb_id);
+   if (!fb)
+   return;
 
-   weston_buffer_reference(>buffer_ref, NULL);
+   assert(fb->type == BUFFER_PIXMAN_DUMB);
+
+   munmap(fb->map, fb->size);
+
+   memset(_arg, 0, sizeof(destroy_arg));
+   destroy_arg.handle = fb->handle;
+   drmIoctl(fb->fd, DRM_IOCTL_MODE_DESTROY_DUMB, _arg);
+
+   drm_fb_destroy(fb);
+}
+
+static void
+drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
+{
+   struct drm_fb *fb = data;
 
-   free(data);
+   assert(fb->type == BUFFER_GBM_SURFACE || fb->type == BUFFER_CLIENT);
+   drm_fb_destroy(fb);
 }
 
 static struct drm_fb *
@@ -359,30 +382,6 @@ err_fb:
return NULL;
 }
 
-static void
-drm_fb_destroy_dumb(struct drm_fb *fb)
-{
-   struct drm_mode_destroy_dumb destroy_arg;
-
-   assert(fb->type == BUFFER_PIXMAN_DUMB);
-
-   if (!fb->map)
-   return;
-
-   if (fb->fb_id)
-   drmModeRmFB(fb->fd, fb->fb_id);
-
-   weston_buffer_reference(>buffer_ref, NULL);
-
-   munmap(fb->map, fb->size);
-
-   memset(_arg, 0, sizeof(destroy_arg));
-   destroy_arg.handle = fb->handle;
-   drmIoctl(fb->fd, DRM_IOCTL_MODE_DESTROY_DUMB, _arg);
-
-   free(fb);
-}
-
 static struct drm_fb *
 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
   uint32_t format, enum drm_fb_type type)
@@ -450,7 +449,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend 
*backend,
goto err_free;
}
 
-   gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
+   gbm_bo_set_user_data(bo, fb, drm_fb_destroy_gbm);
 
return fb;
 
-- 
2.9.3

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


[PATCH weston 28/68] compositor-drm: Rename drm_sprite to drm_plane

2016-12-09 Thread Daniel Stone
We make the differentiation where planes are an abstract framebuffer
with a position within a CRTC/output, and sprites are special cases of
planes that are neither the primary (base/framebuffer) nor cursor plane.

drm_sprite, OTOH, contains nothing that's actually specific to sprites,
and we end up duplicating a lot of code to deal with them, especially
when we come to use an entirely plane-based interface with atomic
modesetting.

Rename drm_sprite to drm_plane, to reflect that it's actually generic.

No functional changes.

Signed-off-by: Daniel Stone 
Reviewed-by: Pekka Paalanen 
Reviewed-by: Quentin Glidic 

Differential Revision: https://phabricator.freedesktop.org/D1408
---
 libweston/compositor-drm.c | 187 -
 1 file changed, 98 insertions(+), 89 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index bd6170a..1b123b5 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -164,6 +164,42 @@ struct drm_edid {
char serial_number[13];
 };
 
+/**
+ * A plane represents one buffer, positioned within a CRTC, and stacked
+ * relative to other planes on the same CRTC.
+ *
+ * Each CRTC has a 'primary plane', which use used to display the classic
+ * framebuffer contents, as accessed through the legacy drmModeSetCrtc
+ * call (which combines setting the CRTC's actual physical mode, and the
+ * properties of the primary plane).
+ *
+ * The cursor plane also has its own alternate legacy API.
+ *
+ * Other planes are used opportunistically to display content we do not
+ * wish to blit into the primary plane. These non-primary/cursor planes
+ * are referred to as 'sprites'.
+ */
+struct drm_plane {
+   struct wl_list link;
+
+   struct weston_plane base;
+
+   struct drm_fb *fb_current, *fb_pending, *fb_last;
+   struct drm_output *output;
+   struct drm_backend *backend;
+
+   uint32_t possible_crtcs;
+   uint32_t plane_id;
+   uint32_t count_formats;
+
+   int32_t src_x, src_y;
+   uint32_t src_w, src_h;
+   uint32_t dest_x, dest_y;
+   uint32_t dest_w, dest_h;
+
+   uint32_t formats[];
+};
+
 struct drm_output {
struct weston_output base;
drmModeConnector *connector;
@@ -202,31 +238,6 @@ struct drm_output {
struct wl_listener recorder_frame_listener;
 };
 
-/*
- * An output has a primary display plane plus zero or more sprites for
- * blending display contents.
- */
-struct drm_sprite {
-   struct wl_list link;
-
-   struct weston_plane plane;
-
-   struct drm_fb *fb_current, *fb_pending, *fb_last;
-   struct drm_output *output;
-   struct drm_backend *backend;
-
-   uint32_t possible_crtcs;
-   uint32_t plane_id;
-   uint32_t count_formats;
-
-   int32_t src_x, src_y;
-   uint32_t src_w, src_h;
-   uint32_t dest_x, dest_y;
-   uint32_t dest_w, dest_h;
-
-   uint32_t formats[];
-};
-
 static struct gl_renderer_interface *gl_renderer;
 
 static const char default_seat[] = "seat0";
@@ -250,9 +261,9 @@ static void
 drm_output_update_msc(struct drm_output *output, unsigned int seq);
 
 static int
-drm_sprite_crtc_supported(struct drm_output *output, struct drm_sprite *sprite)
+drm_plane_crtc_supported(struct drm_output *output, struct drm_plane *plane)
 {
-   return !!(sprite->possible_crtcs & (1 << output->pipe));
+   return !!(plane->possible_crtcs & (1 << output->pipe));
 }
 
 static void
@@ -748,7 +759,7 @@ drm_output_repaint(struct weston_output *output_base,
struct drm_output *output = to_drm_output(output_base);
struct drm_backend *backend =
to_drm_backend(output->base.compositor);
-   struct drm_sprite *s;
+   struct drm_plane *s;
struct drm_mode *mode;
int ret = 0;
 
@@ -801,10 +812,8 @@ drm_output_repaint(struct weston_output *output_base,
.request.sequence = 1,
};
 
-   /* XXX: Set output much earlier, so we don't attempt to place
-*  planes on entirely the wrong output. */
if ((!s->fb_current && !s->fb_pending) ||
-   !drm_sprite_crtc_supported(output, s))
+   !drm_plane_crtc_supported(output, s))
continue;
 
if (s->fb_pending && !backend->sprites_hidden)
@@ -944,7 +953,7 @@ static void
 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
   void *data)
 {
-   struct drm_sprite *s = (struct drm_sprite *)data;
+   struct drm_plane *s = (struct drm_plane *)data;
struct drm_output *output = s->output;
struct timespec ts;
uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
@@ -1003,7 +1012,7 @@ page_flip_handler(int fd, unsigned int frame,
 }
 
 static uint32_t

[PATCH weston 12/68] compositor-drm: Use fb->fd consistently

2016-12-09 Thread Daniel Stone
Everyone else uses fb->fd rather than pulling the FD back out of GBM.
Use that in the destroy callback too.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1406
---
 libweston/compositor-drm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 3276ed0..a9bde0c 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -243,10 +243,9 @@ static void
 drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
 {
struct drm_fb *fb = data;
-   struct gbm_device *gbm = gbm_bo_get_device(bo);
 
if (fb->fb_id)
-   drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id);
+   drmModeRmFB(fb->fd, fb->fb_id);
 
weston_buffer_reference(>buffer_ref, NULL);
 
-- 
2.9.3

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


[PATCH weston 13/68] compositor-drm: Use signed int for width/height

2016-12-09 Thread Daniel Stone
This makes it sign-compatible with weston_output->{width,height}.

Differential Revision: https://phabricator.freedesktop.org/D1486

Signed-off-by: Daniel Stone 
Reviewed-by: Quentin Glidic 
---
 libweston/compositor-drm.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a9bde0c..a5052b9 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -104,8 +104,8 @@ struct drm_backend {
 * due to out of bounds dimensions, and then mistakenly set
 * sprites_are_broken:
 */
-   uint32_t min_width, max_width;
-   uint32_t min_height, max_height;
+   int min_width, max_width;
+   int min_height, max_height;
int no_addfb2;
 
struct wl_list sprite_list;
@@ -253,7 +253,7 @@ drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
 }
 
 static struct drm_fb *
-drm_fb_create_dumb(struct drm_backend *b, unsigned width, unsigned height,
+drm_fb_create_dumb(struct drm_backend *b, int width, int height,
   uint32_t format)
 {
struct drm_fb *fb;
@@ -371,7 +371,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
   struct drm_backend *backend, uint32_t format)
 {
struct drm_fb *fb = gbm_bo_get_user_data(bo);
-   uint32_t width, height;
+   int width, height;
uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
int ret;
 
@@ -391,7 +391,8 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
fb->size = fb->stride * height;
fb->fd = backend->drm.fd;
 
-   if (backend->min_width > width || width > backend->max_width ||
+   if (backend->min_width > width ||
+   width > backend->max_width ||
backend->min_height > height ||
height > backend->max_height) {
weston_log("bo geometry out of bounds\n");
-- 
2.9.3

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


[PATCH weston 02/68] meson: pixel-formats

2016-12-09 Thread Daniel Stone
Differential Revision: https://phabricator.freedesktop.org/D1512
---
 libweston/meson.build | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libweston/meson.build b/libweston/meson.build
index d396c00..aee444a 100644
--- a/libweston/meson.build
+++ b/libweston/meson.build
@@ -19,6 +19,7 @@ srcs_libweston = [
'noop-renderer.c',
'pixman-renderer.c',
'linux-dmabuf.c',
+   'pixel-formats.c',
'screenshooter.c',
'../shared/file-util.c',
'../shared/matrix.c',
-- 
2.9.3

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


[PATCH weston 09/68] compositor-drm: Reshuffle and comment plane conditions

2016-12-09 Thread Daniel Stone
Try to harmonise the various plane-import paths a little bit, starting
with reshuffling and commenting the conditions to do so.

Signed-off-by: Daniel Stone 

Differential Revision: https://phabricator.freedesktop.org/D1413
---
 libweston/compositor-drm.c | 79 --
 1 file changed, 48 insertions(+), 31 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 5fb45b4..8cd9d5a 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -502,18 +502,28 @@ drm_output_prepare_scanout_view(struct drm_output *output,
struct gbm_bo *bo;
uint32_t format;
 
-   if (ev->geometry.x != output->base.x ||
-   ev->geometry.y != output->base.y ||
-   buffer == NULL || b->gbm == NULL ||
-   buffer->width != output->base.current_mode->width ||
-   buffer->height != output->base.current_mode->height ||
-   output->base.transform != viewport->buffer.transform ||
-   ev->transform.enabled)
+   /* We use GBM to import buffers. */
+   if (b->gbm == NULL)
+   return NULL;
+
+   if (buffer == NULL)
return NULL;
 
+   /* Make sure our view is exactly compatible with the output. */
+   if (ev->geometry.x != output->base.x ||
+   ev->geometry.y != output->base.y)
+   return NULL;
+   if (ev->transform.enabled)
+   return NULL;
if (ev->geometry.scissor_enabled)
return NULL;
 
+   if (buffer->width != output->base.current_mode->width ||
+   buffer->height != output->base.current_mode->height)
+   return NULL;
+   if (viewport->buffer.transform != output->base.transform)
+   return NULL;
+
bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
   buffer->resource, GBM_BO_USE_SCANOUT);
 
@@ -950,34 +960,33 @@ drm_output_prepare_overlay_view(struct drm_output *output,
uint32_t format;
wl_fixed_t sx1, sy1, sx2, sy2;
 
-   if (b->gbm == NULL)
-   return NULL;
-
-   if (viewport->buffer.transform != output->base.transform)
-   return NULL;
-
-   if (viewport->buffer.scale != output->base.current_scale)
-   return NULL;
-
if (b->sprites_are_broken)
return NULL;
 
+   /* Don't import buffers which span multiple outputs. */
if (ev->output_mask != (1u << output->base.id))
return NULL;
 
-   if (ev->surface->buffer_ref.buffer == NULL)
+   /* We can only import GBM buffers. */
+   if (b->gbm == NULL)
return NULL;
-   buffer_resource = ev->surface->buffer_ref.buffer->resource;
 
-   if (ev->alpha != 1.0f)
+   if (ev->surface->buffer_ref.buffer == NULL)
return NULL;
-
+   buffer_resource = ev->surface->buffer_ref.buffer->resource;
if (wl_shm_buffer_get(buffer_resource))
return NULL;
 
+   if (viewport->buffer.transform != output->base.transform)
+   return NULL;
+   if (viewport->buffer.scale != output->base.current_scale)
+   return NULL;
if (!drm_view_transform_supported(ev))
return NULL;
 
+   if (ev->alpha != 1.0f)
+   return NULL;
+
wl_list_for_each(s, >sprite_list, link) {
if (!drm_sprite_crtc_supported(output, s))
continue;
@@ -1114,23 +1123,20 @@ drm_output_prepare_cursor_view(struct drm_output 
*output,
struct weston_buffer_viewport *viewport = >surface->buffer_viewport;
struct wl_shm_buffer *shmbuf;
 
-   if (ev->transform.enabled &&
-   (ev->transform.matrix.type > WESTON_MATRIX_TRANSFORM_TRANSLATE))
-   return NULL;
-   if (b->gbm == NULL)
-   return NULL;
-   if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
-   return NULL;
-   if (viewport->buffer.scale != output->base.current_scale)
+   if (b->cursors_are_broken)
return NULL;
+
if (output->cursor_view)
return NULL;
+
+   /* Don't import buffers which span multiple outputs. */
if (ev->output_mask != (1u << output->base.id))
return NULL;
-   if (b->cursors_are_broken)
-   return NULL;
-   if (ev->geometry.scissor_enabled)
+
+   /* We use GBM to import SHM buffers. */
+   if (b->gbm == NULL)
return NULL;
+
if (ev->surface->buffer_ref.buffer == NULL)
return NULL;
shmbuf = wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource);
@@ -1138,6 +1144,17 @@ drm_output_prepare_cursor_view(struct drm_output *output,
return NULL;
if (wl_shm_buffer_get_format(shmbuf) != WL_SHM_FORMAT_ARGB)
return NULL;
+
+   if (output->base.transform != 

[PATCH weston 05/68] compositor-drm: Remove open-coded weston_compositor_wake

2016-12-09 Thread Daniel Stone
This always changes the state to ACTIVE when we enter the session,
whereas the previous implementation preserved the state (i.e. if state
was SLEEPING on exit, it would be restored to SLEEPING, but also with a
repaint). This seems more helpful behaviour, however: if you enter a
session, it's probably in order to interact with it.

Differential Revision: https://phabricator.freedesktop.org/D1482

Signed-off-by: Daniel Stone 
Reviewed-by: Quentin Glidic 
---
 libweston/compositor-drm.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 7d1c01b..d577c05 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -116,8 +116,6 @@ struct drm_backend {
 
int use_pixman;
 
-   uint32_t prev_state;
-
struct udev_input input;
 
int32_t cursor_width;
@@ -2833,14 +2831,13 @@ session_notify(struct wl_listener *listener, void *data)
 
if (compositor->session_active) {
weston_log("activating session\n");
-   compositor->state = b->prev_state;
+   weston_compositor_wake(compositor);
weston_compositor_damage_all(compositor);
udev_input_enable(>input);
} else {
weston_log("deactivating session\n");
udev_input_disable(>input);
 
-   b->prev_state = compositor->state;
weston_compositor_offscreen(compositor);
 
/* If we have a repaint scheduled (either from a
@@ -3197,8 +3194,6 @@ drm_backend_create(struct weston_compositor *compositor,
b->base.destroy = drm_destroy;
b->base.restore = drm_restore;
 
-   b->prev_state = WESTON_COMPOSITOR_ACTIVE;
-
weston_setup_vt_switch_bindings(compositor);
 
wl_list_init(>sprite_list);
-- 
2.9.3

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


[PATCH weston 08/68] compositor-drm: Extract EGL destroy to helper

2016-12-09 Thread Daniel Stone
No functional change.

Differential Revision: https://phabricator.freedesktop.org/D1484

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 2d5faa0..5fb45b4 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1322,9 +1322,6 @@ drm_assign_planes(struct weston_output *output_base)
pixman_region32_fini();
 }
 
-static void
-drm_output_fini_pixman(struct drm_output *output);
-
 /**
  * Find the closest-matching mode for a given target
  *
@@ -1363,8 +1360,12 @@ choose_mode (struct drm_output *output, struct 
weston_mode *target_mode)
 
 static int
 drm_output_init_egl(struct drm_output *output, struct drm_backend *b);
+static void
+drm_output_fini_egl(struct drm_output *output);
 static int
 drm_output_init_pixman(struct drm_output *output, struct drm_backend *b);
+static void
+drm_output_fini_pixman(struct drm_output *output);
 
 static int
 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode 
*mode)
@@ -1414,9 +1415,7 @@ drm_output_switch_mode(struct weston_output *output_base, 
struct weston_mode *mo
return -1;
}
} else {
-   gl_renderer->output_destroy(>base);
-   gbm_surface_destroy(output->gbm_surface);
-
+   drm_output_fini_egl(output);
if (drm_output_init_egl(output, b) < 0) {
weston_log("failed to init output egl state with "
   "new mode");
@@ -1853,6 +1852,13 @@ drm_output_init_egl(struct drm_output *output, struct 
drm_backend *b)
return 0;
 }
 
+static void
+drm_output_fini_egl(struct drm_output *output)
+{
+   gl_renderer->output_destroy(>base);
+   gbm_surface_destroy(output->gbm_surface);
+}
+
 static int
 drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
 {
@@ -2423,12 +2429,10 @@ drm_output_deinit(struct weston_output *base)
struct drm_output *output = to_drm_output(base);
struct drm_backend *b = to_drm_backend(base->compositor);
 
-   if (b->use_pixman) {
+   if (b->use_pixman)
drm_output_fini_pixman(output);
-   } else {
-   gl_renderer->output_destroy(>base);
-   gbm_surface_destroy(output->gbm_surface);
-   }
+   else
+   drm_output_fini_egl(output);
 
weston_plane_release(>fb_plane);
weston_plane_release(>cursor_plane);
-- 
2.9.3

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


[PATCH weston 04/68] compositor-drm: Delete drm_backend_set_modes

2016-12-09 Thread Daniel Stone
Even if we do have a framebuffer matching the mode, we immediately
schedule a repaint, meaning we either do work for no reason, or show
stale content before we bring up the new content.

Delete this and just let repaint deal with it.

Differential Revision: https://phabricator.freedesktop.org/D1481

Signed-off-by: Daniel Stone 
---
 libweston/compositor-drm.c | 33 -
 1 file changed, 33 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 268117d..7d1c01b 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -2824,38 +2824,6 @@ drm_destroy(struct weston_compositor *ec)
 }
 
 static void
-drm_backend_set_modes(struct drm_backend *backend)
-{
-   struct drm_output *output;
-   struct drm_mode *drm_mode;
-   int ret;
-
-   wl_list_for_each(output, >compositor->output_list, base.link) {
-   if (!output->current) {
-   /* If something that would cause the output to
-* switch mode happened while in another vt, we
-* might not have a current drm_fb. In that case,
-* schedule a repaint and let drm_output_repaint
-* handle setting the mode. */
-   weston_output_schedule_repaint(>base);
-   continue;
-   }
-
-   drm_mode = (struct drm_mode *) output->base.current_mode;
-   ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
-output->current->fb_id, 0, 0,
->connector_id, 1,
-_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);
-   }
-   }
-}
-
-static void
 session_notify(struct wl_listener *listener, void *data)
 {
struct weston_compositor *compositor = data;
@@ -2866,7 +2834,6 @@ session_notify(struct wl_listener *listener, void *data)
if (compositor->session_active) {
weston_log("activating session\n");
compositor->state = b->prev_state;
-   drm_backend_set_modes(b);
weston_compositor_damage_all(compositor);
udev_input_enable(>input);
} else {
-- 
2.9.3

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


[PATCH weston 03/68] compositor-drm: Comment struct members

2016-12-09 Thread Daniel Stone
Clarify the difference between crtc_id (DRM object) and pipe (index into
drmModeRes->crtcs array, possible_crtcs bitmask).

Signed-off-by: Daniel Stone 
Reviewed-by: Quentin Glidic 
Differential Revision: https://phabricator.freedesktop.org/D1405
---
 libweston/compositor-drm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index a899213..268117d 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -155,8 +155,8 @@ struct drm_output {
struct weston_output base;
drmModeConnector *connector;
 
-   uint32_t crtc_id;
-   int pipe;
+   uint32_t crtc_id; /* object ID to pass to DRM functions */
+   int pipe; /* index of CRTC in resource array / bitmasks */
uint32_t connector_id;
drmModeCrtcPtr original_crtc;
struct drm_edid edid;
-- 
2.9.3

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


[PATCH weston v2 0/68] Atomic modesetting, planes, extended drm_fb

2016-12-09 Thread Daniel Stone
Hi all,
This is v2 of the atomic patchset, which incorporates quite a few
fixups on the original code, and extends it far enough to flip
sprites_are_broken off for atomic. \o/

Compared to earlier versions, drm_output_state is introduced much
earlier, and everything hangs off this. This made a lot of things much
more clean than they used to be. Most of the patches before this are
relatively untouched, but for bugfixes.

The pixel-format helpers patch is new, after I got frustrated at
having to write yet another table of formats with validation. I'm
fully intending to convert gl-renderer over to using this for its SHM
upload path, but on the other hand I didn't want to tie that together
with this series; it's big enough as it is. (Similarly, for
multi-output you'll need the 'Assign new views to the primary plane'
patch I sent out earlier, separately.)

On top of the code from v1, which is primarily concerned with how we
apply state, v2 attacks how we _generate_ the state in the first
place. The major difference is the whittling down of the
prepare_*_view() functions into common helpers, and then cleaving
assign_planes() in two. Doing the latter allows us to actually
reasonably do atomic TEST_ONLY.

First we try to construct a view made entirely out of planes and
nothing else; if this succeeds, we just use that and we don't need to
render anything. Failing that, we try to incrementally build a state,
trying one view at a time on one plane at a time, and seeing if that
changes anything. Doing this is what lets us flip sprites_are_broken,
because we can not only generate an optimal configuration, but make
sure it'll actually work when we do it.

Included in with this is a set of patches which let us import more
exotic buffers: primarily multi-planar, and with buffers. The earlier
work means that this is now generalised, and we can use them for
scanout, overlay, or anything really.

After this, a set of optimisation patches to ignore views which aren't
on other outputs and occluded views. This prevents us from triggering
spurious repaints on multi-head systems.

At the end of this, on my multihead setup, I was able to set up one
fullscreen (but scaled, due to HiDPI) and one non-fullscreen view
above it. With nothing else on screen, these were promoted to planes
(scanout and overlay, respectively), and no rendering was done. When
something was moved on top of them, they moved back to GPU composition
where necessary.

Any review or testing would be appreciated; I have no idea when 1.13
is supposed to be (in 11 days ...?), so I assume it won't land for
then, but I'd like to get this in as early as possible for the 1.14
cycle, so we can iron out as many of the bugs as possible.

Many thanks to Fabien DESSENNE for testing and fixes, Tomohito Esaki
for the dmabuf-without-GBM patch, Derek Foreman and others for things
like cursor clipping (already fixed, but the reports were nice). And
of course, I somehow forgot to mention in my original mail - to Pekka
Paalanen, Louis-Francis Ratté-Boulianne and Derek Foreman, who worked
on much earlier iterations of atomic support.

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


Re: [PATCH weston] compositor: Assign new views to the primary plane

2016-12-09 Thread Daniel Stone
Hi,

On 9 December 2016 at 16:35, Daniel Stone  wrote:
> However, this is undesirable for DRM. In a multi-output situation,
> we would see a view only visible on another output, reasonably decide we
> didn't want it in a plane on our output, and move it to the primary
> plane, causing damage, and an output repaint. The plane wouldn't be
> assigned until the other output ran through repaint.
>
> For large SHM buffers (weston_surface->keep_buffer as false), this means
> that the other output would assign it to a plane later, which caused
> weston_surface_damage to be called - in the exact way the comment says
> it shouldn't - which triggered a flush and buffer upload. By this stage,
> the buffer content would be gone and we would upload garbage.

Er, I can't English this afternoon. Imagine the above two paragraphs
never happened, and mentally replace them with:

However, this is undesirable for DRM. With multi-output, when
assign_planes() is called, any view which wasn't on a plane for our
putput was moved to the primary plane, thus causing damage, and an
output repaint. Fixing this, to ignore views which do not touch our
output at all, means that the view wouldn't have a plane assigned until
the other output eventually ran through repaint.

For large SHM buffers (weston_surface->keep_buffer == false), this means
that by the time the other output assigned it to a plane, the buffer may
have been discarded on the client side.

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


[PATCH weston] compositor: Assign new views to the primary plane

2016-12-09 Thread Daniel Stone
When we create a new view, assign it to the primary plane from the
beginning.

This made no difference before, since the next surface repaint would
forcibly assign all views to a plane, either through DRM's
assign_planes() hook, or the fallback inside core repaint.

However, this is undesirable for DRM. In a multi-output situation,
we would see a view only visible on another output, reasonably decide we
didn't want it in a plane on our output, and move it to the primary
plane, causing damage, and an output repaint. The plane wouldn't be
assigned until the other output ran through repaint.

For large SHM buffers (weston_surface->keep_buffer as false), this means
that the other output would assign it to a plane later, which caused
weston_surface_damage to be called - in the exact way the comment says
it shouldn't - which triggered a flush and buffer upload. By this stage,
the buffer content would be gone and we would upload garbage.

Avoid this problem for now by assigning the view to the primary plane on
creation, thus short-circuiting weston_view_move_to_plane when we do
call it during output repaint. This is arguably the right thing to do if
definitely the wrong way to fix it, but the atomic series is long enough
for now.

Signed-off-by: Daniel Stone 
Cc: Pekka Paalanen 
---
 libweston/compositor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libweston/compositor.c b/libweston/compositor.c
index 6a69394..895a040 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -269,6 +269,7 @@ weston_view_create(struct weston_surface *surface)
return NULL;
 
view->surface = surface;
+   view->plane = >compositor->primary_plane;
 
/* Assign to surface */
wl_list_insert(>views, >surface_link);
-- 
2.9.3

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


Re: [PATCH wayland v2] wayland-server: abort instead of posting events with wrong client objects

2016-12-09 Thread Derek Foreman

On 09/12/16 08:51 AM, Giulio Camuffo wrote:

2016-12-08 20:36 GMT+01:00 Derek Foreman :

Check that all the objects in an event belong to the same client as
the resource posting it.  This prevents a compositor from accidentally
mixing client objects and posting an event that causes a client to
kill itself.

It's intended that the compositor killing itself be easier to debug
than the client killing itself for something that it's completely
innocent of.


It may be easier, but as an user the compositor crashing is a highly
disruptive event, and i think we should strive to avoid it at all
times. By all means, log the problem, get a backtrace and print it,
maybe, but i don't agree with the abort(). Unless the problem really
is unrecoverable, but it seems this is not the case. If it was an
assert(0) it may be better, but i'm not sure i'd like that either.



Yeah, Pekka and I have been discussing that further on-list (and off). 
At this point I'm thinking it should just wl_log(), and drop the client 
the same way nullable violation does.


I wouldn't mind a conditional assert on WAYLAND_DEBUG=server or such...

I'm also wondering if other aborts() that happen in wl_closure_marshal() 
should be reconsidered...  I think perhaps they were added with client 
side in mind, without paying attention to the fact that 
wl_closure_marshal() is called from both client and server.


Thanks,
Derek


Cheers,
Giulio



Signed-off-by: Derek Foreman 
---

Changes since v1:
uses get_next_arguments and arg_count_for_signature in the normal fashion
abort instead of assert


This does not address Pekka's request for a new_id test, as it's not
immediately clear to me how to write it.

 src/wayland-server.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 9d7d9c1..429dbef 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -160,6 +160,33 @@ log_closure(struct wl_resource *resource,
}
 }

+static void
+verify_objects(struct wl_resource *resource, uint32_t opcode,
+ union wl_argument *args)
+{
+   struct wl_object *object = >object;
+   const char *signature = object->interface->events[opcode].signature;
+   struct argument_details arg;
+   struct wl_resource *res;
+   int count, i;
+
+   count = arg_count_for_signature(signature);
+   for (i = 0; i < count; i++) {
+   signature = get_next_argument(signature, );
+   switch (arg.type) {
+   case 'o':
+   res = (struct wl_resource *) (args[i].o);
+   if (res && res->client != resource->client) {
+   wl_log("unrecoverable error: The compositor "
+  "tried to use an object from one "
+  "client in an event for a different "
+  "client.\n");
+   abort();
+   }
+   }
+   }
+}
+
 WL_EXPORT void
 wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
 union wl_argument *args)
@@ -167,6 +194,7 @@ wl_resource_post_event_array(struct wl_resource *resource, 
uint32_t opcode,
struct wl_closure *closure;
struct wl_object *object = >object;

+   verify_objects(resource, opcode, args);
closure = wl_closure_marshal(object, opcode, args,
 >interface->events[opcode]);

@@ -206,6 +234,7 @@ wl_resource_queue_event_array(struct wl_resource *resource, 
uint32_t opcode,
struct wl_closure *closure;
struct wl_object *object = >object;

+   verify_objects(resource, opcode, args);
closure = wl_closure_marshal(object, opcode, args,
 >interface->events[opcode]);

--
2.10.2

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


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


Re: [PATCH wayland v2] wayland-server: abort instead of posting events with wrong client objects

2016-12-09 Thread Giulio Camuffo
2016-12-08 20:36 GMT+01:00 Derek Foreman :
> Check that all the objects in an event belong to the same client as
> the resource posting it.  This prevents a compositor from accidentally
> mixing client objects and posting an event that causes a client to
> kill itself.
>
> It's intended that the compositor killing itself be easier to debug
> than the client killing itself for something that it's completely
> innocent of.

It may be easier, but as an user the compositor crashing is a highly
disruptive event, and i think we should strive to avoid it at all
times. By all means, log the problem, get a backtrace and print it,
maybe, but i don't agree with the abort(). Unless the problem really
is unrecoverable, but it seems this is not the case. If it was an
assert(0) it may be better, but i'm not sure i'd like that either.


Cheers,
Giulio

>
> Signed-off-by: Derek Foreman 
> ---
>
> Changes since v1:
> uses get_next_arguments and arg_count_for_signature in the normal fashion
> abort instead of assert
>
>
> This does not address Pekka's request for a new_id test, as it's not
> immediately clear to me how to write it.
>
>  src/wayland-server.c | 29 +
>  1 file changed, 29 insertions(+)
>
> diff --git a/src/wayland-server.c b/src/wayland-server.c
> index 9d7d9c1..429dbef 100644
> --- a/src/wayland-server.c
> +++ b/src/wayland-server.c
> @@ -160,6 +160,33 @@ log_closure(struct wl_resource *resource,
> }
>  }
>
> +static void
> +verify_objects(struct wl_resource *resource, uint32_t opcode,
> + union wl_argument *args)
> +{
> +   struct wl_object *object = >object;
> +   const char *signature = object->interface->events[opcode].signature;
> +   struct argument_details arg;
> +   struct wl_resource *res;
> +   int count, i;
> +
> +   count = arg_count_for_signature(signature);
> +   for (i = 0; i < count; i++) {
> +   signature = get_next_argument(signature, );
> +   switch (arg.type) {
> +   case 'o':
> +   res = (struct wl_resource *) (args[i].o);
> +   if (res && res->client != resource->client) {
> +   wl_log("unrecoverable error: The compositor "
> +  "tried to use an object from one "
> +  "client in an event for a different "
> +  "client.\n");
> +   abort();
> +   }
> +   }
> +   }
> +}
> +
>  WL_EXPORT void
>  wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
>  union wl_argument *args)
> @@ -167,6 +194,7 @@ wl_resource_post_event_array(struct wl_resource 
> *resource, uint32_t opcode,
> struct wl_closure *closure;
> struct wl_object *object = >object;
>
> +   verify_objects(resource, opcode, args);
> closure = wl_closure_marshal(object, opcode, args,
>  >interface->events[opcode]);
>
> @@ -206,6 +234,7 @@ wl_resource_queue_event_array(struct wl_resource 
> *resource, uint32_t opcode,
> struct wl_closure *closure;
> struct wl_object *object = >object;
>
> +   verify_objects(resource, opcode, args);
> closure = wl_closure_marshal(object, opcode, args,
>  >interface->events[opcode]);
>
> --
> 2.10.2
>
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH wayland v2] wayland-server: abort instead of posting events with wrong client objects

2016-12-09 Thread Yong Bakos
Hi Derek,


> On Dec 8, 2016, at 11:36 AM, Derek Foreman  wrote:
> 
> Check that all the objects in an event belong to the same client as
> the resource posting it.  This prevents a compositor from accidentally
> mixing client objects and posting an event that causes a client to
> kill itself.
> 
> It's intended that the compositor killing itself be easier to debug
> than the client killing itself for something that it's completely
> innocent of.
> 
> Signed-off-by: Derek Foreman 
> ---
> 
> Changes since v1:
> uses get_next_arguments and arg_count_for_signature in the normal fashion
> abort instead of assert
> 
> 
> This does not address Pekka's request for a new_id test, as it's not
> immediately clear to me how to write it.
> 
> src/wayland-server.c | 29 +
> 1 file changed, 29 insertions(+)
> 
> diff --git a/src/wayland-server.c b/src/wayland-server.c
> index 9d7d9c1..429dbef 100644
> --- a/src/wayland-server.c
> +++ b/src/wayland-server.c
> @@ -160,6 +160,33 @@ log_closure(struct wl_resource *resource,
>   }
> }
> 
> +static void
> +verify_objects(struct wl_resource *resource, uint32_t opcode,
> +   union wl_argument *args)
> +{
> + struct wl_object *object = >object;
> + const char *signature = object->interface->events[opcode].signature;
> + struct argument_details arg;
> + struct wl_resource *res;

I know that `res` is used throughout the source, but since there are
two resources here, it might be nice to add some semantics, eg. `event_resource`
or `argument_resource`.


> + int count, i;
> +
> + count = arg_count_for_signature(signature);
> + for (i = 0; i < count; i++) {
> + signature = get_next_argument(signature, );
> + switch (arg.type) {
> + case 'o':
> + res = (struct wl_resource *) (args[i].o);
> + if (res && res->client != resource->client) {
> + wl_log("unrecoverable error: The compositor "
> +"tried to use an object from one "
> +"client in an event for a different "
> +"client.\n");
> + abort();

This should probably wl_abort, right?

Regards,
yong


> + }
> + }
> + }
> +}
> +
> WL_EXPORT void
> wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
>union wl_argument *args)
> @@ -167,6 +194,7 @@ wl_resource_post_event_array(struct wl_resource 
> *resource, uint32_t opcode,
>   struct wl_closure *closure;
>   struct wl_object *object = >object;
> 
> + verify_objects(resource, opcode, args);
>   closure = wl_closure_marshal(object, opcode, args,
>>interface->events[opcode]);
> 
> @@ -206,6 +234,7 @@ wl_resource_queue_event_array(struct wl_resource 
> *resource, uint32_t opcode,
>   struct wl_closure *closure;
>   struct wl_object *object = >object;
> 
> + verify_objects(resource, opcode, args);
>   closure = wl_closure_marshal(object, opcode, args,
>>interface->events[opcode]);
> 
> -- 
> 2.10.2
> 
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel

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


Re: [RFC wayland-protocols] Color management protocol

2016-12-09 Thread Niels Ole Salscheider
Am Donnerstag, 8. Dezember 2016, 15:51:12 CET schrieb Graeme Gill:
> Niels Ole Salscheider wrote:
> > Therefore I think that the situation has changed and I'd like to propose
> > this protocol for inclusion in wayland-protocols again.
> > What do you think?
> 
> Hi,
>   I'm prompted to look into the current state of color management
> in Wayland, by Richard Hughes comment on the ArgyllCMS mailing list
> 
> recently that:
> > About this; in the near future systems will be migrating from X11 to
> > Wayland (Fedora 25 already defaults to Wayland, other distros will
> > follow) and so setting X atoms is no longer going to work. Even with
> > XWayland (the compatibility "wrapper" that provides an isolated
> > xserver for the app) you can't use the root window as it's isolated
> > from the other windows. I think most applications that want to know
> > what profile to use are now using either libcolord, or more commonly,
> > the colord DBus API.
> 
> What I take from this is that XWayland is lacking in its emulation
> of existing X11 color management protocols (primarily due to lack
> of underlying support in Wayland), and that currently the only
> option for pure Wayland applications is to depend on system
> specific work-arounds such as using Weston with colord. I can
> therefore see that users that depend on color managed X11 applications
> (such as photographers, desktop publishers, video editors etc.)
> aren't going to be switching to Wayland based systems any
> time soon.
> 
> Looking through the current Wayland color-management protocol
> proposal, I think it is missing a really fundamental thing -
> managing the output device color calibration state and color
> profile. I guess the assumption is that this is being done
> by colord, but my understanding is that colord is specific
> to Gnome based systems, and certainly depends on DBus, which
> Wayland does not. [ Please correct me if I've got any of this wrong. ]

It is (currently) up to the compositor to decide how to implement this. The 
compositor could come with its own settings for the output color profiles or 
query some other program. This might be colord, but it could also be 
kolormanager, or something else.

> It also seems fundamentally poor design to be using a parallel
> protocol to manage the color of the graphics system, rather
> than it being kept in sync with the elements being managed,
> such as outputs and pixel rasters, etc. Certainly in X11 it is
> all kept within the X11 protocol or its extensions.
> If Wayland gets extended to be a remote protocol, then
> the existence of in band protocols for color management
> become even more important.

Yes, with the protocol I proposed there is a (small) time window after 
changing the output color space where the application might still display 
surfaces with the old color space...

> So as a broad outline, what I would regard as features of
> a reasonable color management facility for a graphics
> system such as Wayland are:
> 
> * That color management protocol's have two uses :- 1) configuring
>   color management and 2) allowing applications to use color management.
>   These two uses may need different security profiles.
>   The assumption should be that color management applications
>   used to create calibrations, profiles and configure the
>   state of color management, are of equal importance to color
>   managed applications that depend on a properly profiled and
>   configured color management system, since you can't have latter
>   with out the former.
> 
> * Color management of a graphics rendering system such as Wayland
>   should be split into two levels (possibly two extensions) :-
> 
>   1) Core == output device management, which involves identifying output
> devices, controlling their calibration state (Video LUT), installing a
> color profile resources associated with that output device, and identifying
> which rendered pixels go to which output device(s). This is the most basic
> requirement, since this is the bare minimum for applications to be properly
> color managed. It is also a necessary resource for the second level to be
> able to operate.
> 
>   2) Enhanced == input space management, which assumes a graphics
>   server rendering system capable of color management. This involves
> labeling an input raster with a color profile, and controlling the manner
> of rendering (i.e. rendering intent, maybe blending space ? etc.) This is
> useful for implementing default color management (e.g. as a means of coping
> with wide gamut displays when many applications are not color aware), or as
> a low developer overhead means of implementing basic color management in
> non color critical applications.
> 
> Translating these aims into a more concrete set of capabilities might
> look like this:
> 
> Core:
>   Get corresponding CRTC regions for a given Surface.
>   Get corresponding Output(s) for a CRTC.
>   Get unique Monitor identifier for an Output (i.e. EDID)
>  

Re: [RFC wayland-protocols] Color management protocol

2016-12-09 Thread Niels Ole Salscheider
Am Donnerstag, 8. Dezember 2016, 13:33:20 CET schrieb Graeme Gill:
> Niels Ole Salscheider wrote:
> 
> Hi,
> 
> > The first version of my proposal had such a flag. I removed it and
> > replaced it by the described version based on feedback from Zoxc
> > (zox...@gmail.com).
> Do you have a link to the specifics ?

Most of the discussion happened on IRC back then. It should be in the logs 
but...

> > I can see advantages with both solutions. One advantage with the current
> > proposal is that you can have a surface that covers multiple screens. In
> > this case the compositor can still try its best to correct the colours
> > for all but the main screen.
> 
> I'm not quite sure what you mean. Generally an application will have
> specific reasons for wanting to do it's own color management - for
> instance, perhaps it is previewing a CMYKOGlclm file, and wants to
> treat out of gamut mapping and black point mapping in a particular way, etc.
> I don't think the Wayland compositor is going to be expected to handle
> CMYKOGlclm etc. input rasters, never mind all the requirements of
> specialist application color management!

This is of course something that the client application has to do. It would 
query the main output for its surface, do the conversions to that color space 
and then attach the output color space to the surface.

The compositor now must not touch the parts of the surface on the main output 
(where the color spaces match). But it could still try to convert from the 
color space of the main output to that of a secondary screen if the surface 
covers two screens with different color profiles.

This might of course cause artifacts when one of the screens has a too small 
gamut but still seems better than ignoring this.

But then again most people that work with professional applications would not 
make them cover multiple screens, I guess. Therefore I'm not opposed to adding 
a flag that indicates that the application wants to disable color corrections 
completely for that surface, independent of the output.

> Which is not to say that compositor color management doesn't have its
> place - it is ideal for applications that just want to use "RGB", and
> not deal with specific display behavior.

Very simple applications would just keep the attached sRGB color space and 
maybe place images on subsurfaces with the embedded color space from the image 
attached.

Applications that care a bit more about color correction (but do not have 
professional needs) could convert all their colors to the blending color space 
of the compositor. I'd expect this blending color space to be linear if the 
compositor cares about good colors.
This would have the advantage that the compositor does not have to do the 
conversion "application output color space -> blending color space".

> > Back then I argued that this might not be good enough if you want to
> > calibrate the monitor. But the consent was that this would require
> > another protocol to disable all colour corrections anyway and that it
> > could be developed at a later point.
> 
> I strongly disagree with this idea - disabling application-side color
> management is a fundamental step in achieving end to end color management.
> You don't have color management until you are able to profile the output
> device, so this is not something that can be left until latter!
> 
> Graeme Gill.
> 
> 
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel


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


  1   2   >