Mir

Merge lp:~mir-team/mir/touchspot-renderable into lp:mir

Proposed by Robert Carr
Status: Merged
Approved by: Cemil Azizoglu
Approved revision: no longer in the source branch.
Merged at revision: 1924
Proposed branch: lp:~mir-team/mir/touchspot-renderable
Merge into: lp:mir
Prerequisite: lp:~kdub/mir/fix-1348330
Diff against target: 3585 lines (+2202/-95)
77 files modified
debian/control (+2/-2)
debian/libmirplatform3.install (+1/-1)
include/platform/mir/graphics/platform.h (+3/-0)
include/platform/mir/options/configuration.h (+1/-0)
include/server/mir/default_server_configuration.h (+5/-2)
include/server/mir/input/cursor_listener.h (+2/-2)
include/server/mir/input/touch_visualizer.h (+6/-2)
platform-ABI-sha1sums (+2/-2)
playground/demo-shell/demo_compositor.cpp (+6/-1)
playground/demo-shell/demo_renderer.cpp (+8/-3)
playground/demo-shell/demo_renderer.h (+7/-1)
server-ABI-sha1sums (+5/-4)
src/include/platform/mir/graphics/buffer_writer.h (+44/-0)
src/include/platform/mir/graphics/native_platform.h (+3/-0)
src/include/server/mir/compositor/scene_element.h (+4/-0)
src/include/server/mir/input/scene.h (+23/-8)
src/include/server/mir/scene/legacy_scene_change_notification.h (+2/-0)
src/include/server/mir/scene/observer.h (+4/-0)
src/platform/CMakeLists.txt (+1/-1)
src/platform/graphics/android/CMakeLists.txt (+1/-0)
src/platform/graphics/android/android_buffer_writer.cpp (+70/-0)
src/platform/graphics/android/android_buffer_writer.h (+50/-0)
src/platform/graphics/android/android_display.cpp (+1/-1)
src/platform/graphics/android/android_platform.cpp (+6/-0)
src/platform/graphics/android/android_platform.h (+1/-0)
src/platform/graphics/mesa/CMakeLists.txt (+1/-0)
src/platform/graphics/mesa/buffer_allocator.cpp (+1/-1)
src/platform/graphics/mesa/buffer_writer.cpp (+40/-0)
src/platform/graphics/mesa/buffer_writer.h (+43/-0)
src/platform/graphics/mesa/native_platform.cpp (+5/-0)
src/platform/graphics/mesa/native_platform.h (+1/-0)
src/platform/graphics/mesa/platform.cpp (+6/-0)
src/platform/graphics/mesa/platform.h (+1/-0)
src/platform/graphics/mesa/shm_buffer.cpp (+13/-0)
src/platform/graphics/mesa/shm_buffer.h (+2/-0)
src/platform/options/default_configuration.cpp (+3/-1)
src/platform/symbols.map (+2/-1)
src/server/graphics/default_configuration.cpp (+10/-0)
src/server/graphics/nested/nested_platform.cpp (+5/-0)
src/server/graphics/nested/nested_platform.h (+1/-0)
src/server/input/CMakeLists.txt (+1/-0)
src/server/input/android/android_input_registrar.cpp (+4/-0)
src/server/input/android/android_input_registrar.h (+1/-0)
src/server/input/android/android_input_target_enumerator.cpp (+4/-4)
src/server/input/android/android_input_target_enumerator.h (+3/-3)
src/server/input/android/input_sender.cpp (+9/-5)
src/server/input/android/input_sender.h (+1/-0)
src/server/input/cursor_controller.cpp (+8/-3)
src/server/input/cursor_controller.h (+3/-3)
src/server/input/default_configuration.cpp (+16/-10)
src/server/input/touchspot_controller.cpp (+166/-0)
src/server/input/touchspot_controller.h (+77/-0)
src/server/input/touchspot_image.c (+1034/-0)
src/server/scene/basic_surface.cpp (+0/-1)
src/server/scene/default_configuration.cpp (+2/-2)
src/server/scene/legacy_scene_change_notification.cpp (+5/-0)
src/server/scene/surface_stack.cpp (+78/-0)
src/server/scene/surface_stack.h (+16/-3)
src/server/symbols.map (+4/-1)
tests/acceptance-tests/test_nested_mir.cpp (+6/-1)
tests/acceptance-tests/test_touchspot_visualization.cpp (+2/-0)
tests/include/mir_test_doubles/null_platform.h (+7/-2)
tests/include/mir_test_doubles/stub_input_scene.h (+16/-5)
tests/include/mir_test_doubles/stub_scene_element.h (+5/-0)
tests/include/mir_test_doubles/stub_touch_visualizer.h (+6/-0)
tests/integration-tests/input/android/test_android_cursor_listener.cpp (+1/-1)
tests/integration-tests/input/android/test_android_input_manager.cpp (+1/-1)
tests/integration-tests/input/test_nested_input.cpp (+1/-1)
tests/mir_test_framework/stubbed_server_configuration.cpp (+13/-0)
tests/unit-tests/frontend/test_session_mediator.cpp (+1/-0)
tests/unit-tests/graphics/mesa/test_shm_buffer.cpp (+1/-1)
tests/unit-tests/graphics/nested/test_nested_platform.cpp (+5/-0)
tests/unit-tests/input/CMakeLists.txt (+1/-0)
tests/unit-tests/input/android/test_android_input_target_enumerator.cpp (+5/-4)
tests/unit-tests/input/test_cursor_controller.cpp (+12/-11)
tests/unit-tests/input/test_touchspot_controller.cpp (+199/-0)
tests/unit-tests/scene/test_surface_stack.cpp (+96/-0)
To merge this branch: bzr merge lp:~mir-team/mir/touchspot-renderable
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Needs Fixing
Andreas Pokorny (community) Approve
Alberto Aguirre (community) Approve
Kevin DuBois (community) Approve
Cemil Azizoglu (community) Approve
Review via email: mp+230555@code.launchpad.net

This proposal supersedes a proposal from 2014-07-30.

Commit message

Add touchspot visualizations toggleable with --enable-touchspots

Description of the change

Add touchspot visualizations toggleable with --enable-touchspots, a runtime configuration method will be added at the USC level.

A humble attempt at a review guide, beginning with comments on the implementation (1, 2):

1. A lot of the diff size comes from touchspot_image.c .I feel that the actual cost from this is minimal and its better than implementing/copy-pasting an anti-aliased circle drawing algorithm. I think I would prefer to implement the drawing algorthmically using libpixman, but there has been some resistance in the past.

2. The core class is TouchspotController (implements TouchVisualizer) (touchspot_controller.cpp). TouchspotController implements a bespoke interface out of android-input (see droidinput::PointerController, and src/server/input/android_android/pointer_controller.cpp). TouchspotController responds to an instantaneous list of touchpoints (that is to say is not responsible for touch state tracking) and maintains an internal set of Renderables which it places at appropriate positions in the scene.

It's come up, should TouchspotController really use a bespoke interface for touch visualization or instead function as a server input filter. I'll give a few reasons why I've chosen this path (a, b, c):

a. Test guidance: There are two tests which guide towards the bespoke interface. First the test which expresses that device touches result in invocation of the TouchspotController. The TouchVisualizer interface allows this to be tested without involving the unrelated parts of MirEvent, it also allows for testing of the touch-visualization loop independent of the TouchspotController, helping solve a problem under test for shells which desire alternate implementations.
b. Reduction of domain: The TouchVisualizer is not interested in key events, the ability to accept/reject events, or a host of other things the InputFilter offers.
c. Decoupling from dispatch loop: The TouchVisualizer (through droidinput::PointerController) operates at the level of the InputReader. Given that it may never consume input events, there is no need for it to exist as part of the dispatch loop where it can stall a greater portion of the server event stream (due to say lock contention on the scene).

Moving on to some comments about the assorted server changes:

1. DemoRenderer requires modification in order to not render decorations on the touchspots. Ultimately I think the overridden ::begin interface is pretty strange...but its not any worse than the existing code. This little hack exposes a wart of DemoRenderer I had yet to notice...it implements mg::Renderer but no one consumes it through this interface.)prop
2. SurfaceStack extended with add/remove input_visualization. Ideally this would use a more scenegraphy style approach...not requiring bespoke methods for input visualizations (this interface is appropriate for touchspots, and then cursors). Changing add_surface/remove_surface to be add_renderable/remove_renderable is not a trivial task though, in particular due to the nature of SurfaceObservers (observing a superset of renderable properties) I estimated that this would add a couple thousand more lines to the diff. Ultimately this method is useful for multiple consumers (touchspot, cursor) and easy to verify (see changes in test_surface_stack) so I decided it had a certain pragmatic elegance.
3. SceneObserver extended with scene_changed, SurfaceStack extended with emit_scene_changed. It's not possible for the TouchspotRenderables to use the SurfaceObserver interface, and so an interface to notify the compositor the renderables have been added/removed/moved is required. In order for the TouchspotRenderable to use the the same interface as SurfaceObservation a few changes would be required. Notably the point at which surface observers are installed (SceneObserver:surface_added/removed) would need to work through a common base interface (presumably mg::Renderable or mc::SceneElement). Then, the SurfaceObserver interface itself would need trimming down, some methods are inappropriate for non surface renderables, i.e. SurfaceAttributes. Actually! If we wish to enforce the notion that the "scene" is a complete representation of the visual output, the SurfaceObserver needs trimming down anyway, the compositor should not be responding directly to a MirSurfaceAttrib change, rather the shell should respond and make changes to directly render-able attributes (i.e. size...) triggering recomposition. This suggests that two interfaces are warranted: mir::shell::SurfaceObserver and mir::compositor::(SceneElement/Renderable)Observer . I estimated this as another 2000 lines or so of diff though, and likely to cause some controversy, so I don't really want to open it up in this mp.
4. mi::InputTargets renamed to mi::Scene, with the addition of add/remove input_visualization and emit_scene_changed I think this is an obvious choice.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

At a quick glance, the things making this a 3685 line proposal actually don't need to be here...

(1) server-ABI-sha1sums: Changes to the ordering of this file are unreviewable (can't tell if things have been deleted or just moved). Please either keep the existing ordering or propose a re-ordering separately as a pre-req.

(2) touchspot_image.c: Obviously big as text. I think we can do better by generating this texture algorithmically. Not a blocker but I might do a proof-of-concept to demonstrate...

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

(3) Unused #includes and whitespace changes can be removed:
src/server/compositor/temporary_buffers.cpp
src/server/compositor/temporary_buffers.h

(4) src/platform/graphics/android/android_buffer_writer.cpp
Hmm, I'm wondering if we should have already abstracted software buffers on the server side so you don't need to write platform-specific code like this.

(5) A touchspot size of 64px is probably too small for high-res displays. If you're actually touching the display then it would be helpful for the touchspot to not be so small that it's completely hidden behind a finger. Consider making the Renderable rectangle dimensions independent of the buffer dimensions. OpenGL will scale for you.

Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

(1) server-ABI-sha1sums: Changes to the ordering of this file are unreviewable (can't tell if things have been deleted or just moved). Please either keep the existing ordering or propose a re-ordering separately as a pre-req.

Proposed reoredering as prereq.

(3) Unused #includes and whitespace changes can be removed:
src/server/compositor/temporary_buffers.cpp
src/server/compositor/temporary_buffers.h

Fixed! Thanks.

>> (4) src/platform/graphics/android/android_buffer_writer.cpp
>> Hmm, I'm wondering if we should have already abstracted software buffers on the server side so you
>> don't need to write platform-specific code like this.

You mean something like a generic version of the mesa shm_buffer? At one point I was thinking about something like this...but this way should be faster on platforms like android with HWC which allow generic buffer overlay.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

needed?:
639 + auto mga_buffer = std::dynamic_pointer_cast<mga::Buffer>(buffer);
640 + if (!mga_buffer)
641 + BOOST_THROW_EXCEPTION(std::logic_error("Invalid buffer (did not originate from platform graphics driver)"));

could there be stronger typing than void*?
void mga::AndroidBufferWriter::write(std::shared_ptr<mg::Buffer> const& buffer, void const* data, size_t size)

overlay is a bit overloaded already, maybe just add_cursor_renderable()?
2824 + void add_overlay(std::shared_ptr<graphics::Renderable> const& overlay);
2825 + void remove_overlay(std::weak_ptr<graphics::Renderable> const& overlay);

const&
643 + auto handle = buffer->native_buffer_handle();

we shouldn't be adding this to Renderable without rejecting all 'decorated' renderables down in the hwc code. This function makes the RenderableList indeterminate in terms of what would appear on the screen. It says it should be decorated but doesn't say what this entails.
165 + virtual bool should_be_decorated() const = 0;

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

> You mean something like a generic version of the mesa shm_buffer? At one point
> I was thinking about something like this...but this way should be faster on
> platforms like android with HWC which allow generic buffer overlay.

That's interesting. GBM also allows overlays (bypass) of software buffers. However when I enabled it, the performance was worse, which is quite reasonable to expect but is driver-dependent too. Maybe Android would also benefit from intentionally disallowing overlaying of buffers that reside in CPU memory... Although if the CPU/GPU memory is shared then theoretically there should be no performance disadvantage to overlaying software buffers.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Alright my blocking concern (1) is fixed. Please consider issues (2)-(5) still.

review: Abstain
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

needed?:
639 + auto mga_buffer = std::dynamic_pointer_cast<mga::Buffer>(buffer);
640 + if (!mga_buffer)
641 + BOOST_THROW_EXCEPTION(std::logic_error("Invalid buffer (did not originate from platform graphics driver)"));

Yeah...kind of strange I guess, just using static cast.

>> could there be stronger typing than void*?
>> void mga::AndroidBufferWriter::write(std::shared_ptr<mg::Buffer> const& buffer, void const* data, >> size_t size)

Using unsigned char now or did you mean something that encodes the pixel format?

>> overlay is a bit overloaded already, maybe just add_cursor_renderable()?
>> 2824 + void add_overlay(std::shared_ptr<graphics::Renderable> const& overlay);
>> 2825 + void remove_overlay(std::weak_ptr<graphics::Renderable> const& overlay);

How about "input_visualization"

>> const&
>> 643 + auto handle = buffer->native_buffer_handle();

Fixed

>> we shouldn't be adding this to Renderable without rejecting all 'decorated' renderables down in >> the hwc code. This function makes the RenderableList indeterminate in terms of what would appear >> on the screen. It says it should be decorated but doesn't say what this entails.
>> 165 + virtual bool should_be_decorated() const = 0;

I'm not sure the renderables should be / need to be rejected. If a shell wants to draw decorations then it is responsible for recognizing that passing the renderlist to the display buffer isn't appropriate right? So this method is really just for the shell compositor tor ecognize if the renderable is of a type which should be decorated. I agree it's strange...but I don't know how to do anything better without decorations expressed in the scene.

Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

> needed?:
> 639 + auto mga_buffer = std::dynamic_pointer_cast<mga::Buffer>(buffer);
> 640 + if (!mga_buffer)
> 641 + BOOST_THROW_EXCEPTION(std::logic_error("Invalid buffer (did not
> originate from platform graphics driver)"));
>
> Yeah...kind of strange I guess, just using static cast.
>
> >> could there be stronger typing than void*?
> >> void mga::AndroidBufferWriter::write(std::shared_ptr<mg::Buffer> const&
> buffer, void const* data, >> size_t size)
>
> Using unsigned char now or did you mean something that encodes the pixel
> format?
>
> >> overlay is a bit overloaded already, maybe just add_cursor_renderable()?
> >> 2824 + void add_overlay(std::shared_ptr<graphics::Renderable> const&
> overlay);
> >> 2825 + void remove_overlay(std::weak_ptr<graphics::Renderable> const&
> overlay);
>
> How about "input_visualization"
>
>
> >> const&
> >> 643 + auto handle = buffer->native_buffer_handle();
>
> Fixed
>
> >> we shouldn't be adding this to Renderable without rejecting all 'decorated'
> renderables down in >> the hwc code. This function makes the RenderableList
> indeterminate in terms of what would appear >> on the screen. It says it
> should be decorated but doesn't say what this entails.
> >> 165 + virtual bool should_be_decorated() const = 0;
>
> I'm not sure the renderables should be / need to be rejected. If a shell wants
> to draw decorations then it is responsible for recognizing that passing the
> renderlist to the display buffer isn't appropriate right? So this method is
> really just for the shell compositor tor ecognize if the renderable is of a
> type which should be decorated. I agree it's strange...but I don't know how to
> do anything better without decorations expressed in the scene.

The problem is really that:
mg::DisplayBuffer::post_renderables_if_optimizable() has the contract of either rejecting the list as whole, or painting exactly what is contained in the list. The addition of should_be_decorated() throws a big wrench in that contract because the implementer doesn't know what to paint correctly if should_be_decorated() returns true.

This also drives at the conversation in lp:~kdub/mir/prep-for-1348330. The compositors wants to do something different if this is a 'input visualization'. So, a decent compromise to me seems to be:
bool is_a_input_visualization()
instead of
bool should_be_decorated().
That way, the RenderableList remains definite, and can leave it up to the compositors as to what they want to do with the visualization.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I think it's safe to say that demo-shell's decorations are a proof of concept that may change dramatically in the case of "everything's in the scene graph".

A scenegraph may exist in memory or in run-time recursion structure (at present, also used in Compiz). If the scenegraph moves to the former then should_be_decorated() wouldn't exist.

At the same time, should_be_decorated() probably shouldn't exist as it will be superseded by improved surface dimension info, that's been started but not finished yet:
  https://code.launchpad.net/~vanvugt/mir/clarify-surface-size-pos/+merge/218578

That said, should_be_decorated() is simple enough that it's easy to drop when and if we're ready.

I suspect we can do better than the way post_renderables_if_optimizable() is designed right now, but until something better is proposed we should try to not block the overlays effort.

Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

should_be_decorated->is_a_surface

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal

I guess, still 'needs fixing', as the "is_a_surface" still has no context down within the mg::DisplayBuffer::post_renderables_if_optimizable function. Like, what should the display buffer do if this function returns false? "can hwc draw non-surfaces?" has an ambiguous answer.

In my estimation, mg::Renderable should just be a basic list of squares, the traditional information needed for blitting. A RenderableList should give a defined, specific picture that can be drawn.
I don't mind SceneElement gaining information that's specific to the scene, but Renderable should remain a simple list of squares.

Just for future planning, I think that some of this conflict is just because the name 'Renderable' is liked quite a lot. Perhaps we should rename the stuff down in the compositor BlitSquares, and then the Renderable/SceneElements can expand in whichever ways they need to, without dragging the platform display buffers (and the HWC implementation) along for the ride.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

Kevin: Moved is_a_surface to scene element. Chose is_a_surface over is_an_input_visualization to avoid the term input_visualization sticking (im not that hot on it).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Per previous discussions (in kdub's proposals I think?) any logic specific to how demo shell does decorations will likely need to be rewritten and/or removed in future as proper window management takes shape. And I think we're already landing too much code that apparently has a short lifespan.

Between that and my previous comments above, Abstain.

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

#1
86 + void begin(std::unordered_set<graphics::Renderable::ID> &&renderables_not_to_decorate) const;

I think its a bit more flexible not to force the use of the rvalue.
void begin(std::unordered_set<graphics::Renderable::ID> renderables_not_to_decorate) const;

begin(std::move(a)) would still use the move constructor

#2
193 + virtual std::shared_ptr<BufferWriter> create_buffer_writer() = 0;
I had to change to make_* over in my MP :)
<side note> I think that the "display stuff" should get split out of Platform into its own interface to get rid of NativePlatform.

#3
167 + virtual void write(std::shared_ptr<Buffer> const& buffer, unsigned char const* data, size_t size) = 0;

A continuation from the superseded discussion, but a char* and a size seems like it puts more burden on the caller of the interface to make sure that raw data in the char* matches what the buffer expects. (An example of this is line 1059 where we throw if the size is incorrect) The ideal is probably to see something like:
write(Buffer&, std::vector<Pixels>)
where the write function figures out how to get the pixels into that buffer (adjust for stride, format differences, etc etc)

#4
711 + auto mga_buffer = std::static_pointer_cast<mga::Buffer>(buffer);
needs removal.
Somewhat related, but write() could use a Buffer& instead of a shared_ptr<Buffer>

#5
716 + int usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
minor point, but we just need SW_WRITE_OFTEN

#6
696 +mga::AndroidBufferWriter::AndroidBufferWriter()
We recreate the gralloc module in the constructor here, could reuse a single instance.

#7
698 + int err;
699 +
could use auto and get rid of these lines

#8
963 +
2701
whitespace introduction

#9
The 64x64x4 still increases mir's memory and installation footprint a fair amount, maybe we could programatically create a smaller image?

Revision history for this message
Kevin DuBois (kdub) wrote :

okay, so structurally, much better.

I think
#1,2,4,5,7,8
are my 'needs fixings'

and the rest are just suggestions

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Kevin. Thanks for review :) Getting to your comments asap.

Reflected some on the configuration requirements with Anpok this morning. In particular autopilot would like to runtime enable/disable the visualization via IPC. I considered a mirclient function but we lack the necessary infrastructure, i.e.

mir_input_device_enable_touch_visualization could make sense if we supported some sort of client MirInputDevice enumeration.

For now ( some sort of client InputDevice enumeration is available) I have landed on the com.canonical.Unity.Screen DBus interface in USC. USC MP incoming soon.

In order to support this without awkward usage of mir options in USC or exposing the touchspot controller implementation I have added enable/disable methods to the TouchVisualizer interface and ported the default server configuration to use this mechanism for the static touchspot option.

Revision history for this message
Robert Carr (robertcarr) wrote :

kdub 1. Fixed rvalue usage...still not used to move semantics I guess.
2. Aha good call
3. It seems like we really need a Pixels(Array, Size, PixelFormat) kind of type...not for this MP though I think.
4, 5: Good call.
6: Hmm I kind of have the thought that I like it more this way so people can just construct it without getting in to the game of who owns the dependencies. On the other hand its not clear that hiding the depdency in the constructor is really correct. I think you could make an argument for it though in that the gralloc module is effectively a system resource...*shrug* I dont have a strong enough opinion to change it really but maybe someone else will comment.
7, 8: Fixed
9: I've thought about it...the problem is effective circle anti-aliasing algorithms are more than a few dozen that lines long...at which point the question starts to become, should we link in pixman? etc...to which there has been a little resistance in the past so I didn't want to dredge up again.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Interesting it looks like one of the jenkins jobs missed r1847...ah the perils of real time.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Not a complete review yet, just some first notes:

162 +class BufferWriter

At first glance it would be more natural to introduce a Buffer::write() method instead of a class that acts on the buffer, unless we want to potentially support multiple implementations of it.

1577 +void mi::TouchspotController::visualize_touches(std::vector<Spot> const& touches)

Perhaps the logic in this method would be more clear if we split it out into different stages, e.g.:

1. grow touchpot renderable vector as needed (already there)
2. for each touch: set up and add renderable to scene
3. for unused renderables: remove from scene

1618 + scene->emit_scene_changed();

We should call this out of lock if possible.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Why are the touchspots not rendered with just GL draw commands?

Why the need for raw RGB data?

review: Needs Information
Revision history for this message
Robert Carr (robertcarr) wrote :

write/BufferWriter discussed in standup. Calling scene->emit_scene_changed out of lock now.

Will think if visualize touches can be cleared up.

>>
>> Why are the touchspots not rendered with just GL draw commands?
>> Why the need for raw RGB data?
>>

It seems to me that RGB data is simpler in every way except for polluting the launchpad diff. No worry about anti-aliasing approaches, no dealing with GL contexts, etc...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

touch_visualizer.h should be in the public headers as the USC branch that makes use of this feature will use it.

review: Needs Fixing
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

556 + if (buffer.stride().as_uint32_t() * buffer_size.height.as_uint32_t() != size)
557 + BOOST_THROW_EXCEPTION(std::logic_error("Size of pixels is not equal to size of buffer"));

You should just do a line by line copy. You'll be excluding devices with stride.

review: Needs Fixing
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

1362 + void move_to(geom::Point pos)
1363 + {
1364 + std::lock_guard<std::mutex> lg(guard);
1365 + position = pos;
1366 + }

The position should either represent the centroid of the buffer, or it should be translated so that the renderable position centroid is the position given.

Othewise, the touchspots look like they are offset from the touch location.

review: Needs Fixing
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

With overlays enabled in an android based device, for a device say with 4 overlay layers..

It only renders 3/4 simultaneous touch-spots but the other client surfaces are not getting rendered.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

touchspot_controller.cpp:
 + nits: a lot of additional whitespace ..
 + unsure: from what interfaces it needs it feels more like belonging to scene maybe?
 + needs fixing: visualize_touches will benefit a lot from extracting the three steps inside the mutex block into separate methods, and you could remove some of the comments then
 + needs fixing: touch spot render ables should be centered around the spots

I might have missed the rationale behind it, because looking at how buffer writer is looks like an alternative buffer allocator/constructor function. Especially looking at the behavior - new buffer must match the old buffer in size...?

Nit: mgm::BufferWriter::write should throw std::invalid_argument when no shm buffer is supplied.

So this is a needs information with two small needs fixing.

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Thanks!

Republished header.
Fixed touchspot centroid.
Made stride copy line by line.l
Overlay issue revealed to be unrelated.
Will clean up visualize_touches in the next hour or so.
Will reflect on moving touchspot_controller to scene, and continue to reflect on BufferWriter.

Revision history for this message
Robert Carr (robertcarr) wrote :

I found it pretty difficult to refactor visualize_touches...

Splitting out functions seemed only to introduce obscure function names that further impaired readability, e.g.

ensure_renderable_pool_has_size_locked, etc...

I've added a textual description of the spot->renderable assignment algorithm in the hopes that this helps?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

sryy,but i meant something trivial like:

1441 + {
1442 + std::lock_guard<std::mutex> lg(guard);
1443 +
1444 + if (!enabled)
1445 + {
1446 + remove_touchspot_renderables();
1454 + return;
1455 + }
1456 +
1457 + grow_touchspot_renderables(touches.size());
1461 +
1462 + update_touchspot_renderables(touches);
1487 + }
1488 +
1489 + // TODO (hackish): We may have just moved renderables which with the current
1490 + // architecture of surface observers will not trigger a propagation to the
1491 + // compositor damage callback we need this "emit_scene_changed".
1492 + scene->emit_scene_changed();

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> I found it pretty difficult to refactor visualize_touches...
>
> Splitting out functions seemed only to introduce obscure function names that further impaired readability, e.g.

I think that, as a first step at least, moving the operations out of a single, big loop will help, and then we can more easily extract to separate functions if we think it will provide gain in readability. For example (code tested with unit tests):

> 1. grow touchpot renderable vector as needed (already there)
> 2. for each touch: set up and add renderable to scene
> 3. for unused renderables: remove from scene

unsigned int const num_touches = enabled ? touches.size() : 0;

while (touchspot_renderables.size() < num_touches)
    touchspot_renderables.push_back(std::make_shared<TouchspotRenderable>(touchspot_buffer));

// Update renderables used for touches
for (unsigned int i = 0; i < num_touches; ++i)
{
    auto const& renderable = touchspot_renderables[i];

    renderable->move_center_to(touches[i].touch_location);

    if (i >= renderables_in_use)
        scene->add_input_visualization(renderable);
}

// Update unused renderables
for (unsigned int i = num_touches; i < renderables_in_use; ++i)
    scene->remove_input_visualization(touchspot_renderables[i]);

renderables_in_use = num_touches;

Revision history for this message
Robert Carr (robertcarr) wrote :

Oh yeah thats much nicer...thanks alf.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Pushed a bunch of random cleanup.

Reflected on mg::BufferWriter v. mg::Buffer::write, decided to keep it as is after consulting the guideline:

Prefer non-member non-friend functions.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

1432 + * Copyright © 2012 Canonical Ltd.

Needs fixing: Wrong year.

1511 +++ src/server/input/touchspot_image.c

I know you already covered this, but given this is mostly a debug thing...What if we are asked to change the color...or the size...

I'd rather just have a dumb basic non-antialiased circle drawing routine (but I don't feel strongly about it so non-blocking).
    for(int y = -radius; y < radius; y++)
    {
        for(int x = -radius; x < radius; x++)
        {
            if( (x*x + y*y) <= radius_sq)
            {
                buffer.setpixel(radius + x, radius + y);
            }
        }
    }

2766 +
2767 + // Intended for input overlays, as described in mir::input::Scene documentation.
2768 + void add_input_visualization(std::shared_ptr<graphics::Renderable> const& overlay);
2769 + void remove_input_visualization(std::weak_ptr<graphics::Renderable> const& overlay);
2770 +
2771 + void emit_scene_changed() override;

I know covered already but seems like a strange interface addition for something named input::scene...But again don't feel too strongly about it since our scene interface is already wonky anyways...

review: Needs Fixing
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Looks good to me overall.

Minor stuff :

1472 +/// of touchspot renderables for visualization. Touchspot visualization
1473 +/// and must be enabled through a call to ::enable

Incorrect sentence in comment

1003 === modified file 'src/server/input/android/android_input_target_enumerator.cpp'

Should this file be renamed to something like android_scene_enumerator.cpp to reflect the input_target --> scene change?

1037 === modified file 'src/server/input/android/android_input_target_enumerator.h'

Ditto

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

Updated copyright and comments.

Alberto: I agree add/remove_input_visualization is strange. I'd rather see a "layers" API but still don't know how to implement it...

Non antialiased circle would be ok if the main other use weren't screen casting where having a nice antialiased ubuntu orange circle is worth something.

Cemil:

Fixed comment.

Wrt to android_input_target_enumerator, my thought is no, as the InputDispatcher doesn't deal in terms of scene. Perhaps the most accurate name would be AndroidInputWindowHandleEnumerator but I don't think that adds much.

Revision history for this message
Kevin DuBois (kdub) wrote :

looking good!

needs-fixings:
could some of the new files be 'private'?

c-cast:
537 + usage, top, left, width, height, (void**) &vaddr) )

mir::graphics::android::AndroidBufferWriter could just be mir::graphics::android::BufferWriter

suggestions:
enable()/disable() on touch visualizer seems a bit misplaced. Could the compositor just know whether it should draw visualizations or not and then call the visualize_touches according to what it wants to do?
The BufferWriters could also have a test.

Revision history for this message
Kevin DuBois (kdub) wrote :

well, looks good to me then!

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

kdub's comment reminded me a couple of other things that I had in mind but had forgotten by the time I finished reviewing :-). This MP will break the server ABI no matter what but let's try to minimize our exposure :

144 === renamed file 'src/include/server/mir/input/touch_visualizer.h' => 'include/server/mir/input/touch_visualizer.h'

Can this stay private please unless you'll be changing downstreams to use this functionality right away?

1 === added file 'include/platform/mir/graphics/buffer_writer.h'

Can we make this private for now?

Since we are messging with makefiles, symbols, etc., also, can you please make sure the 3 downstreams still build? Finding them out at release time is a real PITA.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

@Cemil,

The touch_visualizer.h header will be needed by this USC branch:
https://code.launchpad.net/~mir-team/unity-system-compositor/touchspot-toggling/+merge/233742

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

> @Cemil,
>
> The touch_visualizer.h header will be needed by this USC branch:
> https://code.launchpad.net/~mir-team/unity-system-compositor/touchspot-
> toggling/+merge/233742

O ok that's fine.

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

OK.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

ok

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(6) Server ABI broken, and needs bumping due to:
include/server/mir/default_server_configuration.h
include/server/mir/input/cursor_listener.h
etc.

Although you will probably find CI fails on any server ABI bump. We need to fix bug 1293944 to get past that.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Feel free to ignore my "Needs fixing" above if it causes too much grief. So long as we remember to:
  1. Bump MIRSERVER_ABI to 26 before branching/releasing 0.8.0; and
  2. Not backport this branch or any ABI breaks to 0.7;
then we're OK.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Fixed text conflicts.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2014-09-10 12:50:53 +0000
+++ debian/control 2014-09-18 16:04:44 +0000
@@ -60,7 +60,7 @@
60 .60 .
61 Contains the shared library needed by server applications for Mir.61 Contains the shared library needed by server applications for Mir.
6262
63Package: libmirplatform263Package: libmirplatform3
64Section: libs64Section: libs
65Architecture: i386 amd64 armhf arm6465Architecture: i386 amd64 armhf arm64
66Multi-Arch: same66Multi-Arch: same
@@ -123,7 +123,7 @@
123Architecture: i386 amd64 armhf arm64123Architecture: i386 amd64 armhf arm64
124Multi-Arch: same124Multi-Arch: same
125Pre-Depends: ${misc:Pre-Depends}125Pre-Depends: ${misc:Pre-Depends}
126Depends: libmirplatform2 (= ${binary:Version}), 126Depends: libmirplatform3 (= ${binary:Version}),
127 libmircommon-dev,127 libmircommon-dev,
128 libboost-program-options-dev,128 libboost-program-options-dev,
129 ${misc:Depends},129 ${misc:Depends},
130130
=== renamed file 'debian/libmirplatform2.install' => 'debian/libmirplatform3.install'
--- debian/libmirplatform2.install 2014-09-10 12:50:53 +0000
+++ debian/libmirplatform3.install 2014-09-18 16:04:44 +0000
@@ -1,1 +1,1 @@
1usr/lib/*/libmirplatform.so.21usr/lib/*/libmirplatform.so.3
22
=== modified file 'include/platform/mir/graphics/platform.h'
--- include/platform/mir/graphics/platform.h 2014-09-11 19:07:15 +0000
+++ include/platform/mir/graphics/platform.h 2014-09-18 16:04:44 +0000
@@ -53,6 +53,7 @@
53class GraphicBufferAllocator;53class GraphicBufferAllocator;
54class GLConfig;54class GLConfig;
55class GLProgramFactory;55class GLProgramFactory;
56class BufferWriter;
5657
57enum class BufferIpcMsgType58enum class BufferIpcMsgType
58{59{
@@ -86,6 +87,8 @@
8687
87 virtual std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(88 virtual std::shared_ptr<GraphicBufferAllocator> create_buffer_allocator(
88 std::shared_ptr<BufferInitializer> const& buffer_initializer) = 0;89 std::shared_ptr<BufferInitializer> const& buffer_initializer) = 0;
90
91 virtual std::shared_ptr<BufferWriter> make_buffer_writer() = 0;
8992
90 /**93 /**
91 * Creates the display subsystem.94 * Creates the display subsystem.
9295
=== modified file 'include/platform/mir/options/configuration.h'
--- include/platform/mir/options/configuration.h 2014-09-10 12:50:53 +0000
+++ include/platform/mir/options/configuration.h 2014-09-18 16:04:44 +0000
@@ -41,6 +41,7 @@
41extern char const* const input_report_opt;41extern char const* const input_report_opt;
42extern char const* const host_socket_opt;42extern char const* const host_socket_opt;
43extern char const* const frontend_threads_opt;43extern char const* const frontend_threads_opt;
44extern char const* const touchspots_opt;
44extern char const* const fatal_abort_opt;45extern char const* const fatal_abort_opt;
4546
46extern char const* const name_opt;47extern char const* const name_opt;
4748
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2014-09-10 12:50:53 +0000
+++ include/server/mir/default_server_configuration.h 2014-09-18 16:04:44 +0000
@@ -105,6 +105,7 @@
105class BufferInitializer;105class BufferInitializer;
106class DisplayReport;106class DisplayReport;
107class GraphicBufferAllocator;107class GraphicBufferAllocator;
108class BufferWriter;
108class Cursor;109class Cursor;
109class CursorImage;110class CursorImage;
110class GLConfig;111class GLConfig;
@@ -114,7 +115,7 @@
114namespace input115namespace input
115{116{
116class InputReport;117class InputReport;
117class InputTargets;118class Scene;
118class InputManager;119class InputManager;
119class CompositeEventFilter;120class CompositeEventFilter;
120class InputChannelFactory;121class InputChannelFactory;
@@ -214,6 +215,7 @@
214 * dependencies of compositor on the rest of the Mir215 * dependencies of compositor on the rest of the Mir
215 * @{ */216 * @{ */
216 virtual std::shared_ptr<graphics::GraphicBufferAllocator> the_buffer_allocator();217 virtual std::shared_ptr<graphics::GraphicBufferAllocator> the_buffer_allocator();
218 virtual std::shared_ptr<graphics::BufferWriter> the_buffer_writer();
217 virtual std::shared_ptr<compositor::Scene> the_scene();219 virtual std::shared_ptr<compositor::Scene> the_scene();
218 virtual std::shared_ptr<compositor::FrameDroppingPolicyFactory> the_frame_dropping_policy_factory();220 virtual std::shared_ptr<compositor::FrameDroppingPolicyFactory> the_frame_dropping_policy_factory();
219 /** @} */221 /** @} */
@@ -291,7 +293,7 @@
291 virtual std::shared_ptr<input::InputReport> the_input_report();293 virtual std::shared_ptr<input::InputReport> the_input_report();
292 virtual std::shared_ptr<input::CompositeEventFilter> the_composite_event_filter();294 virtual std::shared_ptr<input::CompositeEventFilter> the_composite_event_filter();
293 virtual std::shared_ptr<shell::InputTargeter> the_input_targeter();295 virtual std::shared_ptr<shell::InputTargeter> the_input_targeter();
294 virtual std::shared_ptr<input::InputTargets> the_input_targets();296 virtual std::shared_ptr<input::Scene> the_input_scene();
295 virtual std::shared_ptr<input::CursorListener> the_cursor_listener();297 virtual std::shared_ptr<input::CursorListener> the_cursor_listener();
296 virtual std::shared_ptr<input::TouchVisualizer> the_touch_visualizer();298 virtual std::shared_ptr<input::TouchVisualizer> the_touch_visualizer();
297 virtual std::shared_ptr<input::InputRegion> the_input_region();299 virtual std::shared_ptr<input::InputRegion> the_input_region();
@@ -359,6 +361,7 @@
359 CachedPtr<graphics::NativePlatform> graphics_native_platform;361 CachedPtr<graphics::NativePlatform> graphics_native_platform;
360 CachedPtr<graphics::BufferInitializer> buffer_initializer;362 CachedPtr<graphics::BufferInitializer> buffer_initializer;
361 CachedPtr<graphics::GraphicBufferAllocator> buffer_allocator;363 CachedPtr<graphics::GraphicBufferAllocator> buffer_allocator;
364 CachedPtr<graphics::BufferWriter> buffer_writer;
362 CachedPtr<graphics::Display> display;365 CachedPtr<graphics::Display> display;
363 CachedPtr<graphics::Cursor> cursor;366 CachedPtr<graphics::Cursor> cursor;
364 CachedPtr<graphics::CursorImage> default_cursor_image;367 CachedPtr<graphics::CursorImage> default_cursor_image;
365368
=== modified file 'include/server/mir/input/cursor_listener.h'
--- include/server/mir/input/cursor_listener.h 2013-04-30 20:44:31 +0000
+++ include/server/mir/input/cursor_listener.h 2014-09-18 16:04:44 +0000
@@ -35,8 +35,8 @@
3535
36protected:36protected:
37 CursorListener() = default;37 CursorListener() = default;
38 CursorListener(const CursorListener&) = delete;38 CursorListener(CursorListener const&) = delete;
39 CursorListener& operator=(const CursorListener&) = delete;39 CursorListener& operator=(CursorListener const&) = delete;
40};40};
4141
42}42}
4343
=== renamed file 'src/include/server/mir/input/touch_visualizer.h' => 'include/server/mir/input/touch_visualizer.h'
--- src/include/server/mir/input/touch_visualizer.h 2014-09-10 12:50:53 +0000
+++ include/server/mir/input/touch_visualizer.h 2014-09-18 16:04:44 +0000
@@ -39,11 +39,15 @@
39 {39 {
40 geometry::Point touch_location;40 geometry::Point touch_location;
41 41
42 // If pressure is non-zero, it indicates a press at the spot, as42 // If pressure is zero, the touch-point can be interpreted as a hover.
43 // opposed to a hover.
44 float pressure;43 float pressure;
45 };44 };
46 45
46 // Toggle visualization of touches
47 virtual void enable() = 0;
48 virtual void disable() = 0;
49
50 // Visualize a given set of touches statelessly.
47 virtual void visualize_touches(std::vector<Spot> const& touches) = 0;51 virtual void visualize_touches(std::vector<Spot> const& touches) = 0;
4852
49protected:53protected:
5054
=== modified file 'platform-ABI-sha1sums'
--- platform-ABI-sha1sums 2014-09-12 09:03:19 +0000
+++ platform-ABI-sha1sums 2014-09-18 16:04:44 +0000
@@ -31,9 +31,9 @@
31979d2c1ac723ccef538d9a378228a02b0f173bd7 include/platform/mir/graphics/graphic_buffer_allocator.h31979d2c1ac723ccef538d9a378228a02b0f173bd7 include/platform/mir/graphics/graphic_buffer_allocator.h
32f90a35371e236a6cfec8e9a8474dbb3305c7621e include/platform/mir/graphics/internal_client.h32f90a35371e236a6cfec8e9a8474dbb3305c7621e include/platform/mir/graphics/internal_client.h
33c9730cac4a3a101f9706ec6f444958abe047fd88 include/platform/mir/graphics/internal_surface.h33c9730cac4a3a101f9706ec6f444958abe047fd88 include/platform/mir/graphics/internal_surface.h
34656a7e1ae3b246930431a6174526fbdc2c76649e include/platform/mir/graphics/platform.h34c775727ea15fd8affa5b4dc9cd226d782e436001 include/platform/mir/graphics/platform.h
3515f201741a465de33e55ffc1ea775b507a5be950 include/platform/mir/graphics/renderable.h3515f201741a465de33e55ffc1ea775b507a5be950 include/platform/mir/graphics/renderable.h
36b0014e8c4f44f831c9d178f995efb172417aaee4 include/platform/mir/options/configuration.h36f5746dab3336266cfd410ce4e4d01333df6e5b99 include/platform/mir/options/configuration.h
3747007c783c174f8e94d332c4b13c6b01358b48fb include/platform/mir/options/default_configuration.h3747007c783c174f8e94d332c4b13c6b01358b48fb include/platform/mir/options/default_configuration.h
38b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h38b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h
393c37cc31e8b290b89c311d82f02e07d342766451 include/platform/mir/options/program_option.h393c37cc31e8b290b89c311d82f02e07d342766451 include/platform/mir/options/program_option.h
4040
=== modified file 'playground/demo-shell/demo_compositor.cpp'
--- playground/demo-shell/demo_compositor.cpp 2014-09-10 12:50:53 +0000
+++ playground/demo-shell/demo_compositor.cpp 2014-09-18 16:04:44 +0000
@@ -66,6 +66,8 @@
66 //the elements should be notified if they are rendered or not66 //the elements should be notified if they are rendered or not
67 bool nonrenderlist_elements{false};67 bool nonrenderlist_elements{false};
68 mg::RenderableList renderable_list;68 mg::RenderableList renderable_list;
69 std::unordered_set<mg::Renderable::ID> decoration_skip_list;
70
69 auto elements = scene->scene_elements_for(this);71 auto elements = scene->scene_elements_for(this);
70 for(auto const& it : elements)72 for(auto const& it : elements)
71 {73 {
@@ -73,6 +75,9 @@
73 auto const& view_area = display_buffer.view_area();75 auto const& view_area = display_buffer.view_area();
74 auto embellished = renderer.would_embellish(*renderable, view_area);76 auto embellished = renderer.would_embellish(*renderable, view_area);
75 auto any_part_drawn = (view_area.overlaps(renderable->screen_position()) || embellished);77 auto any_part_drawn = (view_area.overlaps(renderable->screen_position()) || embellished);
78
79 if (!it->is_a_surface())
80 decoration_skip_list.insert(renderable->id());
76 if (renderable->visible() && any_part_drawn)81 if (renderable->visible() && any_part_drawn)
77 {82 {
78 renderable_list.push_back(renderable);83 renderable_list.push_back(renderable);
@@ -96,7 +101,7 @@
96 display_buffer.make_current();101 display_buffer.make_current();
97102
98 renderer.set_rotation(display_buffer.orientation());103 renderer.set_rotation(display_buffer.orientation());
99 renderer.begin();104 renderer.begin(std::move(decoration_skip_list));
100 renderer.render(renderable_list);105 renderer.render(renderable_list);
101 display_buffer.post_update();106 display_buffer.post_update();
102 renderer.end();107 renderer.end();
103108
=== modified file 'playground/demo-shell/demo_renderer.cpp'
--- playground/demo-shell/demo_renderer.cpp 2014-09-10 12:50:53 +0000
+++ playground/demo-shell/demo_renderer.cpp 2014-09-18 16:04:44 +0000
@@ -171,7 +171,7 @@
171 glDeleteTextures(1, &titlebar_corner_tex);171 glDeleteTextures(1, &titlebar_corner_tex);
172}172}
173173
174void DemoRenderer::begin() const174void DemoRenderer::begin(std::unordered_set<graphics::Renderable::ID> decoration_skip_list_) const
175{175{
176 bool const opaque = destination_alpha() == compositor::DestinationAlpha::opaque;176 bool const opaque = destination_alpha() == compositor::DestinationAlpha::opaque;
177 if (opaque)177 if (opaque)
@@ -184,14 +184,19 @@
184184
185 if (opaque)185 if (opaque)
186 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);186 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
187
188 decoration_skip_list = decoration_skip_list_;
187}189}
188190
189void DemoRenderer::tessellate(std::vector<graphics::GLPrimitive>& primitives,191void DemoRenderer::tessellate(std::vector<graphics::GLPrimitive>& primitives,
190 graphics::Renderable const& renderable) const192 graphics::Renderable const& renderable) const
191{193{
192 GLRenderer::tessellate(primitives, renderable);194 GLRenderer::tessellate(primitives, renderable);
193 tessellate_shadow(primitives, renderable, shadow_radius);195 if (decoration_skip_list.find(renderable.id()) == decoration_skip_list.end())
194 tessellate_frame(primitives, renderable, titlebar_height);196 {
197 tessellate_shadow(primitives, renderable, shadow_radius);
198 tessellate_frame(primitives, renderable, titlebar_height);
199 }
195}200}
196201
197void DemoRenderer::tessellate_shadow(std::vector<graphics::GLPrimitive>& primitives,202void DemoRenderer::tessellate_shadow(std::vector<graphics::GLPrimitive>& primitives,
198203
=== modified file 'playground/demo-shell/demo_renderer.h'
--- playground/demo-shell/demo_renderer.h 2014-09-10 12:50:53 +0000
+++ playground/demo-shell/demo_renderer.h 2014-09-18 16:04:44 +0000
@@ -21,6 +21,8 @@
2121
22#include "mir/compositor/gl_renderer.h"22#include "mir/compositor/gl_renderer.h"
2323
24#include <unordered_set>
25
24namespace mir26namespace mir
25{27{
26namespace examples28namespace examples
@@ -37,7 +39,9 @@
37 float const shadow_radius);39 float const shadow_radius);
38 ~DemoRenderer();40 ~DemoRenderer();
3941
40 void begin() const override;42 void begin() const override { GLRenderer::begin(); }
43 void begin(std::unordered_set<graphics::Renderable::ID> renderables_not_to_decorate) const;
44
41 void tessellate(45 void tessellate(
42 std::vector<graphics::GLPrimitive>& primitives,46 std::vector<graphics::GLPrimitive>& primitives,
43 graphics::Renderable const& renderable) const override;47 graphics::Renderable const& renderable) const override;
@@ -59,6 +63,8 @@
59 float const corner_radius;63 float const corner_radius;
60 GLuint shadow_corner_tex;64 GLuint shadow_corner_tex;
61 GLuint titlebar_corner_tex;65 GLuint titlebar_corner_tex;
66
67 mutable std::unordered_set<graphics::Renderable::ID> decoration_skip_list;
62};68};
6369
64} // namespace examples70} // namespace examples
6571
=== modified file 'server-ABI-sha1sums'
--- server-ABI-sha1sums 2014-09-12 09:03:19 +0000
+++ server-ABI-sha1sums 2014-09-18 16:04:44 +0000
@@ -31,14 +31,14 @@
31979d2c1ac723ccef538d9a378228a02b0f173bd7 include/platform/mir/graphics/graphic_buffer_allocator.h31979d2c1ac723ccef538d9a378228a02b0f173bd7 include/platform/mir/graphics/graphic_buffer_allocator.h
32f90a35371e236a6cfec8e9a8474dbb3305c7621e include/platform/mir/graphics/internal_client.h32f90a35371e236a6cfec8e9a8474dbb3305c7621e include/platform/mir/graphics/internal_client.h
33c9730cac4a3a101f9706ec6f444958abe047fd88 include/platform/mir/graphics/internal_surface.h33c9730cac4a3a101f9706ec6f444958abe047fd88 include/platform/mir/graphics/internal_surface.h
34656a7e1ae3b246930431a6174526fbdc2c76649e include/platform/mir/graphics/platform.h34c775727ea15fd8affa5b4dc9cd226d782e436001 include/platform/mir/graphics/platform.h
3515f201741a465de33e55ffc1ea775b507a5be950 include/platform/mir/graphics/renderable.h3515f201741a465de33e55ffc1ea775b507a5be950 include/platform/mir/graphics/renderable.h
36b0014e8c4f44f831c9d178f995efb172417aaee4 include/platform/mir/options/configuration.h36f5746dab3336266cfd410ce4e4d01333df6e5b99 include/platform/mir/options/configuration.h
3747007c783c174f8e94d332c4b13c6b01358b48fb include/platform/mir/options/default_configuration.h3747007c783c174f8e94d332c4b13c6b01358b48fb include/platform/mir/options/default_configuration.h
38b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h38b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h
393c37cc31e8b290b89c311d82f02e07d342766451 include/platform/mir/options/program_option.h393c37cc31e8b290b89c311d82f02e07d342766451 include/platform/mir/options/program_option.h
40f4030e400baf8baa9c38e7c6ec6b4a5ad7134aeb include/server/mir/compositor/compositor.h40f4030e400baf8baa9c38e7c6ec6b4a5ad7134aeb include/server/mir/compositor/compositor.h
41f102d38fd8afd63b636d76005f9b80f3adda0858 include/server/mir/default_server_configuration.h41ef0b6f26fb40a72e4a4744e4d9c4bd044142de47 include/server/mir/default_server_configuration.h
42af1ff0714be973ac76d56006a2e5991f68cd1dec include/server/mir/display_server.h42af1ff0714be973ac76d56006a2e5991f68cd1dec include/server/mir/display_server.h
4365db331f1c0e956eced5c9fc73a2b2122dbc8dc7 include/server/mir/frontend/connection_creator.h4365db331f1c0e956eced5c9fc73a2b2122dbc8dc7 include/server/mir/frontend/connection_creator.h
44e6e92642301fc9bb85e1d38087a5dd84e5d30fd7 include/server/mir/frontend/connections.h44e6e92642301fc9bb85e1d38087a5dd84e5d30fd7 include/server/mir/frontend/connections.h
@@ -55,12 +55,13 @@
55618b43a84cce0ad671ed68fe2ba796fbc7b79e31 include/server/mir/frontend/surface_id.h55618b43a84cce0ad671ed68fe2ba796fbc7b79e31 include/server/mir/frontend/surface_id.h
565aa4c4db5468d9b9fe8e98a64444538aadd6e17b include/server/mir/frontend/template_protobuf_message_processor.h565aa4c4db5468d9b9fe8e98a64444538aadd6e17b include/server/mir/frontend/template_protobuf_message_processor.h
57f95c2bddf13d15993ef5d6a0ad7b9106ae550b87 include/server/mir/input/composite_event_filter.h57f95c2bddf13d15993ef5d6a0ad7b9106ae550b87 include/server/mir/input/composite_event_filter.h
58c1e96c372d7856d59947f3145d273b1285b569bc include/server/mir/input/cursor_listener.h58cef18b7215fbe00550d18c0aa0f79b641cff494e include/server/mir/input/cursor_listener.h
592331fc402686e862809bf24714a8746cdde97cb1 include/server/mir/input/event_filter.h592331fc402686e862809bf24714a8746cdde97cb1 include/server/mir/input/event_filter.h
6078862dda41d56c6b937a1ed197982e5fa37f50df include/server/mir/input/input_channel.h6078862dda41d56c6b937a1ed197982e5fa37f50df include/server/mir/input/input_channel.h
616f1d9cf83bbb1256f0b4d1ba1d94d95af98c52f0 include/server/mir/input/input_dispatcher.h616f1d9cf83bbb1256f0b4d1ba1d94d95af98c52f0 include/server/mir/input/input_dispatcher.h
62b2ec497c6bec1b3a67c991f31cc7b7c51050ecbb include/server/mir/input/input_reception_mode.h62b2ec497c6bec1b3a67c991f31cc7b7c51050ecbb include/server/mir/input/input_reception_mode.h
6315119bf95b4512c8b91df7c20edf56a3c0734957 include/server/mir/input/surface.h6315119bf95b4512c8b91df7c20edf56a3c0734957 include/server/mir/input/surface.h
64036f3967757873751fcacaa768ca11a52001c225 include/server/mir/input/touch_visualizer.h
64964069b241f1e8211386bb8735ee0f752b666949 include/server/mir/main_loop.h65964069b241f1e8211386bb8735ee0f752b666949 include/server/mir/main_loop.h
65edd5a0a6be0be57ef64c5af89fc5a65dc558648c include/server/mir/report_exception.h66edd5a0a6be0be57ef64c5af89fc5a65dc558648c include/server/mir/report_exception.h
668192727cf5fa0b2b5798b2211c2c8a4ad65c9f60 include/server/mir/run_mir.h678192727cf5fa0b2b5798b2211c2c8a4ad65c9f60 include/server/mir/run_mir.h
6768
=== added file 'src/include/platform/mir/graphics/buffer_writer.h'
--- src/include/platform/mir/graphics/buffer_writer.h 1970-01-01 00:00:00 +0000
+++ src/include/platform/mir/graphics/buffer_writer.h 2014-09-18 16:04:44 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#include <cstddef>
20
21namespace mir
22{
23namespace graphics
24{
25class Buffer;
26
27/// An interface provided by the graphics platform allowing for writing untiled pixel data into buffers.
28class BufferWriter
29{
30public:
31 virtual ~BufferWriter() = default;
32
33 // Expects data to be an unstrided array containing (buffer.width * buffer.height) pixels. Likewise
34 // it is expected that buffer and data match in pixel format.
35 virtual void write(Buffer& buffer, unsigned char const* data, size_t size) = 0;
36
37protected:
38 BufferWriter() = default;
39 BufferWriter(BufferWriter const&) = delete;
40 BufferWriter& operator=(BufferWriter const&) = delete;
41};
42
43}
44}
045
=== modified file 'src/include/platform/mir/graphics/native_platform.h'
--- src/include/platform/mir/graphics/native_platform.h 2014-09-10 12:50:53 +0000
+++ src/include/platform/mir/graphics/native_platform.h 2014-09-18 16:04:44 +0000
@@ -36,6 +36,7 @@
36class InternalClient;36class InternalClient;
37class BufferIPCPacker;37class BufferIPCPacker;
38class Buffer;38class Buffer;
39class BufferWriter;
39class DisplayReport;40class DisplayReport;
40class NestedContext;41class NestedContext;
4142
@@ -58,6 +59,8 @@
58 Buffer const* buffer,59 Buffer const* buffer,
59 BufferIpcMsgType msg_type) const = 0;60 BufferIpcMsgType msg_type) const = 0;
6061
62 virtual std::shared_ptr<BufferWriter> make_buffer_writer() = 0;
63
61 virtual ~NativePlatform() = default;64 virtual ~NativePlatform() = default;
62 NativePlatform(NativePlatform const&) = delete;65 NativePlatform(NativePlatform const&) = delete;
63 NativePlatform& operator=(NativePlatform const&) = delete;66 NativePlatform& operator=(NativePlatform const&) = delete;
6467
=== modified file 'src/include/server/mir/compositor/scene_element.h'
--- src/include/server/mir/compositor/scene_element.h 2014-09-10 12:50:53 +0000
+++ src/include/server/mir/compositor/scene_element.h 2014-09-18 16:04:44 +0000
@@ -39,6 +39,10 @@
39 virtual std::shared_ptr<graphics::Renderable> renderable() const = 0;39 virtual std::shared_ptr<graphics::Renderable> renderable() const = 0;
40 virtual void rendered_in(CompositorID cid) = 0;40 virtual void rendered_in(CompositorID cid) = 0;
41 virtual void occluded_in(CompositorID cid) = 0;41 virtual void occluded_in(CompositorID cid) = 0;
42
43 // Query whether the SceneElement represents a window-surface, which at the discretion of the compositor
44 // may be eligible for window decoration.
45 virtual bool is_a_surface() const = 0;
4246
43protected:47protected:
44 SceneElement() = default;48 SceneElement() = default;
4549
=== renamed file 'src/include/server/mir/input/input_targets.h' => 'src/include/server/mir/input/scene.h'
--- src/include/server/mir/input/input_targets.h 2014-09-10 12:50:53 +0000
+++ src/include/server/mir/input/scene.h 2014-09-18 16:04:44 +0000
@@ -17,8 +17,8 @@
17 * Daniel d'Andradra <daniel.dandrada@canonical.com>17 * Daniel d'Andradra <daniel.dandrada@canonical.com>
18 */18 */
1919
20#ifndef MIR_INPUT_INPUT_TARGETS_H_20#ifndef MIR_INPUT_INPUT_SCENE_H_
21#define MIR_INPUT_INPUT_TARGETS_H_21#define MIR_INPUT_INPUT_SCENE_H_
2222
23#include "mir/input/input_channel_factory.h"23#include "mir/input/input_channel_factory.h"
2424
@@ -30,28 +30,43 @@
30{30{
31class Observer;31class Observer;
32}32}
33namespace graphics
34{
35class Renderable;
36}
3337
34namespace input38namespace input
35{39{
36class Surface;40class Surface;
3741
38class InputTargets42class Scene
39{43{
40public:44public:
41 virtual ~InputTargets() = default;45 virtual ~Scene() = default;
4246
43 virtual void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& callback) = 0;47 virtual void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& callback) = 0;
4448
45 virtual void add_observer(std::shared_ptr<scene::Observer> const& observer) = 0;49 virtual void add_observer(std::shared_ptr<scene::Observer> const& observer) = 0;
46 virtual void remove_observer(std::weak_ptr<scene::Observer> const& observer) = 0;50 virtual void remove_observer(std::weak_ptr<scene::Observer> const& observer) = 0;
4751
52 // An interface which the input stack can use to add certain non interactive input visualizations
53 // in to the scene (i.e. cursors, touchspots). Overlay renderables will be rendered above all surfaces.
54 // Within the set of overlay renderables, rendering order is undefined.
55 virtual void add_input_visualization(std::shared_ptr<graphics::Renderable> const& overlay) = 0;
56 virtual void remove_input_visualization(std::weak_ptr<graphics::Renderable> const& overlay) = 0;
57
58 // As input visualizations added through the overlay system will not use the standard SurfaceObserver
59 // mechanism, we require this method to trigger recomposition.
60 // TODO: How can something like SurfaceObserver be adapted to work with non surface renderables?
61 virtual void emit_scene_changed() = 0;
62
48protected:63protected:
49 InputTargets() = default;64 Scene() = default;
50 InputTargets(InputTargets const&) = delete;65 Scene(Scene const&) = delete;
51 InputTargets& operator=(InputTargets const&) = delete;66 Scene& operator=(Scene const&) = delete;
52};67};
5368
54}69}
55}70}
5671
57#endif // MIR_INPUT_INPUT_TARGETS72#endif // MIR_INPUT_INPUT_SCENE
5873
=== modified file 'src/include/server/mir/scene/legacy_scene_change_notification.h'
--- src/include/server/mir/scene/legacy_scene_change_notification.h 2014-09-10 12:50:53 +0000
+++ src/include/server/mir/scene/legacy_scene_change_notification.h 2014-09-18 16:04:44 +0000
@@ -45,6 +45,8 @@
45 void surface_added(Surface* surface) override;45 void surface_added(Surface* surface) override;
46 void surface_removed(Surface* surface) override;46 void surface_removed(Surface* surface) override;
47 void surfaces_reordered() override;47 void surfaces_reordered() override;
48
49 void scene_changed() override;
4850
49 void surface_exists(Surface* surface) override;51 void surface_exists(Surface* surface) override;
50 void end_observation() override;52 void end_observation() override;
5153
=== modified file 'src/include/server/mir/scene/observer.h'
--- src/include/server/mir/scene/observer.h 2014-09-10 12:50:53 +0000
+++ src/include/server/mir/scene/observer.h 2014-09-18 16:04:44 +0000
@@ -36,6 +36,10 @@
36 virtual void surface_added(Surface* surface) = 0;36 virtual void surface_added(Surface* surface) = 0;
37 virtual void surface_removed(Surface* surface) = 0;37 virtual void surface_removed(Surface* surface) = 0;
38 virtual void surfaces_reordered() = 0;38 virtual void surfaces_reordered() = 0;
39
40 // Used to indicate the scene has changed in some way beyond the present surfaces
41 // and will require full recomposition.
42 virtual void scene_changed() = 0;
3943
40 // Called at observer registration to notify of already existing surfaces.44 // Called at observer registration to notify of already existing surfaces.
41 virtual void surface_exists(Surface* surface) = 0;45 virtual void surface_exists(Surface* surface) = 0;
4246
=== modified file 'src/platform/CMakeLists.txt'
--- src/platform/CMakeLists.txt 2014-09-10 13:27:58 +0000
+++ src/platform/CMakeLists.txt 2014-09-18 16:04:44 +0000
@@ -3,7 +3,7 @@
3 ${PROJECT_SOURCE_DIR}/src/include/platform3 ${PROJECT_SOURCE_DIR}/src/include/platform
4)4)
55
6set(MIRPLATFORM_ABI 2)6set(MIRPLATFORM_ABI 3)
77
8set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)8set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)
99
1010
=== modified file 'src/platform/graphics/android/CMakeLists.txt'
--- src/platform/graphics/android/CMakeLists.txt 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/android/CMakeLists.txt 2014-09-18 16:04:44 +0000
@@ -35,6 +35,7 @@
35 device_quirks.cpp35 device_quirks.cpp
36 real_hwc_wrapper.cpp36 real_hwc_wrapper.cpp
37 hwc_fallback_gl_renderer.cpp37 hwc_fallback_gl_renderer.cpp
38 android_buffer_writer.cpp
38)39)
39add_library(mirplatformgraphicsandroid SHARED40add_library(mirplatformgraphicsandroid SHARED
40 $<TARGET_OBJECTS:mirplatformgraphicsandroidobjects>41 $<TARGET_OBJECTS:mirplatformgraphicsandroidobjects>
4142
=== added file 'src/platform/graphics/android/android_buffer_writer.cpp'
--- src/platform/graphics/android/android_buffer_writer.cpp 1970-01-01 00:00:00 +0000
+++ src/platform/graphics/android/android_buffer_writer.cpp 2014-09-18 16:04:44 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Robert Carr <robert.carr@canonical.com>
18 */
19
20#include "android_buffer_writer.h"
21#include "buffer.h"
22
23#include "mir/graphics/android/android_native_buffer.h"
24
25#include <hardware/hardware.h>
26
27#include <boost/throw_exception.hpp>
28#include <stdexcept>
29
30#include <string.h>
31
32namespace mg = mir::graphics;
33namespace mga = mg::android;
34
35mga::BufferWriter::BufferWriter()
36{
37 auto err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const **)(&hw_module));
38 if (err < 0)
39 BOOST_THROW_EXCEPTION(std::runtime_error("Could not open hardware module"));
40}
41
42void mga::BufferWriter::write(mg::Buffer& buffer, unsigned char const* data, size_t size)
43{
44 auto buffer_size = buffer.size();
45 auto bpp = MIR_BYTES_PER_PIXEL(buffer.pixel_format());
46 if (bpp * buffer_size.width.as_uint32_t() * buffer_size.height.as_uint32_t() != size)
47 BOOST_THROW_EXCEPTION(std::logic_error("Size of pixels is not equal to size of buffer"));
48
49 auto const& handle = buffer.native_buffer_handle();
50
51 char* vaddr;
52 int usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
53 int width = buffer.size().width.as_uint32_t();
54 int height = buffer.size().height.as_uint32_t();
55 int top = 0;
56 int left = 0;
57 if ( hw_module->lock(hw_module, handle->handle(),
58 usage, top, left, width, height, reinterpret_cast<void**>(&vaddr)) )
59 BOOST_THROW_EXCEPTION(std::runtime_error("error securing buffer for client cpu use"));
60
61 // Copy line by line in case of stride != width*bpp
62 for (int i = 0; i < height; i++)
63 {
64 int line_offset_in_buffer = buffer.stride().as_uint32_t()*i;
65 int line_offset_in_source = bpp*width*i;
66 memcpy(vaddr + line_offset_in_buffer, data + line_offset_in_source, width * bpp);
67 }
68
69 hw_module->unlock(hw_module, handle->handle());
70}
071
=== added file 'src/platform/graphics/android/android_buffer_writer.h'
--- src/platform/graphics/android/android_buffer_writer.h 1970-01-01 00:00:00 +0000
+++ src/platform/graphics/android/android_buffer_writer.h 2014-09-18 16:04:44 +0000
@@ -0,0 +1,50 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by:
17 * Robert Carr <robert.carr@canonical.com>
18 */
19
20#ifndef MIR_PLATFORM_ANDROID_ANDROID_BUFFER_WRITER_H_
21#define MIR_PLATFORM_ANDROID_ANDROID_BUFFER_WRITER_H_
22
23#include "mir/graphics/buffer_writer.h"
24
25#include <hardware/gralloc.h>
26
27#include <memory>
28
29namespace mir
30{
31namespace graphics
32{
33namespace android
34{
35
36class BufferWriter : public graphics::BufferWriter
37{
38public:
39 BufferWriter();
40
41 void write(graphics::Buffer& buffer, unsigned char const* pixels, size_t size) override;
42private:
43 gralloc_module_t const* hw_module;
44};
45
46}
47}
48}
49
50#endif /* MIR_PLATFORM_ANDROID_ANDROID_BUFFER_WRITER_H_ */
051
=== modified file 'src/platform/graphics/android/android_display.cpp'
--- src/platform/graphics/android/android_display.cpp 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/android/android_display.cpp 2014-09-18 16:04:44 +0000
@@ -103,7 +103,7 @@
103103
104auto mga::AndroidDisplay::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& /* initial_image */) -> std::shared_ptr<Cursor>104auto mga::AndroidDisplay::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& /* initial_image */) -> std::shared_ptr<Cursor>
105{105{
106 return std::shared_ptr<Cursor>();106 return nullptr;
107}107}
108108
109std::unique_ptr<mg::GLContext> mga::AndroidDisplay::create_gl_context()109std::unique_ptr<mg::GLContext> mga::AndroidDisplay::create_gl_context()
110110
=== modified file 'src/platform/graphics/android/android_platform.cpp'
--- src/platform/graphics/android/android_platform.cpp 2014-09-15 18:58:24 +0000
+++ src/platform/graphics/android/android_platform.cpp 2014-09-18 16:04:44 +0000
@@ -24,6 +24,7 @@
24#include "android_display.h"24#include "android_display.h"
25#include "internal_client.h"25#include "internal_client.h"
26#include "output_builder.h"26#include "output_builder.h"
27#include "android_buffer_writer.h"
27#include "hwc_loggers.h"28#include "hwc_loggers.h"
28#include "mir/graphics/platform_ipc_package.h"29#include "mir/graphics/platform_ipc_package.h"
29#include "mir/graphics/android/native_buffer.h"30#include "mir/graphics/android/native_buffer.h"
@@ -153,6 +154,11 @@
153 return std::make_shared<mga::InternalClient>();154 return std::make_shared<mga::InternalClient>();
154}155}
155156
157std::shared_ptr<mg::BufferWriter> mga::AndroidPlatform::make_buffer_writer()
158{
159 return std::make_shared<mga::BufferWriter>();
160}
161
156extern "C" std::shared_ptr<mg::Platform> mg::create_platform(162extern "C" std::shared_ptr<mg::Platform> mg::create_platform(
157 std::shared_ptr<mo::Option> const& options,163 std::shared_ptr<mo::Option> const& options,
158 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,164 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
159165
=== modified file 'src/platform/graphics/android/android_platform.h'
--- src/platform/graphics/android/android_platform.h 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/android/android_platform.h 2014-09-18 16:04:44 +0000
@@ -49,6 +49,7 @@
49 std::shared_ptr<graphics::GLConfig> const& /*gl_config*/);49 std::shared_ptr<graphics::GLConfig> const& /*gl_config*/);
50 std::shared_ptr<PlatformIPCPackage> get_ipc_package();50 std::shared_ptr<PlatformIPCPackage> get_ipc_package();
51 std::shared_ptr<InternalClient> create_internal_client();51 std::shared_ptr<InternalClient> create_internal_client();
52 std::shared_ptr<graphics::BufferWriter> make_buffer_writer() override;
52 void fill_buffer_package(53 void fill_buffer_package(
53 BufferIPCPacker* packer, graphics::Buffer const* buffer, BufferIpcMsgType msg_type) const;54 BufferIPCPacker* packer, graphics::Buffer const* buffer, BufferIpcMsgType msg_type) const;
54 EGLNativeDisplayType egl_native_display() const;55 EGLNativeDisplayType egl_native_display() const;
5556
=== modified file 'src/platform/graphics/mesa/CMakeLists.txt'
--- src/platform/graphics/mesa/CMakeLists.txt 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/CMakeLists.txt 2014-09-18 16:04:44 +0000
@@ -33,6 +33,7 @@
33 anonymous_shm_file.cpp33 anonymous_shm_file.cpp
34 shm_buffer.cpp34 shm_buffer.cpp
35 bypass.cpp35 bypass.cpp
36 buffer_writer.cpp
36)37)
3738
38add_library(mirplatformgraphicsmesa SHARED39add_library(mirplatformgraphicsmesa SHARED
3940
=== modified file 'src/platform/graphics/mesa/buffer_allocator.cpp'
--- src/platform/graphics/mesa/buffer_allocator.cpp 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/buffer_allocator.cpp 2014-09-18 16:04:44 +0000
@@ -39,7 +39,7 @@
39#include <cassert>39#include <cassert>
4040
41namespace mg = mir::graphics;41namespace mg = mir::graphics;
42namespace mgm = mir::graphics::mesa;42namespace mgm = mg::mesa;
43namespace geom = mir::geometry;43namespace geom = mir::geometry;
4444
45namespace45namespace
4646
=== added file 'src/platform/graphics/mesa/buffer_writer.cpp'
--- src/platform/graphics/mesa/buffer_writer.cpp 1970-01-01 00:00:00 +0000
+++ src/platform/graphics/mesa/buffer_writer.cpp 2014-09-18 16:04:44 +0000
@@ -0,0 +1,40 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#include "buffer_writer.h"
20
21#include "shm_buffer.h"
22
23#include <boost/throw_exception.hpp>
24#include <stdexcept>
25
26namespace mg = mir::graphics;
27namespace mgm = mir::graphics::mesa;
28
29mgm::BufferWriter::BufferWriter()
30{
31}
32
33void mgm::BufferWriter::write(mg::Buffer& buffer, unsigned char const* data, size_t size)
34{
35 auto shm_buffer = dynamic_cast<mgm::ShmBuffer*>(&buffer);
36 if (!shm_buffer)
37 BOOST_THROW_EXCEPTION(std::logic_error("Direct CPU write is only supported to software allocated buffers on mesa platform"));
38
39 shm_buffer->write(data, size);
40}
041
=== added file 'src/platform/graphics/mesa/buffer_writer.h'
--- src/platform/graphics/mesa/buffer_writer.h 1970-01-01 00:00:00 +0000
+++ src/platform/graphics/mesa/buffer_writer.h 2014-09-18 16:04:44 +0000
@@ -0,0 +1,43 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_GRAPHICS_MESA_BUFFER_WRITER_H_
20#define MIR_GRAPHICS_MESA_BUFFER_WRITER_H_
21
22#include "mir/graphics/buffer_writer.h"
23
24namespace mir
25{
26namespace graphics
27{
28class Buffer;
29
30namespace mesa
31{
32class BufferWriter : public graphics::BufferWriter
33{
34public:
35 BufferWriter();
36
37 void write(graphics::Buffer& buffer, unsigned char const* data, size_t size) override;
38};
39}
40}
41}
42
43#endif // MIR_GRAPHICS_MESA_BUFFER_WRITER_H_
044
=== modified file 'src/platform/graphics/mesa/native_platform.cpp'
--- src/platform/graphics/mesa/native_platform.cpp 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/native_platform.cpp 2014-09-18 16:04:44 +0000
@@ -21,6 +21,7 @@
21#include "native_platform.h"21#include "native_platform.h"
2222
23#include "buffer_allocator.h"23#include "buffer_allocator.h"
24#include "buffer_writer.h"
24#include "mir/graphics/buffer_ipc_packer.h"25#include "mir/graphics/buffer_ipc_packer.h"
25#include "mir/graphics/platform_ipc_package.h"26#include "mir/graphics/platform_ipc_package.h"
26#include "mir/graphics/nested_context.h"27#include "mir/graphics/nested_context.h"
@@ -157,3 +158,7 @@
157 native_display.reset();158 native_display.reset();
158}159}
159160
161std::shared_ptr<mg::BufferWriter> mgm::NativePlatform::make_buffer_writer()
162{
163 return std::make_shared<mgm::BufferWriter>();
164}
160165
=== modified file 'src/platform/graphics/mesa/native_platform.h'
--- src/platform/graphics/mesa/native_platform.h 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/native_platform.h 2014-09-18 16:04:44 +0000
@@ -44,6 +44,7 @@
44 std::shared_ptr<InternalClient> create_internal_client() override;44 std::shared_ptr<InternalClient> create_internal_client() override;
45 void fill_buffer_package(45 void fill_buffer_package(
46 BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const override;46 BufferIPCPacker* packer, Buffer const* buffer, BufferIpcMsgType msg_type) const override;
47 std::shared_ptr<graphics::BufferWriter> make_buffer_writer() override;
47 48
48 static std::shared_ptr<InternalNativeDisplay> internal_native_display();49 static std::shared_ptr<InternalNativeDisplay> internal_native_display();
49 static bool internal_native_display_in_use();50 static bool internal_native_display_in_use();
5051
=== modified file 'src/platform/graphics/mesa/platform.cpp'
--- src/platform/graphics/mesa/platform.cpp 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/platform.cpp 2014-09-18 16:04:44 +0000
@@ -23,6 +23,7 @@
23#include "internal_client.h"23#include "internal_client.h"
24#include "internal_native_display.h"24#include "internal_native_display.h"
25#include "linux_virtual_terminal.h"25#include "linux_virtual_terminal.h"
26#include "buffer_writer.h"
26#include "mir/graphics/platform_ipc_package.h"27#include "mir/graphics/platform_ipc_package.h"
27#include "mir/graphics/buffer_ipc_packer.h"28#include "mir/graphics/buffer_ipc_packer.h"
28#include "mir/options/option.h"29#include "mir/options/option.h"
@@ -216,6 +217,11 @@
216 return std::make_shared<mgm::InternalClient>(internal_native_display);217 return std::make_shared<mgm::InternalClient>(internal_native_display);
217}218}
218219
220std::shared_ptr<mg::BufferWriter> mgm::Platform::make_buffer_writer()
221{
222 return std::make_shared<mgm::BufferWriter>();
223}
224
219EGLNativeDisplayType mgm::Platform::egl_native_display() const225EGLNativeDisplayType mgm::Platform::egl_native_display() const
220{226{
221 return gbm.device;227 return gbm.device;
222228
=== modified file 'src/platform/graphics/mesa/platform.h'
--- src/platform/graphics/mesa/platform.h 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/platform.h 2014-09-18 16:04:44 +0000
@@ -54,6 +54,7 @@
54 /* From Platform */54 /* From Platform */
55 std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator(55 std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator(
56 const std::shared_ptr<BufferInitializer>& buffer_initializer);56 const std::shared_ptr<BufferInitializer>& buffer_initializer);
57 std::shared_ptr<graphics::BufferWriter> make_buffer_writer();
57 std::shared_ptr<graphics::Display> create_display(58 std::shared_ptr<graphics::Display> create_display(
58 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,59 std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy,
59 std::shared_ptr<GLProgramFactory> const& program_factory,60 std::shared_ptr<GLProgramFactory> const& program_factory,
6061
=== modified file 'src/platform/graphics/mesa/shm_buffer.cpp'
--- src/platform/graphics/mesa/shm_buffer.cpp 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/shm_buffer.cpp 2014-09-18 16:04:44 +0000
@@ -23,6 +23,12 @@
23#include <GLES2/gl2.h>23#include <GLES2/gl2.h>
24#include <GLES2/gl2ext.h>24#include <GLES2/gl2ext.h>
2525
26#include <boost/throw_exception.hpp>
27
28#include <stdexcept>
29
30#include <string.h>
31
26namespace mgm = mir::graphics::mesa;32namespace mgm = mir::graphics::mesa;
27namespace geom = mir::geometry;33namespace geom = mir::geometry;
2834
@@ -85,3 +91,10 @@
85{91{
86 return false;92 return false;
87}93}
94
95void mgm::ShmBuffer::write(unsigned char const* data, size_t data_size)
96{
97 if (data_size != stride_.as_uint32_t()*size().height.as_uint32_t())
98 BOOST_THROW_EXCEPTION(std::logic_error("Size is not equal to number of pixels in buffer"));
99 memcpy(pixels, data, data_size);
100}
88101
=== modified file 'src/platform/graphics/mesa/shm_buffer.h'
--- src/platform/graphics/mesa/shm_buffer.h 2014-09-10 12:50:53 +0000
+++ src/platform/graphics/mesa/shm_buffer.h 2014-09-18 16:04:44 +0000
@@ -49,6 +49,8 @@
49 void gl_bind_to_texture() override;49 void gl_bind_to_texture() override;
50 bool can_bypass() const;50 bool can_bypass() const;
5151
52 void write(unsigned char const* data, size_t size);
53
52private:54private:
53 ShmBuffer(ShmBuffer const&) = delete;55 ShmBuffer(ShmBuffer const&) = delete;
54 ShmBuffer& operator=(ShmBuffer const&) = delete;56 ShmBuffer& operator=(ShmBuffer const&) = delete;
5557
=== modified file 'src/platform/options/default_configuration.cpp'
--- src/platform/options/default_configuration.cpp 2014-09-10 12:50:53 +0000
+++ src/platform/options/default_configuration.cpp 2014-09-18 16:04:44 +0000
@@ -43,9 +43,9 @@
43char const* const mo::frontend_threads_opt = "ipc-thread-pool";43char const* const mo::frontend_threads_opt = "ipc-thread-pool";
44char const* const mo::name_opt = "name";44char const* const mo::name_opt = "name";
45char const* const mo::offscreen_opt = "offscreen";45char const* const mo::offscreen_opt = "offscreen";
46char const* const mo::touchspots_opt = "enable-touchspots";
46char const* const mo::fatal_abort_opt = "on-fatal-error-abort";47char const* const mo::fatal_abort_opt = "on-fatal-error-abort";
4748
48
49char const* const mo::glog = "glog";49char const* const mo::glog = "glog";
50char const* const mo::glog_stderrthreshold = "glog-stderrthreshold";50char const* const mo::glog_stderrthreshold = "glog-stderrthreshold";
51char const* const mo::glog_minloglevel = "glog-minloglevel";51char const* const mo::glog_minloglevel = "glog-minloglevel";
@@ -161,6 +161,8 @@
161 "When nested, the name Mir uses when registering with the host.")161 "When nested, the name Mir uses when registering with the host.")
162 (offscreen_opt,162 (offscreen_opt,
163 "Render to offscreen buffers instead of the real outputs.")163 "Render to offscreen buffers instead of the real outputs.")
164 (touchspots_opt,
165 "Display visualization of touchspots (e.g. for screencasting).")
164 (fatal_abort_opt, "On \"fatal error\" conditions [e.g. drivers behaving "166 (fatal_abort_opt, "On \"fatal error\" conditions [e.g. drivers behaving "
165 "in unexpected ways] abort (to get a core dump)");167 "in unexpected ways] abort (to get a core dump)");
166168
167169
=== modified file 'src/platform/symbols.map'
--- src/platform/symbols.map 2014-09-10 12:50:53 +0000
+++ src/platform/symbols.map 2014-09-18 16:04:44 +0000
@@ -1,4 +1,4 @@
1MIRPLATFORM_2 {1MIRPLATFORM_3 {
2 global:2 global:
3 extern "C++" {3 extern "C++" {
4# The following symbols come from running a script over the generated docs. Vis:4# The following symbols come from running a script over the generated docs. Vis:
@@ -252,6 +252,7 @@
252 mir::options::scene_report_opt*;252 mir::options::scene_report_opt*;
253 mir::options::server_socket_opt*;253 mir::options::server_socket_opt*;
254 mir::options::session_mediator_report_opt*;254 mir::options::session_mediator_report_opt*;
255 mir::options::touchspots_opt*;
255 typeinfo?for?mir::AbnormalExit;256 typeinfo?for?mir::AbnormalExit;
256 typeinfo?for?mir::EmergencyCleanupRegistry;257 typeinfo?for?mir::EmergencyCleanupRegistry;
257 typeinfo?for?mir::FatalErrorStrategy;258 typeinfo?for?mir::FatalErrorStrategy;
258259
=== modified file 'src/server/graphics/default_configuration.cpp'
--- src/server/graphics/default_configuration.cpp 2014-09-10 12:50:53 +0000
+++ src/server/graphics/default_configuration.cpp 2014-09-18 16:04:44 +0000
@@ -106,6 +106,16 @@
106 });106 });
107}107}
108108
109std::shared_ptr<mg::BufferWriter>
110mir::DefaultServerConfiguration::the_buffer_writer()
111{
112 return buffer_writer(
113 [&]()
114 {
115 return the_graphics_platform()->make_buffer_writer();
116 });
117}
118
109std::shared_ptr<mg::Display>119std::shared_ptr<mg::Display>
110mir::DefaultServerConfiguration::the_display()120mir::DefaultServerConfiguration::the_display()
111{121{
112122
=== modified file 'src/server/graphics/nested/nested_platform.cpp'
--- src/server/graphics/nested/nested_platform.cpp 2014-09-10 12:50:53 +0000
+++ src/server/graphics/nested/nested_platform.cpp 2014-09-18 16:04:44 +0000
@@ -80,6 +80,11 @@
80 return native_platform->create_buffer_allocator(buffer_initializer);80 return native_platform->create_buffer_allocator(buffer_initializer);
81}81}
8282
83std::shared_ptr<mg::BufferWriter> mgn::NestedPlatform::make_buffer_writer()
84{
85 return native_platform->make_buffer_writer();
86}
87
83std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(88std::shared_ptr<mg::Display> mgn::NestedPlatform::create_display(
84 std::shared_ptr<mg::DisplayConfigurationPolicy> const& conf_policy,89 std::shared_ptr<mg::DisplayConfigurationPolicy> const& conf_policy,
85 std::shared_ptr<mg::GLProgramFactory> const&,90 std::shared_ptr<mg::GLProgramFactory> const&,
8691
=== modified file 'src/server/graphics/nested/nested_platform.h'
--- src/server/graphics/nested/nested_platform.h 2014-09-10 12:50:53 +0000
+++ src/server/graphics/nested/nested_platform.h 2014-09-18 16:04:44 +0000
@@ -49,6 +49,7 @@
49 std::shared_ptr<GLConfig> const& gl_config);49 std::shared_ptr<GLConfig> const& gl_config);
50 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;50 std::shared_ptr<PlatformIPCPackage> get_ipc_package() override;
51 std::shared_ptr<InternalClient> create_internal_client() override;51 std::shared_ptr<InternalClient> create_internal_client() override;
52 std::shared_ptr<BufferWriter> make_buffer_writer() override;
52 void fill_buffer_package(53 void fill_buffer_package(
53 BufferIPCPacker* packer, Buffer const* Buffer, BufferIpcMsgType msg_type) const override;54 BufferIPCPacker* packer, Buffer const* Buffer, BufferIpcMsgType msg_type) const override;
54 EGLNativeDisplayType egl_native_display() const;55 EGLNativeDisplayType egl_native_display() const;
5556
=== modified file 'src/server/input/CMakeLists.txt'
--- src/server/input/CMakeLists.txt 2014-09-10 12:50:53 +0000
+++ src/server/input/CMakeLists.txt 2014-09-18 16:04:44 +0000
@@ -16,6 +16,7 @@
16 default_configuration.cpp16 default_configuration.cpp
17 xcursor_loader.cpp17 xcursor_loader.cpp
18 builtin_cursor_images.cpp18 builtin_cursor_images.cpp
19 touchspot_controller.cpp
19)20)
2021
21add_subdirectory(android)22add_subdirectory(android)
2223
=== modified file 'src/server/input/android/android_input_registrar.cpp'
--- src/server/input/android/android_input_registrar.cpp 2014-09-10 12:50:53 +0000
+++ src/server/input/android/android_input_registrar.cpp 2014-09-18 16:04:44 +0000
@@ -123,3 +123,7 @@
123{123{
124 remove(surface);124 remove(surface);
125}125}
126
127void mia::InputRegistrar::SceneObserver::scene_changed()
128{
129}
126130
=== modified file 'src/server/input/android/android_input_registrar.h'
--- src/server/input/android/android_input_registrar.h 2014-09-10 12:50:53 +0000
+++ src/server/input/android/android_input_registrar.h 2014-09-18 16:04:44 +0000
@@ -73,6 +73,7 @@
73 void surface_added(scene::Surface* surface) override;73 void surface_added(scene::Surface* surface) override;
74 void surface_removed(scene::Surface* surface) override;74 void surface_removed(scene::Surface* surface) override;
75 void surface_exists(scene::Surface* surface) override;75 void surface_exists(scene::Surface* surface) override;
76 void scene_changed() override;
7677
77 SurfaceCallback add, remove;78 SurfaceCallback add, remove;
78 };79 };
7980
=== modified file 'src/server/input/android/android_input_target_enumerator.cpp'
--- src/server/input/android/android_input_target_enumerator.cpp 2014-09-10 12:50:53 +0000
+++ src/server/input/android/android_input_target_enumerator.cpp 2014-09-18 16:04:44 +0000
@@ -20,7 +20,7 @@
2020
21#include "android_window_handle_repository.h"21#include "android_window_handle_repository.h"
2222
23#include "mir/input/input_targets.h"23#include "mir/input/scene.h"
24#include "mir/input/surface.h"24#include "mir/input/surface.h"
2525
26#include <InputWindow.h>26#include <InputWindow.h>
@@ -28,9 +28,9 @@
28namespace mi = mir::input;28namespace mi = mir::input;
29namespace mia = mi::android;29namespace mia = mi::android;
3030
31mia::InputTargetEnumerator::InputTargetEnumerator(std::shared_ptr<mi::InputTargets> const& targets,31mia::InputTargetEnumerator::InputTargetEnumerator(std::shared_ptr<mi::Scene> const& scene,
32 std::shared_ptr<mia::WindowHandleRepository> const& repository)32 std::shared_ptr<mia::WindowHandleRepository> const& repository)
33 : targets(targets),33 : scene(scene),
34 repository(repository)34 repository(repository)
35{35{
36}36}
@@ -41,7 +41,7 @@
4141
42void mia::InputTargetEnumerator::for_each(std::function<void(droidinput::sp<droidinput::InputWindowHandle> const&)> const& callback)42void mia::InputTargetEnumerator::for_each(std::function<void(droidinput::sp<droidinput::InputWindowHandle> const&)> const& callback)
43{43{
44 targets->for_each(44 scene->for_each(
45 [&callback, this](std::shared_ptr<mi::Surface> const& target)45 [&callback, this](std::shared_ptr<mi::Surface> const& target)
46 {46 {
47 auto handle = repository->handle_for_channel(target->input_channel());47 auto handle = repository->handle_for_channel(target->input_channel());
4848
=== modified file 'src/server/input/android/android_input_target_enumerator.h'
--- src/server/input/android/android_input_target_enumerator.h 2014-09-10 12:50:53 +0000
+++ src/server/input/android/android_input_target_enumerator.h 2014-09-18 16:04:44 +0000
@@ -41,7 +41,7 @@
41}41}
42namespace input42namespace input
43{43{
44class InputTargets;44class Scene;
45namespace android45namespace android
46{46{
47class WindowHandleRepository;47class WindowHandleRepository;
@@ -49,14 +49,14 @@
49class InputTargetEnumerator : public droidinput::InputEnumerator49class InputTargetEnumerator : public droidinput::InputEnumerator
50{50{
51public:51public:
52 explicit InputTargetEnumerator(std::shared_ptr<input::InputTargets> const& targets,52 explicit InputTargetEnumerator(std::shared_ptr<input::Scene> const& scene,
53 std::shared_ptr<WindowHandleRepository> const& repository);53 std::shared_ptr<WindowHandleRepository> const& repository);
54 virtual ~InputTargetEnumerator() noexcept(true);54 virtual ~InputTargetEnumerator() noexcept(true);
5555
56 void for_each(std::function<void(droidinput::sp<droidinput::InputWindowHandle> const&)> const& callback);56 void for_each(std::function<void(droidinput::sp<droidinput::InputWindowHandle> const&)> const& callback);
5757
58private:58private:
59 std::shared_ptr<input::InputTargets> const targets;59 std::shared_ptr<input::Scene> const scene;
60 std::shared_ptr<input::android::WindowHandleRepository> const repository;60 std::shared_ptr<input::android::WindowHandleRepository> const repository;
61};61};
6262
6363
=== modified file 'src/server/input/android/input_sender.cpp'
--- src/server/input/android/input_sender.cpp 2014-09-10 12:50:53 +0000
+++ src/server/input/android/input_sender.cpp 2014-09-18 16:04:44 +0000
@@ -83,8 +83,12 @@
83 surface_added(surface);83 surface_added(surface);
84}84}
8585
8686void mia::InputSender::SceneObserver::scene_changed()
87void mia::InputSender::SceneObserver::remove_transfer_for(mir::input::Surface * surface)87{
88}
89
90
91void mia::InputSender::SceneObserver::remove_transfer_for(mi::Surface * surface)
88{92{
89 std::shared_ptr<InputChannel> closed_channel = surface->input_channel();93 std::shared_ptr<InputChannel> closed_channel = surface->input_channel();
9094
@@ -96,7 +100,7 @@
96}100}
97101
98mia::InputSender::InputSenderState::InputSenderState(std::shared_ptr<mir::MainLoop> const& main_loop,102mia::InputSender::InputSenderState::InputSenderState(std::shared_ptr<mir::MainLoop> const& main_loop,
99 std::shared_ptr<mir::input::InputSendObserver> const& observer,103 std::shared_ptr<mi::InputSendObserver> const& observer,
100 std::shared_ptr<InputReport> const& report)104 std::shared_ptr<InputReport> const& report)
101 : main_loop{main_loop}, report{report}, observer{observer}, seq{}105 : main_loop{main_loop}, report{report}, observer{observer}, seq{}
102{106{
@@ -131,7 +135,7 @@
131 transfer->send(std::move(entry));135 transfer->send(std::move(entry));
132}136}
133137
134void mia::InputSender::InputSenderState::add_transfer(int fd, mir::input::Surface * surface)138void mia::InputSender::InputSenderState::add_transfer(int fd, mi::Surface * surface)
135{139{
136 std::lock_guard<std::mutex> lock(sender_mutex);140 std::lock_guard<std::mutex> lock(sender_mutex);
137 std::shared_ptr<ActiveTransfer> transfer{get_transfer(fd)};141 std::shared_ptr<ActiveTransfer> transfer{get_transfer(fd)};
@@ -163,7 +167,7 @@
163 return seq;167 return seq;
164}168}
165169
166mia::InputSender::ActiveTransfer::ActiveTransfer(InputSenderState & state, int server_fd, mir::input::Surface* surface) :170mia::InputSender::ActiveTransfer::ActiveTransfer(InputSenderState & state, int server_fd, mi::Surface* surface) :
167 state(state),171 state(state),
168 publisher{droidinput::sp<droidinput::InputChannel>(172 publisher{droidinput::sp<droidinput::InputChannel>(
169 new droidinput::InputChannel(droidinput::String8(surface->name()), server_fd))},173 new droidinput::InputChannel(droidinput::String8(surface->name()), server_fd))},
170174
=== modified file 'src/server/input/android/input_sender.h'
--- src/server/input/android/input_sender.h 2014-09-10 12:50:53 +0000
+++ src/server/input/android/input_sender.h 2014-09-18 16:04:44 +0000
@@ -76,6 +76,7 @@
76 void surface_added(scene::Surface* surface) override;76 void surface_added(scene::Surface* surface) override;
77 void surface_removed(scene::Surface* surface) override;77 void surface_removed(scene::Surface* surface) override;
78 void surface_exists(scene::Surface* surface) override;78 void surface_exists(scene::Surface* surface) override;
79 void scene_changed() override;
7980
80 void remove_transfer_for(input::Surface* surface);81 void remove_transfer_for(input::Surface* surface);
81 InputSenderState & state;82 InputSenderState & state;
8283
=== modified file 'src/server/input/cursor_controller.cpp'
--- src/server/input/cursor_controller.cpp 2014-06-23 02:57:39 +0000
+++ src/server/input/cursor_controller.cpp 2014-09-18 16:04:44 +0000
@@ -18,7 +18,7 @@
1818
19#include "cursor_controller.h"19#include "cursor_controller.h"
2020
21#include "mir/input/input_targets.h"21#include "mir/input/scene.h"
22#include "mir/input/surface.h"22#include "mir/input/surface.h"
23#include "mir/graphics/cursor.h"23#include "mir/graphics/cursor.h"
24#include "mir/scene/observer.h"24#include "mir/scene/observer.h"
@@ -130,6 +130,11 @@
130 {130 {
131 cursor_controller->update_cursor_image();131 cursor_controller->update_cursor_image();
132 }132 }
133
134 void scene_changed()
135 {
136 cursor_controller->update_cursor_image();
137 }
133 138
134 void surface_exists(ms::Surface *surface)139 void surface_exists(ms::Surface *surface)
135 {140 {
@@ -157,7 +162,7 @@
157};162};
158163
159std::shared_ptr<mi::Surface> topmost_surface_containing_point(164std::shared_ptr<mi::Surface> topmost_surface_containing_point(
160 std::shared_ptr<mi::InputTargets> const& targets, geom::Point const& point)165 std::shared_ptr<mi::Scene> const& targets, geom::Point const& point)
161{166{
162 std::shared_ptr<mi::Surface> top_surface_at_point;167 std::shared_ptr<mi::Surface> top_surface_at_point;
163 targets->for_each([&top_surface_at_point, &point]168 targets->for_each([&top_surface_at_point, &point]
@@ -171,7 +176,7 @@
171176
172}177}
173178
174mi::CursorController::CursorController(std::shared_ptr<mi::InputTargets> const& input_targets,179mi::CursorController::CursorController(std::shared_ptr<mi::Scene> const& input_targets,
175 std::shared_ptr<mg::Cursor> const& cursor,180 std::shared_ptr<mg::Cursor> const& cursor,
176 std::shared_ptr<mg::CursorImage> const& default_cursor_image) :181 std::shared_ptr<mg::CursorImage> const& default_cursor_image) :
177 input_targets(input_targets),182 input_targets(input_targets),
178183
=== modified file 'src/server/input/cursor_controller.h'
--- src/server/input/cursor_controller.h 2014-06-11 17:42:49 +0000
+++ src/server/input/cursor_controller.h 2014-09-18 16:04:44 +0000
@@ -39,12 +39,12 @@
3939
40namespace input40namespace input
41{41{
42class InputTargets;42class Scene;
4343
44class CursorController : public CursorListener44class CursorController : public CursorListener
45{45{
46public:46public:
47 CursorController(std::shared_ptr<InputTargets> const& input_targets,47 CursorController(std::shared_ptr<Scene> const& input_targets,
48 std::shared_ptr<graphics::Cursor> const& cursor,48 std::shared_ptr<graphics::Cursor> const& cursor,
49 std::shared_ptr<graphics::CursorImage> const& default_cursor_image);49 std::shared_ptr<graphics::CursorImage> const& default_cursor_image);
50 virtual ~CursorController();50 virtual ~CursorController();
@@ -56,7 +56,7 @@
56 void update_cursor_image();56 void update_cursor_image();
5757
58private:58private:
59 std::shared_ptr<InputTargets> const input_targets;59 std::shared_ptr<Scene> const input_targets;
60 std::shared_ptr<graphics::Cursor> const cursor;60 std::shared_ptr<graphics::Cursor> const cursor;
61 std::shared_ptr<graphics::CursorImage> const default_cursor_image;61 std::shared_ptr<graphics::CursorImage> const default_cursor_image;
6262
6363
=== modified file 'src/server/input/default_configuration.cpp'
--- src/server/input/default_configuration.cpp 2014-09-10 12:50:53 +0000
+++ src/server/input/default_configuration.cpp 2014-09-18 16:04:44 +0000
@@ -30,6 +30,7 @@
30#include "event_filter_chain.h"30#include "event_filter_chain.h"
31#include "null_input_configuration.h"31#include "null_input_configuration.h"
32#include "cursor_controller.h"32#include "cursor_controller.h"
33#include "touchspot_controller.h"
33#include "null_input_dispatcher.h"34#include "null_input_dispatcher.h"
34#include "null_input_targeter.h"35#include "null_input_targeter.h"
35#include "xcursor_loader.h"36#include "xcursor_loader.h"
@@ -114,7 +115,7 @@
114 auto dispatcher = std::make_shared<droidinput::InputDispatcher>(115 auto dispatcher = std::make_shared<droidinput::InputDispatcher>(
115 the_dispatcher_policy(),116 the_dispatcher_policy(),
116 the_input_report(),117 the_input_report(),
117 std::make_shared<mia::InputTargetEnumerator>(the_input_targets(), registrar));118 std::make_shared<mia::InputTargetEnumerator>(the_input_scene(), registrar));
118 registrar->set_dispatcher(dispatcher);119 registrar->set_dispatcher(dispatcher);
119 return dispatcher;120 return dispatcher;
120 });121 });
@@ -234,7 +235,7 @@
234 return cursor_listener(235 return cursor_listener(
235 [this]() -> std::shared_ptr<mi::CursorListener>236 [this]() -> std::shared_ptr<mi::CursorListener>
236 {237 {
237 return std::make_shared<mi::CursorController>(the_input_targets(), 238 return std::make_shared<mi::CursorController>(the_input_scene(),
238 the_cursor(), the_default_cursor_image());239 the_cursor(), the_default_cursor_image());
239 });240 });
240241
@@ -243,16 +244,21 @@
243std::shared_ptr<mi::TouchVisualizer>244std::shared_ptr<mi::TouchVisualizer>
244mir::DefaultServerConfiguration::the_touch_visualizer()245mir::DefaultServerConfiguration::the_touch_visualizer()
245{246{
246 struct NullTouchVisualizer : public mi::TouchVisualizer
247 {
248 void visualize_touches(std::vector<Spot> const& /* touches */) override
249 {
250 }
251 };
252 return touch_visualizer(247 return touch_visualizer(
253 [this]()248 [this]() -> std::shared_ptr<mi::TouchVisualizer>
254 {249 {
255 return std::make_shared<NullTouchVisualizer>();250 auto visualizer = std::make_shared<mi::TouchspotController>(the_buffer_allocator(), the_buffer_writer(),
251 the_input_scene());
252
253 // The visualizer is disabled by default and can be enabled statically via
254 // the MIR_SERVER_ENABLE_TOUCHSPOTS option. In the USC/unity8/autopilot case
255 // it will be toggled at runtime via com.canonical.Unity.Screen DBus interface
256 if (the_options()->is_set(options::touchspots_opt))
257 {
258 visualizer->enable();
259 }
260
261 return visualizer;
256 });262 });
257}263}
258264
259265
=== added file 'src/server/input/touchspot_controller.cpp'
--- src/server/input/touchspot_controller.cpp 1970-01-01 00:00:00 +0000
+++ src/server/input/touchspot_controller.cpp 2014-09-18 16:04:44 +0000
@@ -0,0 +1,166 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#include "touchspot_controller.h"
20#include "touchspot_image.c"
21
22#include "mir/graphics/graphic_buffer_allocator.h"
23#include "mir/graphics/buffer_properties.h"
24#include "mir/graphics/buffer.h"
25#include "mir/graphics/buffer_writer.h"
26#include "mir/graphics/renderable.h"
27#include "mir/geometry/dimensions.h"
28#include "mir/input/scene.h"
29
30namespace mi = mir::input;
31namespace mg = mir::graphics;
32namespace geom = mir::geometry;
33
34namespace
35{
36geom::Size const touchspot_size = {touchspot_image.width, touchspot_image.height};
37MirPixelFormat const touchspot_pixel_format = mir_pixel_format_argb_8888;
38}
39
40class mi::TouchspotRenderable : public mg::Renderable
41{
42public:
43 TouchspotRenderable(std::shared_ptr<mg::Buffer> const& buffer)
44 : buffer_(buffer),
45 position({0, 0})
46 {
47 }
48
49// mg::Renderable
50 mg::Renderable::ID id() const override
51 {
52 return this;
53 }
54
55 std::shared_ptr<mg::Buffer> buffer() const override
56 {
57 return buffer_;
58 }
59
60 bool alpha_enabled() const override
61 {
62 return false;
63 }
64
65 geom::Rectangle screen_position() const
66 {
67 return {position, buffer_->size()};
68 }
69
70 float alpha() const
71 {
72 return 1.0;
73 }
74
75 glm::mat4 transformation() const
76 {
77 return glm::mat4();
78 }
79
80 bool visible() const
81 {
82 return true;
83 }
84
85 bool shaped() const
86 {
87 return true;
88 }
89
90 int buffers_ready_for_compositor() const
91 {
92 return 1;
93 }
94
95// TouchspotRenderable
96 void move_center_to(geom::Point pos)
97 {
98 std::lock_guard<std::mutex> lg(guard);
99 position = {pos.x.as_int() - touchspot_image.width/2, pos.y.as_int() - touchspot_image.height/2};
100 }
101
102
103private:
104 std::shared_ptr<mg::Buffer> const buffer_;
105
106 std::mutex guard;
107 geom::Point position;
108};
109
110
111mi::TouchspotController::TouchspotController(std::shared_ptr<mg::GraphicBufferAllocator> const& allocator,
112 std::shared_ptr<mg::BufferWriter> const& buffer_writer,
113 std::shared_ptr<mi::Scene> const& scene)
114 : touchspot_buffer(allocator->alloc_buffer({touchspot_size, touchspot_pixel_format, mg::BufferUsage::software})),
115 scene(scene),
116 enabled(false),
117 renderables_in_use(0)
118{
119 unsigned int const pixels_size = touchspot_size.width.as_uint32_t()*touchspot_size.height.as_uint32_t() *
120 MIR_BYTES_PER_PIXEL(touchspot_pixel_format);
121
122 buffer_writer->write(*touchspot_buffer, touchspot_image.pixel_data, pixels_size);
123}
124
125void mi::TouchspotController::visualize_touches(std::vector<Spot> const& touches)
126{
127 {
128 std::lock_guard<std::mutex> lg(guard);
129
130 unsigned int const num_touches = enabled ? touches.size() : 0;
131
132 while (touchspot_renderables.size() < num_touches)
133 touchspot_renderables.push_back(std::make_shared<TouchspotRenderable>(touchspot_buffer));
134
135 for (unsigned int i = 0; i < num_touches; i++)
136 {
137 auto const& renderable = touchspot_renderables[i];
138
139 renderable->move_center_to(touches[i].touch_location);
140 if (i >= renderables_in_use)
141 scene->add_input_visualization(renderable);
142 }
143
144 for (unsigned int i = num_touches; i < renderables_in_use; i++)
145 scene->remove_input_visualization(touchspot_renderables[i]);
146
147 renderables_in_use = num_touches;
148 } // release mutex
149
150 // TODO (hackish): We may have just moved renderables which with the current
151 // architecture of surface observers will not trigger a propagation to the
152 // compositor damage callback we need this "emit_scene_changed".
153 scene->emit_scene_changed();
154}
155
156void mi::TouchspotController::enable()
157{
158 std::lock_guard<std::mutex> lg(guard);
159 enabled = true;
160}
161
162void mi::TouchspotController::disable()
163{
164 std::lock_guard<std::mutex> lg(guard);
165 enabled = false;
166}
0167
=== added file 'src/server/input/touchspot_controller.h'
--- src/server/input/touchspot_controller.h 1970-01-01 00:00:00 +0000
+++ src/server/input/touchspot_controller.h 2014-09-18 16:04:44 +0000
@@ -0,0 +1,77 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#ifndef MIR_INPUT_TOUCHSPOT_CONTROLLER_H_
20#define MIR_INPUT_TOUCHSPOT_CONTROLLER_H_
21
22#include "mir/input/touch_visualizer.h"
23
24#include <memory>
25#include <mutex>
26
27namespace mir
28{
29namespace graphics
30{
31class GraphicBufferAllocator;
32class Buffer;
33class BufferWriter;
34class Renderable;
35}
36namespace input
37{
38class Scene;
39class TouchspotRenderable;
40
41/// Receives touchspot events out of the input stack and manages appearance
42/// of touchspot renderables for visualization. Touchspot visualization is
43/// disabled by default and must be enabled through a call to ::enable.
44class TouchspotController : public TouchVisualizer
45{
46public:
47 TouchspotController(std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator,
48 std::shared_ptr<graphics::BufferWriter> const& writer,
49 std::shared_ptr<input::Scene> const& scene);
50
51 virtual ~TouchspotController() = default;
52
53 void enable() override;
54 void disable() override;
55
56 void visualize_touches(std::vector<Spot> const& touches) override;
57
58protected:
59 TouchspotController(TouchspotController const&) = delete;
60 TouchspotController& operator=(TouchspotController const&) = delete;
61
62private:
63 std::shared_ptr<graphics::Buffer> touchspot_buffer;
64 std::shared_ptr<Scene> scene;
65
66 std::mutex guard;
67
68 bool enabled;
69
70 unsigned int renderables_in_use;
71 std::vector<std::shared_ptr<TouchspotRenderable>> touchspot_renderables;
72};
73
74}
75}
76
77#endif // MIR_INPUT_TOUCHSPOT_CONTROLLER_H_
078
=== added file 'src/server/input/touchspot_image.c'
--- src/server/input/touchspot_image.c 1970-01-01 00:00:00 +0000
+++ src/server/input/touchspot_image.c 2014-09-18 16:04:44 +0000
@@ -0,0 +1,1034 @@
1/* GIMP RGBA C-Source image dump (spot.c) */
2
3static const struct {
4 unsigned int width;
5 unsigned int height;
6 unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
7 unsigned char pixel_data[64 * 64 * 4 + 1];
8} touchspot_image = {
9 64, 64, 4,
10{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
140,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
160,0,0,5,0,0,0,65,0,0,0,104,0,0,0,129,
170,0,0,154,0,0,0,179,0,0,0,204,0,0,0,230,
180,0,0,230,0,0,0,204,0,0,0,179,0,0,0,154,
190,0,0,129,0,0,0,104,0,0,0,65,0,0,0,5,
200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
290,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
310,0,0,0,0,0,0,15,0,0,0,88,0,0,0,166,
320,0,0,240,0,0,0,255,0,0,0,255,0,0,0,255,
330,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
340,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
350,0,0,255,0,0,0,255,0,0,0,255,0,0,0,240,
360,0,0,166,0,0,0,88,0,0,0,15,0,0,0,0,
370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
380,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
420,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
460,0,0,0,0,0,0,0,0,0,0,3,0,0,0,95,
470,0,0,187,0,0,0,250,0,0,0,255,0,0,0,255,
480,0,0,255,0,15,28,255,0,45,82,255,0,60,108,255,
490,75,135,255,0,89,161,255,0,104,188,255,0,119,215,255,
500,119,215,255,0,104,188,255,0,89,161,255,0,75,135,255,
510,60,108,255,0,45,82,255,0,15,28,255,0,0,0,255,
520,0,0,255,0,0,0,255,0,0,0,250,0,0,0,187,
530,0,0,95,0,0,0,3,0,0,0,0,0,0,0,0,
540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
590,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
610,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
620,0,0,0,0,0,0,83,0,0,0,215,0,0,0,255,
630,0,0,255,0,0,0,255,0,27,49,255,0,70,126,255,
640,112,203,255,0,139,251,255,0,139,251,255,0,139,251,255,
650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
660,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
670,139,251,255,0,139,251,255,0,139,251,255,0,112,203,255,
680,70,126,255,0,27,49,255,0,0,0,255,0,0,0,255,
690,0,0,255,0,0,0,215,0,0,0,83,0,0,0,0,
700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
770,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,
780,0,0,203,0,0,0,255,0,0,0,255,0,12,22,255,
790,77,139,255,0,124,223,255,0,139,251,255,0,139,251,255,
800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
830,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
840,139,251,255,0,139,251,255,0,124,223,255,0,77,139,255,
850,13,23,255,0,0,0,255,0,0,0,255,0,0,0,203,
860,0,0,69,0,0,0,0,0,0,0,0,0,0,0,0,
870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
890,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
900,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
920,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
930,0,0,0,0,0,0,24,0,0,0,187,0,0,0,255,
940,0,0,255,0,8,14,255,0,71,128,255,0,133,240,255,
950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
960,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
990,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1010,133,240,255,0,72,130,255,0,8,15,255,0,0,0,255,
1020,0,0,255,0,0,0,187,0,0,0,24,0,0,0,0,
1030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1040,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1050,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1060,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1080,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1090,0,0,53,0,0,0,228,0,0,0,255,0,4,7,255,
1100,62,112,255,0,129,232,255,0,139,251,255,0,139,251,255,
1110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1120,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1150,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1170,139,251,255,0,139,251,255,0,129,233,255,0,63,114,255,
1180,4,8,255,0,0,0,255,0,0,0,228,0,0,0,53,
1190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,
1250,0,0,247,0,0,0,255,0,28,51,255,0,122,220,255,
1260,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1280,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1310,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1330,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1340,123,221,255,0,28,50,255,0,0,0,255,0,0,0,247,
1350,0,0,92,0,0,0,0,0,0,0,0,0,0,0,0,
1360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1380,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1400,0,0,0,0,0,0,3,0,0,0,140,0,0,0,255,
1410,0,0,255,0,49,89,255,0,134,242,255,0,139,251,255,
1420,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1440,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1470,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1490,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1500,139,251,255,0,134,242,255,0,47,86,255,0,0,0,255,
1510,0,0,255,0,0,0,140,0,0,0,3,0,0,0,0,
1520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1560,0,0,5,0,0,0,181,0,0,0,255,0,1,2,255,
1570,74,133,255,0,139,251,255,0,139,251,255,0,139,251,255,
1580,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1600,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1660,139,251,255,0,139,251,255,0,139,251,255,0,71,129,255,
1670,1,1,255,0,0,0,255,0,0,0,178,0,0,0,3,
1680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1690,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1720,0,0,151,0,0,0,255,0,7,14,255,0,98,177,255,
1730,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1740,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1760,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1770,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1830,95,172,255,0,6,12,255,0,0,0,255,0,0,0,143,
1840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1850,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1860,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,
1880,0,0,255,0,2,4,255,0,105,189,255,0,139,251,255,
1890,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1900,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1920,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1930,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1940,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1960,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
1990,139,251,255,0,101,182,255,0,2,3,255,0,0,0,255,
2000,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,
2010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2020,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2030,0,0,0,0,0,0,0,0,0,0,61,0,0,0,250,
2040,0,0,255,0,81,147,255,0,139,251,255,0,139,251,255,
2050,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2060,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2070,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2080,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2090,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2100,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2120,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2150,139,251,255,0,139,251,255,0,76,138,255,0,0,0,255,
2160,0,0,248,0,0,0,55,0,0,0,0,0,0,0,0,
2170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2190,0,0,0,0,0,0,30,0,0,0,234,0,0,0,255,
2200,56,100,255,0,139,251,255,0,139,251,255,0,139,251,255,
2210,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2220,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2230,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2240,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2250,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2260,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2280,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2310,139,251,255,0,139,251,255,0,139,251,255,0,51,92,255,
2320,0,0,255,0,0,0,230,0,0,0,26,0,0,0,0,
2330,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2340,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2350,0,0,0,0,0,0,195,0,0,0,255,0,33,59,255,
2360,136,246,255,0,139,251,255,0,139,251,255,0,139,251,255,
2370,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2380,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2390,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2400,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2410,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2420,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2440,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2470,139,251,255,0,139,251,255,0,139,251,255,0,135,243,255,
2480,29,52,255,0,0,0,255,0,0,0,193,0,0,0,0,
2490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2510,0,0,79,0,0,0,255,0,8,14,255,0,126,228,255,
2520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2530,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2540,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2550,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2560,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2570,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2580,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2600,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2640,124,224,255,0,8,15,255,0,0,0,255,0,0,0,77,
2650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2660,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,
2670,0,0,213,0,0,0,255,0,71,129,255,0,139,251,255,
2680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2690,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2700,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2710,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2720,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2730,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2740,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2760,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2770,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2800,139,251,255,0,72,130,255,0,0,0,255,0,0,0,211,
2810,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
2820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,
2830,0,0,255,0,14,25,255,0,134,241,255,0,139,251,255,
2840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2850,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2860,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2870,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2880,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2890,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2900,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2920,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2930,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2940,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
2960,139,251,255,0,133,240,255,0,13,24,255,0,0,0,255,
2970,0,0,93,0,0,0,0,0,0,0,0,0,0,0,0,
2980,0,0,0,0,0,0,0,0,0,0,8,0,0,0,227,
2990,0,0,255,0,83,150,255,0,139,251,255,0,139,251,255,
3000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3010,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3020,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3030,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3040,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3050,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3060,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3070,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3080,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3090,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3100,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3120,139,251,255,0,139,251,255,0,81,147,255,0,0,0,255,
3130,0,0,223,0,0,0,6,0,0,0,0,0,0,0,0,
3140,0,0,0,0,0,0,0,0,0,0,115,0,0,0,255,
3150,21,37,255,0,137,247,255,0,139,251,255,0,139,251,255,
3160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3170,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3180,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3190,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3200,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3210,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3220,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3230,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3240,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3250,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3260,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3280,139,251,255,0,139,251,255,0,136,246,255,0,19,34,255,
3290,0,0,255,0,0,0,110,0,0,0,0,0,0,0,0,
3300,0,0,0,0,0,0,0,0,0,0,209,0,0,0,255,
3310,88,159,255,0,139,251,255,0,139,251,255,0,139,251,255,
3320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3330,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3340,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3350,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3360,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3370,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3380,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3390,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3400,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3410,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3420,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3440,139,251,255,0,139,251,255,0,139,251,255,0,88,158,255,
3450,0,0,255,0,0,0,209,0,0,0,0,0,0,0,0,
3460,0,0,0,0,0,0,32,0,0,0,255,0,3,6,255,
3470,131,237,255,0,139,251,255,0,139,251,255,0,139,251,255,
3480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3490,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3500,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3510,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3530,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3540,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3550,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3560,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3570,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3580,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3600,139,251,255,0,139,251,255,0,139,251,255,0,132,239,255,
3610,4,7,255,0,0,0,255,0,0,0,32,0,0,0,0,
3620,0,0,0,0,0,0,111,0,0,0,255,0,38,69,255,
3630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3660,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3670,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3690,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3700,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3710,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3720,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3730,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3740,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3760,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3770,39,71,255,0,0,0,255,0,0,0,111,0,0,0,0,
3780,0,0,0,0,0,0,189,0,0,0,255,0,81,147,255,
3790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3830,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3850,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3860,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3870,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3880,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3890,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3900,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3920,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3930,82,149,255,0,0,0,255,0,0,0,189,0,0,0,0,
3940,0,0,17,0,0,0,251,0,1,1,255,0,124,224,255,
3950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3960,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
3990,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4010,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4020,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4030,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4040,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4050,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4060,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4070,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4080,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4090,124,224,255,0,1,1,255,0,0,0,251,0,0,0,17,
4100,0,0,89,0,0,0,255,0,28,51,255,0,139,251,255,
4110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4120,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4150,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4170,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4180,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4190,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4200,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4210,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4220,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4230,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4240,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4250,139,251,255,0,28,50,255,0,0,0,255,0,0,0,89,
4260,0,0,128,0,0,0,255,0,63,114,255,0,139,251,255,
4270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4280,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4310,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4330,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4340,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4350,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4360,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4370,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4380,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4390,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4400,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4410,139,251,255,0,58,104,255,0,0,0,255,0,0,0,128,
4420,0,0,155,0,0,0,255,0,77,140,255,0,139,251,255,
4430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4440,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4470,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4490,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4500,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4510,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4530,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4540,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4550,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4560,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4570,139,251,255,0,73,132,255,0,0,0,255,0,0,0,155,
4580,0,0,181,0,0,0,255,0,91,164,255,0,139,251,255,
4590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4600,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4660,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4670,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4690,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4700,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4710,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4720,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4730,139,251,255,0,88,158,255,0,0,0,255,0,0,0,181,
4740,0,0,208,0,0,0,255,0,105,190,255,0,139,251,255,
4750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4760,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4770,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4830,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4850,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4860,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4870,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4880,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4890,139,251,255,0,102,185,255,0,0,0,255,0,0,0,208,
4900,0,0,234,0,0,0,255,0,119,215,255,0,139,251,255,
4910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4920,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4930,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4940,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4960,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
4990,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5010,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5020,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5030,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5040,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5050,139,251,255,0,117,212,255,0,0,0,255,0,0,0,234,
5060,0,0,254,0,0,0,255,0,132,239,255,0,139,251,255,
5070,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5080,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5090,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5100,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5120,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5150,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5170,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5180,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5190,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5200,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5210,139,251,255,0,132,238,255,0,0,0,255,0,0,0,254,
5220,0,0,254,0,0,0,255,0,132,239,255,0,139,251,255,
5230,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5240,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5250,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5260,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5280,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5310,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5330,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5340,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5350,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5360,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5370,139,251,255,0,132,238,255,0,0,0,255,0,0,0,254,
5380,0,0,234,0,0,0,255,0,119,215,255,0,139,251,255,
5390,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5400,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5410,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5420,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5440,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5470,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5490,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5500,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5510,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5530,139,251,255,0,117,212,255,0,0,0,255,0,0,0,234,
5540,0,0,208,0,0,0,255,0,105,190,255,0,139,251,255,
5550,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5560,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5570,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5580,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5600,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5660,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5670,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5690,139,251,255,0,102,185,255,0,0,0,255,0,0,0,208,
5700,0,0,181,0,0,0,255,0,91,164,255,0,139,251,255,
5710,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5720,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5730,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5740,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5760,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5770,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5830,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5850,139,251,255,0,88,158,255,0,0,0,255,0,0,0,181,
5860,0,0,155,0,0,0,255,0,77,140,255,0,139,251,255,
5870,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5880,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5890,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5900,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5920,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5930,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5940,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5960,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
5990,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6010,139,251,255,0,73,132,255,0,0,0,255,0,0,0,155,
6020,0,0,128,0,0,0,255,0,63,114,255,0,139,251,255,
6030,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6040,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6050,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6060,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6070,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6080,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6090,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6100,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6120,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6150,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6170,139,251,255,0,58,104,255,0,0,0,255,0,0,0,128,
6180,0,0,89,0,0,0,255,0,28,51,255,0,139,251,255,
6190,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6200,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6210,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6220,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6230,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6240,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6250,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6260,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6280,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6310,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6330,139,251,255,0,28,50,255,0,0,0,255,0,0,0,89,
6340,0,0,17,0,0,0,251,0,1,1,255,0,124,224,255,
6350,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6360,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6370,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6380,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6390,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6400,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6410,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6420,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6440,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6470,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6490,124,224,255,0,1,1,255,0,0,0,251,0,0,0,17,
6500,0,0,0,0,0,0,189,0,0,0,255,0,81,147,255,
6510,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6530,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6540,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6550,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6560,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6570,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6580,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6600,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6650,82,149,255,0,0,0,255,0,0,0,189,0,0,0,0,
6660,0,0,0,0,0,0,111,0,0,0,255,0,38,69,255,
6670,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6690,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6700,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6710,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6720,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6730,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6740,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6760,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6770,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6810,39,71,255,0,0,0,255,0,0,0,111,0,0,0,0,
6820,0,0,0,0,0,0,32,0,0,0,255,0,3,6,255,
6830,131,237,255,0,139,251,255,0,139,251,255,0,139,251,255,
6840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6850,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6860,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6870,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6880,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6890,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6900,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6920,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6930,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6940,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
6960,139,251,255,0,139,251,255,0,139,251,255,0,132,239,255,
6970,4,7,255,0,0,0,255,0,0,0,32,0,0,0,0,
6980,0,0,0,0,0,0,0,0,0,0,209,0,0,0,255,
6990,88,159,255,0,139,251,255,0,139,251,255,0,139,251,255,
7000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7010,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7020,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7030,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7040,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7050,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7060,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7070,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7080,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7090,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7100,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7120,139,251,255,0,139,251,255,0,139,251,255,0,88,158,255,
7130,0,0,255,0,0,0,209,0,0,0,0,0,0,0,0,
7140,0,0,0,0,0,0,0,0,0,0,115,0,0,0,255,
7150,21,37,255,0,137,247,255,0,139,251,255,0,139,251,255,
7160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7170,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7180,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7190,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7200,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7210,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7220,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7230,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7240,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7250,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7260,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7280,139,251,255,0,139,251,255,0,136,246,255,0,19,34,255,
7290,0,0,255,0,0,0,110,0,0,0,0,0,0,0,0,
7300,0,0,0,0,0,0,0,0,0,0,8,0,0,0,227,
7310,0,0,255,0,83,150,255,0,139,251,255,0,139,251,255,
7320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7330,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7340,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7350,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7360,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7370,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7380,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7390,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7400,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7410,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7420,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7440,139,251,255,0,139,251,255,0,81,147,255,0,0,0,255,
7450,0,0,223,0,0,0,6,0,0,0,0,0,0,0,0,
7460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,
7470,0,0,255,0,14,25,255,0,134,241,255,0,139,251,255,
7480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7490,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7500,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7510,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7530,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7540,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7550,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7560,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7570,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7580,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7590,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7600,139,251,255,0,133,240,255,0,13,24,255,0,0,0,255,
7610,0,0,93,0,0,0,0,0,0,0,0,0,0,0,0,
7620,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,
7630,0,0,213,0,0,0,255,0,71,129,255,0,139,251,255,
7640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7660,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7670,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7690,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7700,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7710,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7720,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7730,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7740,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7750,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7760,139,251,255,0,72,130,255,0,0,0,255,0,0,0,211,
7770,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
7780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7790,0,0,79,0,0,0,255,0,8,14,255,0,126,228,255,
7800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7830,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7850,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7860,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7870,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7880,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7890,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7900,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7910,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7920,124,224,255,0,8,15,255,0,0,0,255,0,0,0,77,
7930,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7940,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7950,0,0,0,0,0,0,195,0,0,0,255,0,33,59,255,
7960,136,246,255,0,139,251,255,0,139,251,255,0,139,251,255,
7970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
7990,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8010,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8020,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8030,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8040,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8050,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8060,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8070,139,251,255,0,139,251,255,0,139,251,255,0,135,243,255,
8080,29,52,255,0,0,0,255,0,0,0,193,0,0,0,0,
8090,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8110,0,0,0,0,0,0,30,0,0,0,234,0,0,0,255,
8120,56,100,255,0,139,251,255,0,139,251,255,0,139,251,255,
8130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8150,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8170,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8180,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8190,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8200,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8210,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8220,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8230,139,251,255,0,139,251,255,0,139,251,255,0,51,92,255,
8240,0,0,255,0,0,0,230,0,0,0,26,0,0,0,0,
8250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8270,0,0,0,0,0,0,0,0,0,0,61,0,0,0,250,
8280,0,0,255,0,81,147,255,0,139,251,255,0,139,251,255,
8290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8310,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8330,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8340,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8350,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8360,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8370,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8380,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8390,139,251,255,0,139,251,255,0,76,138,255,0,0,0,255,
8400,0,0,248,0,0,0,55,0,0,0,0,0,0,0,0,
8410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8420,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,
8440,0,0,255,0,2,4,255,0,105,189,255,0,139,251,255,
8450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8470,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8490,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8500,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8510,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8520,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8530,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8540,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8550,139,251,255,0,101,182,255,0,2,3,255,0,0,0,255,
8560,0,0,95,0,0,0,0,0,0,0,0,0,0,0,0,
8570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8590,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8600,0,0,151,0,0,0,255,0,7,14,255,0,98,177,255,
8610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8640,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8650,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8660,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8670,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8680,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8690,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8700,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8710,95,172,255,0,6,12,255,0,0,0,255,0,0,0,143,
8720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8760,0,0,5,0,0,0,181,0,0,0,255,0,1,2,255,
8770,74,133,255,0,139,251,255,0,139,251,255,0,139,251,255,
8780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8790,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8800,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8810,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8820,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8830,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8840,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8850,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8860,139,251,255,0,139,251,255,0,139,251,255,0,71,129,255,
8870,1,1,255,0,0,0,255,0,0,0,178,0,0,0,3,
8880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8890,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8900,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8920,0,0,0,0,0,0,3,0,0,0,140,0,0,0,255,
8930,0,0,255,0,49,89,255,0,134,242,255,0,139,251,255,
8940,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8950,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8960,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8970,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8980,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
8990,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9000,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9010,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9020,139,251,255,0,134,242,255,0,47,86,255,0,0,0,255,
9030,0,0,255,0,0,0,140,0,0,0,3,0,0,0,0,
9040,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9050,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9060,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9080,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,
9090,0,0,247,0,0,0,255,0,28,51,255,0,122,220,255,
9100,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9110,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9120,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9130,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9140,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9150,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9160,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9170,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9180,123,221,255,0,28,50,255,0,0,0,255,0,0,0,247,
9190,0,0,92,0,0,0,0,0,0,0,0,0,0,0,0,
9200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9250,0,0,53,0,0,0,228,0,0,0,255,0,4,7,255,
9260,62,112,255,0,129,232,255,0,139,251,255,0,139,251,255,
9270,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9280,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9290,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9300,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9310,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9320,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9330,139,251,255,0,139,251,255,0,129,233,255,0,63,114,255,
9340,4,8,255,0,0,0,255,0,0,0,228,0,0,0,53,
9350,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9380,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9410,0,0,0,0,0,0,24,0,0,0,187,0,0,0,255,
9420,0,0,255,0,8,14,255,0,71,128,255,0,133,240,255,
9430,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9440,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9450,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9460,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9470,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9480,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9490,133,240,255,0,72,130,255,0,8,15,255,0,0,0,255,
9500,0,0,255,0,0,0,187,0,0,0,24,0,0,0,0,
9510,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,
9580,0,0,203,0,0,0,255,0,0,0,255,0,12,22,255,
9590,77,139,255,0,124,223,255,0,139,251,255,0,139,251,255,
9600,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9610,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9620,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9630,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9640,139,251,255,0,139,251,255,0,124,223,255,0,77,139,255,
9650,13,23,255,0,0,0,255,0,0,0,255,0,0,0,203,
9660,0,0,69,0,0,0,0,0,0,0,0,0,0,0,0,
9670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9690,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9740,0,0,0,0,0,0,83,0,0,0,215,0,0,0,255,
9750,0,0,255,0,0,0,255,0,27,49,255,0,70,126,255,
9760,112,203,255,0,139,251,255,0,139,251,255,0,139,251,255,
9770,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9780,139,251,255,0,139,251,255,0,139,251,255,0,139,251,255,
9790,139,251,255,0,139,251,255,0,139,251,255,0,112,203,255,
9800,70,126,255,0,27,49,255,0,0,0,255,0,0,0,255,
9810,0,0,255,0,0,0,215,0,0,0,83,0,0,0,0,
9820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9830,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9850,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9860,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9880,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9890,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9900,0,0,0,0,0,0,0,0,0,0,3,0,0,0,95,
9910,0,0,187,0,0,0,250,0,0,0,255,0,0,0,255,
9920,0,0,255,0,15,28,255,0,45,82,255,0,60,108,255,
9930,75,135,255,0,89,161,255,0,104,188,255,0,119,215,255,
9940,119,215,255,0,104,188,255,0,89,161,255,0,75,135,255,
9950,60,108,255,0,45,82,255,0,15,28,255,0,0,0,255,
9960,0,0,255,0,0,0,255,0,0,0,250,0,0,0,187,
9970,0,0,95,0,0,0,3,0,0,0,0,0,0,0,0,
9980,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10020,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10040,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10050,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10060,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10070,0,0,0,0,0,0,15,0,0,0,88,0,0,0,166,
10080,0,0,240,0,0,0,255,0,0,0,255,0,0,0,255,
10090,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
10100,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
10110,0,0,255,0,0,0,255,0,0,0,255,0,0,0,240,
10120,0,0,166,0,0,0,88,0,0,0,15,0,0,0,0,
10130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10140,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10240,0,0,5,0,0,0,65,0,0,0,104,0,0,0,129,
10250,0,0,154,0,0,0,179,0,0,0,204,0,0,0,230,
10260,0,0,230,0,0,0,204,0,0,0,179,0,0,0,154,
10270,0,0,129,0,0,0,104,0,0,0,65,0,0,0,5,
10280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10290,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10320,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10330,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
1034};
01035
=== modified file 'src/server/scene/basic_surface.cpp'
--- src/server/scene/basic_surface.cpp 2014-09-10 12:50:53 +0000
+++ src/server/scene/basic_surface.cpp 2014-09-18 16:04:44 +0000
@@ -667,7 +667,6 @@
667 667
668 mg::Renderable::ID id() const override668 mg::Renderable::ID id() const override
669 { return id_; }669 { return id_; }
670
671private:670private:
672 std::shared_ptr<mc::BufferStream> const underlying_buffer_stream;671 std::shared_ptr<mc::BufferStream> const underlying_buffer_stream;
673 std::shared_ptr<mg::Buffer> mutable compositor_buffer;672 std::shared_ptr<mg::Buffer> mutable compositor_buffer;
674673
=== modified file 'src/server/scene/default_configuration.cpp'
--- src/server/scene/default_configuration.cpp 2014-09-10 12:50:53 +0000
+++ src/server/scene/default_configuration.cpp 2014-09-18 16:04:44 +0000
@@ -20,7 +20,7 @@
2020
21#include "mir/graphics/display.h"21#include "mir/graphics/display.h"
22#include "mir/graphics/gl_context.h"22#include "mir/graphics/gl_context.h"
23#include "mir/input/input_targets.h"23#include "mir/input/scene.h"
24#include "mir/abnormal_exit.h"24#include "mir/abnormal_exit.h"
25#include "mir/scene/session.h"25#include "mir/scene/session.h"
2626
@@ -57,7 +57,7 @@
57 { return std::make_shared<ms::SurfaceStack>(the_scene_report()); });57 { return std::make_shared<ms::SurfaceStack>(the_scene_report()); });
58}58}
5959
60std::shared_ptr<mi::InputTargets> mir::DefaultServerConfiguration::the_input_targets()60std::shared_ptr<mi::Scene> mir::DefaultServerConfiguration::the_input_scene()
61{61{
62 return surface_stack([this]()62 return surface_stack([this]()
63 { return std::make_shared<ms::SurfaceStack>(the_scene_report()); });63 { return std::make_shared<ms::SurfaceStack>(the_scene_report()); });
6464
=== modified file 'src/server/scene/legacy_scene_change_notification.cpp'
--- src/server/scene/legacy_scene_change_notification.cpp 2014-09-10 12:50:53 +0000
+++ src/server/scene/legacy_scene_change_notification.cpp 2014-09-18 16:04:44 +0000
@@ -82,6 +82,11 @@
82 scene_notify_change();82 scene_notify_change();
83}83}
8484
85void ms::LegacySceneChangeNotification::scene_changed()
86{
87 scene_notify_change();
88}
89
85void ms::LegacySceneChangeNotification::end_observation()90void ms::LegacySceneChangeNotification::end_observation()
86{91{
87 std::unique_lock<decltype(surface_observers_guard)> lg(surface_observers_guard);92 std::unique_lock<decltype(surface_observers_guard)> lg(surface_observers_guard);
8893
=== modified file 'src/server/scene/surface_stack.cpp'
--- src/server/scene/surface_stack.cpp 2014-09-10 12:50:53 +0000
+++ src/server/scene/surface_stack.cpp 2014-09-18 16:04:44 +0000
@@ -68,11 +68,47 @@
68 tracker->occluded_in(cid);68 tracker->occluded_in(cid);
69 }69 }
7070
71 bool is_a_surface() const override
72 {
73 return true;
74 }
75
71private:76private:
72 std::shared_ptr<mg::Renderable> const renderable_;77 std::shared_ptr<mg::Renderable> const renderable_;
73 std::shared_ptr<ms::RenderingTracker> const tracker;78 std::shared_ptr<ms::RenderingTracker> const tracker;
74};79};
7580
81class OverlaySceneElement : public mc::SceneElement
82{
83public:
84 OverlaySceneElement(
85 std::shared_ptr<mg::Renderable> renderable)
86 : renderable_{renderable}
87 {
88 }
89
90 std::shared_ptr<mg::Renderable> renderable() const override
91 {
92 return renderable_;
93 }
94
95 void rendered_in(mc::CompositorID /* cid */) override
96 {
97 }
98
99 void occluded_in(mc::CompositorID /* cid */) override
100 {
101 }
102
103 bool is_a_surface() const override
104 {
105 return false;
106 }
107
108private:
109 std::shared_ptr<mg::Renderable> const renderable_;
110};
111
76}112}
77113
78ms::SurfaceStack::SurfaceStack(114ms::SurfaceStack::SurfaceStack(
@@ -95,6 +131,10 @@
95 elements.emplace_back(element);131 elements.emplace_back(element);
96 }132 }
97 }133 }
134 for (auto const& renderable : overlays)
135 {
136 elements.emplace_back(std::make_shared<OverlaySceneElement>(renderable));
137 }
98 return elements;138 return elements;
99}139}
100140
@@ -116,6 +156,38 @@
116 update_rendering_tracker_compositors();156 update_rendering_tracker_compositors();
117}157}
118158
159void ms::SurfaceStack::add_input_visualization(
160 std::shared_ptr<mg::Renderable> const& overlay)
161{
162 {
163 std::lock_guard<decltype(guard)> lg(guard);
164 overlays.push_back(overlay);
165 }
166 observers.scene_changed();
167}
168
169void ms::SurfaceStack::remove_input_visualization(
170 std::weak_ptr<mg::Renderable> const& weak_overlay)
171{
172 auto overlay = weak_overlay.lock();
173 {
174 std::lock_guard<decltype(guard)> lg(guard);
175 auto const p = std::find(overlays.begin(), overlays.end(), overlay);
176 if (p == overlays.end())
177 {
178 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to remove an overlay which was never added or which has been previously removed"));
179 }
180 overlays.erase(p);
181 }
182
183 observers.scene_changed();
184}
185
186void ms::SurfaceStack::emit_scene_changed()
187{
188 observers.scene_changed();
189}
190
119void ms::SurfaceStack::add_surface(191void ms::SurfaceStack::add_surface(
120 std::shared_ptr<Surface> const& surface,192 std::shared_ptr<Surface> const& surface,
121 DepthId depth,193 DepthId depth,
@@ -264,6 +336,12 @@
264 { observer->surfaces_reordered(); });336 { observer->surfaces_reordered(); });
265}337}
266338
339void ms::Observers::scene_changed()
340{
341 for_each([&](std::shared_ptr<Observer> const& observer)
342 { observer->scene_changed(); });
343}
344
267void ms::Observers::surface_exists(ms::Surface* surface)345void ms::Observers::surface_exists(ms::Surface* surface)
268{346{
269 for_each([&](std::shared_ptr<Observer> const& observer)347 for_each([&](std::shared_ptr<Observer> const& observer)
270348
=== modified file 'src/server/scene/surface_stack.h'
--- src/server/scene/surface_stack.h 2014-09-10 12:50:53 +0000
+++ src/server/scene/surface_stack.h 2014-09-18 16:04:44 +0000
@@ -24,7 +24,7 @@
24#include "mir/compositor/scene.h"24#include "mir/compositor/scene.h"
25#include "mir/scene/depth_id.h"25#include "mir/scene/depth_id.h"
26#include "mir/scene/observer.h"26#include "mir/scene/observer.h"
27#include "mir/input/input_targets.h"27#include "mir/input/scene.h"
2828
29#include "mir/basic_observers.h"29#include "mir/basic_observers.h"
3030
@@ -36,6 +36,10 @@
3636
37namespace mir37namespace mir
38{38{
39namespace graphics
40{
41class Renderable;
42}
39/// Management of Surface objects. Includes the model (SurfaceStack and Surface43/// Management of Surface objects. Includes the model (SurfaceStack and Surface
40/// classes) and controller (SurfaceController) elements of an MVC design.44/// classes) and controller (SurfaceController) elements of an MVC design.
41namespace scene45namespace scene
@@ -52,6 +56,7 @@
52 void surface_added(Surface* surface) override;56 void surface_added(Surface* surface) override;
53 void surface_removed(Surface* surface) override;57 void surface_removed(Surface* surface) override;
54 void surfaces_reordered() override;58 void surfaces_reordered() override;
59 void scene_changed() override;
55 void surface_exists(Surface* surface) override;60 void surface_exists(Surface* surface) override;
56 void end_observation();61 void end_observation();
5762
@@ -59,7 +64,7 @@
59 using BasicObservers<Observer>::remove;64 using BasicObservers<Observer>::remove;
60};65};
6166
62class SurfaceStack : public compositor::Scene, public input::InputTargets, public SurfaceStackModel67class SurfaceStack : public compositor::Scene, public input::Scene, public SurfaceStackModel
63{68{
64public:69public:
65 explicit SurfaceStack(70 explicit SurfaceStack(
@@ -71,7 +76,7 @@
71 void register_compositor(compositor::CompositorID id) override;76 void register_compositor(compositor::CompositorID id) override;
72 void unregister_compositor(compositor::CompositorID id) override;77 void unregister_compositor(compositor::CompositorID id) override;
7378
74 // From InputTargets79 // From Scene
75 void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& callback);80 void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& callback);
7681
77 virtual void remove_surface(std::weak_ptr<Surface> const& surface) override;82 virtual void remove_surface(std::weak_ptr<Surface> const& surface) override;
@@ -85,6 +90,12 @@
85 90
86 void add_observer(std::shared_ptr<Observer> const& observer) override;91 void add_observer(std::shared_ptr<Observer> const& observer) override;
87 void remove_observer(std::weak_ptr<Observer> const& observer) override;92 void remove_observer(std::weak_ptr<Observer> const& observer) override;
93
94 // Intended for input overlays, as described in mir::input::Scene documentation.
95 void add_input_visualization(std::shared_ptr<graphics::Renderable> const& overlay);
96 void remove_input_visualization(std::weak_ptr<graphics::Renderable> const& overlay);
97
98 void emit_scene_changed() override;
8899
89private:100private:
90 SurfaceStack(const SurfaceStack&) = delete;101 SurfaceStack(const SurfaceStack&) = delete;
@@ -101,6 +112,8 @@
101 std::map<DepthId, Layer> layers_by_depth;112 std::map<DepthId, Layer> layers_by_depth;
102 std::map<Surface*,std::shared_ptr<RenderingTracker>> rendering_trackers;113 std::map<Surface*,std::shared_ptr<RenderingTracker>> rendering_trackers;
103 std::set<compositor::CompositorID> registered_compositors;114 std::set<compositor::CompositorID> registered_compositors;
115
116 std::vector<std::shared_ptr<graphics::Renderable>> overlays;
104117
105 Observers observers;118 Observers observers;
106};119};
107120
=== modified file 'src/server/symbols.map'
--- src/server/symbols.map 2014-09-10 12:50:53 +0000
+++ src/server/symbols.map 2014-09-18 16:04:44 +0000
@@ -108,6 +108,7 @@
108 mir::DefaultServerConfiguration::the_buffer_allocator*;108 mir::DefaultServerConfiguration::the_buffer_allocator*;
109 mir::DefaultServerConfiguration::the_buffer_initializer*;109 mir::DefaultServerConfiguration::the_buffer_initializer*;
110 mir::DefaultServerConfiguration::the_buffer_stream_factory*;110 mir::DefaultServerConfiguration::the_buffer_stream_factory*;
111 mir::DefaultServerConfiguration::the_buffer_writer*;
111 mir::DefaultServerConfiguration::the_clock*;112 mir::DefaultServerConfiguration::the_clock*;
112 mir::DefaultServerConfiguration::the_composite_event_filter*;113 mir::DefaultServerConfiguration::the_composite_event_filter*;
113 mir::DefaultServerConfiguration::the_compositor*;114 mir::DefaultServerConfiguration::the_compositor*;
@@ -149,7 +150,7 @@
149 mir::DefaultServerConfiguration::the_input_sender*;150 mir::DefaultServerConfiguration::the_input_sender*;
150 mir::DefaultServerConfiguration::the_input_send_observer*;151 mir::DefaultServerConfiguration::the_input_send_observer*;
151 mir::DefaultServerConfiguration::the_input_targeter*;152 mir::DefaultServerConfiguration::the_input_targeter*;
152 mir::DefaultServerConfiguration::the_input_targets*;153 mir::DefaultServerConfiguration::the_input_scene*;
153 mir::DefaultServerConfiguration::the_logger*;154 mir::DefaultServerConfiguration::the_logger*;
154 mir::DefaultServerConfiguration::the_main_loop*;155 mir::DefaultServerConfiguration::the_main_loop*;
155 mir::DefaultServerConfiguration::the_mediating_display_changer*;156 mir::DefaultServerConfiguration::the_mediating_display_changer*;
@@ -407,6 +408,8 @@
407 mir::input::TouchVisualizer::?TouchVisualizer*;408 mir::input::TouchVisualizer::?TouchVisualizer*;
408 mir::input::TouchVisualizer::TouchVisualizer*;409 mir::input::TouchVisualizer::TouchVisualizer*;
409 mir::input::TouchVisualizer::visualize_touches*;410 mir::input::TouchVisualizer::visualize_touches*;
411 mir::input::TouchVisualizer::enable*;
412 mir::input::TouchVisualizer::disable*;
410 mir::input::VTFilter::handle*;413 mir::input::VTFilter::handle*;
411 mir::logging::GlogLogger::GlogLogger*;414 mir::logging::GlogLogger::GlogLogger*;
412 mir::logging::GlogLogger::log*;415 mir::logging::GlogLogger::log*;
413416
=== modified file 'tests/acceptance-tests/test_nested_mir.cpp'
--- tests/acceptance-tests/test_nested_mir.cpp 2014-09-10 12:50:53 +0000
+++ tests/acceptance-tests/test_nested_mir.cpp 2014-09-18 16:04:44 +0000
@@ -132,6 +132,11 @@
132 return adaptee->create_internal_client();132 return adaptee->create_internal_client();
133 }133 }
134134
135 std::shared_ptr<mg::BufferWriter> make_buffer_writer() override
136 {
137 return adaptee->make_buffer_writer();
138 }
139
135 void fill_buffer_package(140 void fill_buffer_package(
136 mg::BufferIPCPacker* packer,141 mg::BufferIPCPacker* packer,
137 mg::Buffer const* buffer,142 mg::Buffer const* buffer,
@@ -139,7 +144,7 @@
139 {144 {
140 return adaptee->fill_buffer_package(packer, buffer, msg_type);145 return adaptee->fill_buffer_package(packer, buffer, msg_type);
141 }146 }
142147
143 std::shared_ptr<mg::Platform> const adaptee;148 std::shared_ptr<mg::Platform> const adaptee;
144};149};
145150
146151
=== modified file 'tests/acceptance-tests/test_touchspot_visualization.cpp'
--- tests/acceptance-tests/test_touchspot_visualization.cpp 2014-06-30 21:33:58 +0000
+++ tests/acceptance-tests/test_touchspot_visualization.cpp 2014-09-18 16:04:44 +0000
@@ -82,6 +82,8 @@
82struct MockTouchVisualizer : public mi::TouchVisualizer82struct MockTouchVisualizer : public mi::TouchVisualizer
83{83{
84 MOCK_METHOD1(visualize_touches, void(std::vector<mi::TouchVisualizer::Spot> const&));84 MOCK_METHOD1(visualize_touches, void(std::vector<mi::TouchVisualizer::Spot> const&));
85 MOCK_METHOD0(enable, void());
86 MOCK_METHOD0(disable, void());
85};87};
8688
87struct ServerConfiguration : mtf::InputTestingServerConfiguration89struct ServerConfiguration : mtf::InputTestingServerConfiguration
8890
=== modified file 'tests/include/mir_test_doubles/null_platform.h'
--- tests/include/mir_test_doubles/null_platform.h 2014-09-10 12:50:53 +0000
+++ tests/include/mir_test_doubles/null_platform.h 2014-09-18 16:04:44 +0000
@@ -35,7 +35,7 @@
35 std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator(35 std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator(
36 const std::shared_ptr<graphics::BufferInitializer>& /*buffer_initializer*/)36 const std::shared_ptr<graphics::BufferInitializer>& /*buffer_initializer*/)
37 {37 {
38 return std::shared_ptr<graphics::GraphicBufferAllocator>();38 return nullptr;
39 }39 }
4040
41 std::shared_ptr<graphics::Display> create_display(41 std::shared_ptr<graphics::Display> create_display(
@@ -53,7 +53,12 @@
5353
54 std::shared_ptr<graphics::InternalClient> create_internal_client()54 std::shared_ptr<graphics::InternalClient> create_internal_client()
55 {55 {
56 return std::shared_ptr<graphics::InternalClient>();56 return nullptr;
57 }
58
59 std::shared_ptr<graphics::BufferWriter> make_buffer_writer()
60 {
61 return nullptr;
57 }62 }
5863
59 void fill_buffer_package(64 void fill_buffer_package(
6065
=== renamed file 'tests/include/mir_test_doubles/stub_input_targets.h' => 'tests/include/mir_test_doubles/stub_input_scene.h'
--- tests/include/mir_test_doubles/stub_input_targets.h 2014-09-10 12:50:53 +0000
+++ tests/include/mir_test_doubles/stub_input_scene.h 2014-09-18 16:04:44 +0000
@@ -16,10 +16,10 @@
16 * Authored by: Robert Carr <robert.carr@canonical.com>16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */17 */
1818
19#ifndef MIR_TEST_DOUBLES_STUB_INPUT_TARGETS_H_19#ifndef MIR_TEST_DOUBLES_STUB_INPUT_SCENE_H_
20#define MIR_TEST_DOUBLES_STUB_INPUT_TARGETS_H_20#define MIR_TEST_DOUBLES_STUB_INPUT_SCENE_H_
2121
22#include "mir/input/input_targets.h"22#include "mir/input/scene.h"
2323
24namespace mir24namespace mir
25{25{
@@ -28,7 +28,7 @@
28namespace doubles28namespace doubles
29{29{
3030
31class StubInputTargets : public input::InputTargets31class StubInputScene : public input::Scene
32{32{
33 void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& ) override33 void for_each(std::function<void(std::shared_ptr<input::Surface> const&)> const& ) override
34 {34 {
@@ -39,10 +39,21 @@
39 void remove_observer(std::weak_ptr<scene::Observer> const& /* observer */)39 void remove_observer(std::weak_ptr<scene::Observer> const& /* observer */)
40 {40 {
41 }41 }
42
43 void add_input_visualization(std::shared_ptr<graphics::Renderable> const& /* overlay */)
44 {
45 }
46 void remove_input_visualization(std::weak_ptr<graphics::Renderable> const& /* overlay */)
47 {
48 }
49
50 void emit_scene_changed()
51 {
52 }
42};53};
4354
44}55}
45}56}
46} // namespace mir57} // namespace mir
4758
48#endif /* MIR_TEST_DOUBLES_STUB_INPUT_TARGETS_H_ */59#endif /* MIR_TEST_DOUBLES_STUB_INPUT_SCENE_H_ */
4960
=== modified file 'tests/include/mir_test_doubles/stub_scene_element.h'
--- tests/include/mir_test_doubles/stub_scene_element.h 2014-06-20 17:57:16 +0000
+++ tests/include/mir_test_doubles/stub_scene_element.h 2014-09-18 16:04:44 +0000
@@ -48,6 +48,11 @@
48 void occluded_in(compositor::CompositorID) override48 void occluded_in(compositor::CompositorID) override
49 {49 {
50 }50 }
51
52 bool is_a_surface() const override
53 {
54 return false;
55 }
5156
52private:57private:
53 std::shared_ptr<graphics::Renderable> const renderable_;58 std::shared_ptr<graphics::Renderable> const renderable_;
5459
=== modified file 'tests/include/mir_test_doubles/stub_touch_visualizer.h'
--- tests/include/mir_test_doubles/stub_touch_visualizer.h 2014-06-26 20:31:56 +0000
+++ tests/include/mir_test_doubles/stub_touch_visualizer.h 2014-09-18 16:04:44 +0000
@@ -33,6 +33,12 @@
33 void visualize_touches(std::vector<Spot> const&) override33 void visualize_touches(std::vector<Spot> const&) override
34 {34 {
35 }35 }
36 void enable() override
37 {
38 }
39 void disable() override
40 {
41 }
36};42};
3743
38}44}
3945
=== modified file 'tests/integration-tests/input/android/test_android_cursor_listener.cpp'
--- tests/integration-tests/input/android/test_android_cursor_listener.cpp 2014-09-10 12:50:53 +0000
+++ tests/integration-tests/input/android/test_android_cursor_listener.cpp 2014-09-18 16:04:44 +0000
@@ -26,7 +26,7 @@
26#include "mir/input/android/default_android_input_configuration.h"26#include "mir/input/android/default_android_input_configuration.h"
27#include "mir/input/event_filter.h"27#include "mir/input/event_filter.h"
28#include "mir/input/cursor_listener.h"28#include "mir/input/cursor_listener.h"
29#include "mir/input/input_targets.h"29#include "mir/input/scene.h"
30#include "mir/input/input_region.h"30#include "mir/input/input_region.h"
31#include "mir/input/input_dispatcher.h"31#include "mir/input/input_dispatcher.h"
32#include "mir/geometry/rectangle.h"32#include "mir/geometry/rectangle.h"
3333
=== modified file 'tests/integration-tests/input/android/test_android_input_manager.cpp'
--- tests/integration-tests/input/android/test_android_input_manager.cpp 2014-09-10 12:50:53 +0000
+++ tests/integration-tests/input/android/test_android_input_manager.cpp 2014-09-18 16:04:44 +0000
@@ -38,7 +38,7 @@
38#include "mir_test_doubles/mock_event_filter.h"38#include "mir_test_doubles/mock_event_filter.h"
39#include "mir_test_doubles/stub_scene_surface.h"39#include "mir_test_doubles/stub_scene_surface.h"
40#include "mir_test_doubles/stub_input_channel.h"40#include "mir_test_doubles/stub_input_channel.h"
41#include "mir_test_doubles/stub_input_targets.h"41#include "mir_test_doubles/stub_scene.h"
42#include "mir_test_doubles/stub_scene.h"42#include "mir_test_doubles/stub_scene.h"
43#include "mir_test_doubles/stub_input_enumerator.h"43#include "mir_test_doubles/stub_input_enumerator.h"
44#include "mir_test_doubles/stub_touch_visualizer.h"44#include "mir_test_doubles/stub_touch_visualizer.h"
4545
=== modified file 'tests/integration-tests/input/test_nested_input.cpp'
--- tests/integration-tests/input/test_nested_input.cpp 2014-09-10 12:50:53 +0000
+++ tests/integration-tests/input/test_nested_input.cpp 2014-09-18 16:04:44 +0000
@@ -25,7 +25,7 @@
25#include "src/server/report/null_report_factory.h"25#include "src/server/report/null_report_factory.h"
26#include "mir/raii.h"26#include "mir/raii.h"
2727
28#include "mir_test_doubles/stub_input_targets.h"28#include "mir_test_doubles/stub_scene.h"
29#include "mir_test_doubles/mock_event_filter.h"29#include "mir_test_doubles/mock_event_filter.h"
30#include "mir_test_doubles/stub_input_enumerator.h"30#include "mir_test_doubles/stub_input_enumerator.h"
31#include "mir_test/fake_shared.h"31#include "mir_test/fake_shared.h"
3232
=== modified file 'tests/mir_test_framework/stubbed_server_configuration.cpp'
--- tests/mir_test_framework/stubbed_server_configuration.cpp 2014-09-10 12:50:53 +0000
+++ tests/mir_test_framework/stubbed_server_configuration.cpp 2014-09-18 16:04:44 +0000
@@ -21,6 +21,7 @@
2121
22#include "mir/options/default_configuration.h"22#include "mir/options/default_configuration.h"
23#include "mir/graphics/buffer_ipc_packer.h"23#include "mir/graphics/buffer_ipc_packer.h"
24#include "mir/graphics/buffer_writer.h"
24#include "mir/graphics/cursor.h"25#include "mir/graphics/cursor.h"
25#include "mir/input/input_channel.h"26#include "mir/input/input_channel.h"
26#include "mir/input/input_manager.h"27#include "mir/input/input_manager.h"
@@ -181,6 +182,18 @@
181 return std::make_shared<mtd::StubDisplay>(display_rects);182 return std::make_shared<mtd::StubDisplay>(display_rects);
182 }183 }
183 184
185 std::shared_ptr<mg::BufferWriter> make_buffer_writer() override
186 {
187 struct NullWriter : mg::BufferWriter
188 {
189 void write(mg::Buffer& /* buffer */,
190 unsigned char const* /* data */, size_t /* size */) override
191 {
192 }
193 };
194 return std::make_shared<NullWriter>();
195 }
196
184 std::vector<geom::Rectangle> const display_rects;197 std::vector<geom::Rectangle> const display_rects;
185};198};
186199
187200
=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
--- tests/unit-tests/frontend/test_session_mediator.cpp 2014-09-12 13:26:47 +0000
+++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-09-18 16:04:44 +0000
@@ -203,6 +203,7 @@
203 MOCK_CONST_METHOD3(fill_buffer_package,203 MOCK_CONST_METHOD3(fill_buffer_package,
204 void(mg::BufferIPCPacker*, mg::Buffer const*, mg::BufferIpcMsgType));204 void(mg::BufferIPCPacker*, mg::Buffer const*, mg::BufferIpcMsgType));
205 MOCK_CONST_METHOD0(egl_native_display, EGLNativeDisplayType());205 MOCK_CONST_METHOD0(egl_native_display, EGLNativeDisplayType());
206 MOCK_METHOD0(make_buffer_writer, std::shared_ptr<mg::BufferWriter>());
206};207};
207208
208struct StubScreencast : mtd::NullScreencast209struct StubScreencast : mtd::NullScreencast
209210
=== modified file 'tests/unit-tests/graphics/mesa/test_shm_buffer.cpp'
--- tests/unit-tests/graphics/mesa/test_shm_buffer.cpp 2014-09-10 12:50:53 +0000
+++ tests/unit-tests/graphics/mesa/test_shm_buffer.cpp 2014-09-18 16:04:44 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as5 * it under the terms of the GNU General Public License version 3 as
66
=== modified file 'tests/unit-tests/graphics/nested/test_nested_platform.cpp'
--- tests/unit-tests/graphics/nested/test_nested_platform.cpp 2014-09-10 12:50:53 +0000
+++ tests/unit-tests/graphics/nested/test_nested_platform.cpp 2014-09-18 16:04:44 +0000
@@ -64,6 +64,11 @@
64 {64 {
65 return {};65 return {};
66 }66 }
67
68 std::shared_ptr<mg::BufferWriter> make_buffer_writer() override
69 {
70 return {};
71 }
6772
68 void fill_buffer_package(73 void fill_buffer_package(
69 mg::BufferIPCPacker*, mg::Buffer const*, mg::BufferIpcMsgType) const override {}74 mg::BufferIPCPacker*, mg::Buffer const*, mg::BufferIpcMsgType) const override {}
7075
=== modified file 'tests/unit-tests/input/CMakeLists.txt'
--- tests/unit-tests/input/CMakeLists.txt 2014-09-10 12:50:53 +0000
+++ tests/unit-tests/input/CMakeLists.txt 2014-09-18 16:04:44 +0000
@@ -5,6 +5,7 @@
5 ${CMAKE_CURRENT_SOURCE_DIR}/test_display_input_region.cpp5 ${CMAKE_CURRENT_SOURCE_DIR}/test_display_input_region.cpp
6 ${CMAKE_CURRENT_SOURCE_DIR}/test_cursor_controller.cpp6 ${CMAKE_CURRENT_SOURCE_DIR}/test_cursor_controller.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/test_xcursor_loader.cpp7 ${CMAKE_CURRENT_SOURCE_DIR}/test_xcursor_loader.cpp
8 ${CMAKE_CURRENT_SOURCE_DIR}/test_touchspot_controller.cpp
8)9)
910
10set(11set(
1112
=== modified file 'tests/unit-tests/input/android/test_android_input_target_enumerator.cpp'
--- tests/unit-tests/input/android/test_android_input_target_enumerator.cpp 2014-09-10 12:50:53 +0000
+++ tests/unit-tests/input/android/test_android_input_target_enumerator.cpp 2014-09-18 16:04:44 +0000
@@ -19,13 +19,14 @@
19#include "src/server/input/android/android_input_target_enumerator.h"19#include "src/server/input/android/android_input_target_enumerator.h"
2020
21#include "mir/input/input_channel.h"21#include "mir/input/input_channel.h"
22#include "mir/input/input_targets.h"22#include "mir/input/scene.h"
23#include "mir/input/surface.h"23#include "mir/input/surface.h"
2424
25#include "mir_test/fake_shared.h"25#include "mir_test/fake_shared.h"
26#include "mir_test_doubles/stub_input_channel.h"26#include "mir_test_doubles/stub_input_channel.h"
27#include "mir_test_doubles/stub_input_handles.h"27#include "mir_test_doubles/stub_input_handles.h"
28#include "mir_test_doubles/stub_input_surface.h"28#include "mir_test_doubles/stub_input_surface.h"
29#include "mir_test_doubles/stub_input_scene.h"
29#include "mir_test_doubles/mock_window_handle_repository.h"30#include "mir_test_doubles/mock_window_handle_repository.h"
3031
31#include <InputDispatcher.h>32#include <InputDispatcher.h>
@@ -48,9 +49,9 @@
48namespace49namespace
49{50{
5051
51struct StubInputTargets : public mi::InputTargets52struct StubScene : public mtd::StubInputScene
52{53{
53 StubInputTargets(std::initializer_list<std::shared_ptr<mi::Surface>> const& target_list)54 StubScene(std::initializer_list<std::shared_ptr<mi::Surface>> const& target_list)
54 : targets(target_list.begin(), target_list.end())55 : targets(target_list.begin(), target_list.end())
55 {56 {
56 }57 }
@@ -85,7 +86,7 @@
85 mtd::MockWindowHandleRepository repository;86 mtd::MockWindowHandleRepository repository;
86 droidinput::sp<droidinput::InputWindowHandle> stub_window_handle1 = new mtd::StubWindowHandle;87 droidinput::sp<droidinput::InputWindowHandle> stub_window_handle1 = new mtd::StubWindowHandle;
87 droidinput::sp<droidinput::InputWindowHandle> stub_window_handle2 = new mtd::StubWindowHandle;88 droidinput::sp<droidinput::InputWindowHandle> stub_window_handle2 = new mtd::StubWindowHandle;
88 StubInputTargets targets({target1, target2});89 StubScene targets({target1, target2});
8990
90 Sequence seq2;91 Sequence seq2;
91 EXPECT_CALL(repository, handle_for_channel(92 EXPECT_CALL(repository, handle_for_channel(
9293
=== modified file 'tests/unit-tests/input/test_cursor_controller.cpp'
--- tests/unit-tests/input/test_cursor_controller.cpp 2014-09-10 12:50:53 +0000
+++ tests/unit-tests/input/test_cursor_controller.cpp 2014-09-18 16:04:44 +0000
@@ -19,7 +19,7 @@
19#include "src/server/input/cursor_controller.h"19#include "src/server/input/cursor_controller.h"
2020
21#include "mir/input/surface.h"21#include "mir/input/surface.h"
22#include "mir/input/input_targets.h"22#include "mir/input/scene.h"
23#include "mir/scene/observer.h"23#include "mir/scene/observer.h"
24#include "mir/scene/surface_observer.h"24#include "mir/scene/surface_observer.h"
25#include "mir/graphics/cursor_image.h"25#include "mir/graphics/cursor_image.h"
@@ -29,6 +29,7 @@
2929
30#include "mir_test/fake_shared.h"30#include "mir_test/fake_shared.h"
31#include "mir_test_doubles/stub_scene_surface.h"31#include "mir_test_doubles/stub_scene_surface.h"
32#include "mir_test_doubles/stub_input_scene.h"
3233
33#include <gtest/gtest.h>34#include <gtest/gtest.h>
34#include <gmock/gmock.h>35#include <gmock/gmock.h>
@@ -166,9 +167,9 @@
166 std::vector<std::shared_ptr<ms::SurfaceObserver>> observers;167 std::vector<std::shared_ptr<ms::SurfaceObserver>> observers;
167};168};
168169
169struct StubInputTargets : public mi::InputTargets170struct StubScene : public mtd::StubInputScene
170{171{
171 StubInputTargets(std::initializer_list<std::shared_ptr<ms::Surface>> const& targets)172 StubScene(std::initializer_list<std::shared_ptr<ms::Surface>> const& targets)
172 : targets(targets.begin(), targets.end())173 : targets(targets.begin(), targets.end())
173 {174 {
174 }175 }
@@ -243,7 +244,7 @@
243{244{
244 using namespace ::testing;245 using namespace ::testing;
245246
246 StubInputTargets targets({});247 StubScene targets({});
247 248
248 mi::CursorController controller(mt::fake_shared(targets),249 mi::CursorController controller(mt::fake_shared(targets),
249 mt::fake_shared(cursor), default_cursor_image);250 mt::fake_shared(cursor), default_cursor_image);
@@ -262,7 +263,7 @@
262263
263 StubInputSurface surface{rect_1_1_1_1,264 StubInputSurface surface{rect_1_1_1_1,
264 std::make_shared<NamedCursorImage>(cursor_name_1)};265 std::make_shared<NamedCursorImage>(cursor_name_1)};
265 StubInputTargets targets({mt::fake_shared(surface)});266 StubScene targets({mt::fake_shared(surface)});
266 267
267 mi::CursorController controller(mt::fake_shared(targets),268 mi::CursorController controller(mt::fake_shared(targets),
268 mt::fake_shared(cursor), default_cursor_image);269 mt::fake_shared(cursor), default_cursor_image);
@@ -279,7 +280,7 @@
279280
280 StubInputSurface surface{rect_1_1_1_1,281 StubInputSurface surface{rect_1_1_1_1,
281 nullptr};282 nullptr};
282 StubInputTargets targets({mt::fake_shared(surface)});283 StubScene targets({mt::fake_shared(surface)});
283 284
284 mi::CursorController controller(mt::fake_shared(targets),285 mi::CursorController controller(mt::fake_shared(targets),
285 mt::fake_shared(cursor), default_cursor_image);286 mt::fake_shared(cursor), default_cursor_image);
@@ -296,7 +297,7 @@
296297
297 StubInputSurface surface_1{rect_1_1_1_1, std::make_shared<NamedCursorImage>(cursor_name_1)};298 StubInputSurface surface_1{rect_1_1_1_1, std::make_shared<NamedCursorImage>(cursor_name_1)};
298 StubInputSurface surface_2{rect_1_1_1_1, std::make_shared<NamedCursorImage>(cursor_name_2)};299 StubInputSurface surface_2{rect_1_1_1_1, std::make_shared<NamedCursorImage>(cursor_name_2)};
299 StubInputTargets targets({mt::fake_shared(surface_1), mt::fake_shared(surface_2)});300 StubScene targets({mt::fake_shared(surface_1), mt::fake_shared(surface_2)});
300 301
301 mi::CursorController controller(mt::fake_shared(targets),302 mi::CursorController controller(mt::fake_shared(targets),
302 mt::fake_shared(cursor), default_cursor_image);303 mt::fake_shared(cursor), default_cursor_image);
@@ -313,7 +314,7 @@
313314
314 StubInputSurface surface{rect_1_1_1_1,315 StubInputSurface surface{rect_1_1_1_1,
315 std::make_shared<NamedCursorImage>(cursor_name_1)};316 std::make_shared<NamedCursorImage>(cursor_name_1)};
316 StubInputTargets targets({mt::fake_shared(surface)});317 StubScene targets({mt::fake_shared(surface)});
317 318
318 mi::CursorController controller(mt::fake_shared(targets),319 mi::CursorController controller(mt::fake_shared(targets),
319 mt::fake_shared(cursor), default_cursor_image);320 mt::fake_shared(cursor), default_cursor_image);
@@ -336,7 +337,7 @@
336337
337 StubInputSurface surface{rect_1_1_1_1,338 StubInputSurface surface{rect_1_1_1_1,
338 std::make_shared<NamedCursorImage>(cursor_name_1)};339 std::make_shared<NamedCursorImage>(cursor_name_1)};
339 StubInputTargets targets({mt::fake_shared(surface)});340 StubScene targets({mt::fake_shared(surface)});
340 341
341 mi::CursorController controller(mt::fake_shared(targets),342 mi::CursorController controller(mt::fake_shared(targets),
342 mt::fake_shared(cursor), default_cursor_image);343 mt::fake_shared(cursor), default_cursor_image);
@@ -359,7 +360,7 @@
359 // Here we also demonstrate that the cursor begins at 0,0.360 // Here we also demonstrate that the cursor begins at 0,0.
360 StubInputSurface surface{rect_0_0_1_1,361 StubInputSurface surface{rect_0_0_1_1,
361 std::make_shared<NamedCursorImage>(cursor_name_1)};362 std::make_shared<NamedCursorImage>(cursor_name_1)};
362 StubInputTargets targets({});363 StubScene targets({});
363 364
364 mi::CursorController controller(mt::fake_shared(targets),365 mi::CursorController controller(mt::fake_shared(targets),
365 mt::fake_shared(cursor), default_cursor_image);366 mt::fake_shared(cursor), default_cursor_image);
@@ -379,7 +380,7 @@
379 // Here we also demonstrate that the cursor begins at 0,0.380 // Here we also demonstrate that the cursor begins at 0,0.
380 StubInputSurface surface1{rect_0_0_1_1, image};381 StubInputSurface surface1{rect_0_0_1_1, image};
381 StubInputSurface surface2{rect_0_0_1_1, image};382 StubInputSurface surface2{rect_0_0_1_1, image};
382 StubInputTargets targets({});383 StubScene targets({});
383 384
384 mi::CursorController controller(mt::fake_shared(targets),385 mi::CursorController controller(mt::fake_shared(targets),
385 mt::fake_shared(cursor), default_cursor_image);386 mt::fake_shared(cursor), default_cursor_image);
386387
=== added file 'tests/unit-tests/input/test_touchspot_controller.cpp'
--- tests/unit-tests/input/test_touchspot_controller.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/input/test_touchspot_controller.cpp 2014-09-18 16:04:44 +0000
@@ -0,0 +1,199 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Carr <robert.carr@canonical.com>
17 */
18
19#include "src/server/input/touchspot_controller.h"
20
21#include "mir/graphics/graphic_buffer_allocator.h"
22#include "mir/graphics/renderable.h"
23#include "mir/graphics/buffer_writer.h"
24#include "mir_test/fake_shared.h"
25#include "mir_test_doubles/stub_buffer.h"
26#include "mir_test_doubles/stub_scene.h"
27#include "mir_test_doubles/mock_buffer.h"
28#include "mir_test_doubles/stub_input_scene.h"
29
30#include <gmock/gmock.h>
31#include <gtest/gtest.h>
32
33#include <algorithm>
34#include <vector>
35
36#include <assert.h>
37
38namespace mi = mir::input;
39namespace mg = mir::graphics;
40namespace mt = mir::test;
41namespace mtd = mt::doubles;
42namespace geom = mir::geometry;
43
44namespace
45{
46
47struct MockBufferAllocator : public mg::GraphicBufferAllocator
48{
49 MOCK_METHOD1(alloc_buffer, std::shared_ptr<mg::Buffer>(mg::BufferProperties const&));
50 MOCK_METHOD0(supported_pixel_formats, std::vector<MirPixelFormat>(void));
51};
52
53struct StubBufferWriter : public mg::BufferWriter
54{
55 void write(mg::Buffer& /* buffer */,
56 unsigned char const* /* data */, size_t /* size */) override
57 {
58 }
59};
60
61struct StubScene : public mtd::StubInputScene
62{
63 void add_input_visualization(std::shared_ptr<mg::Renderable> const& overlay) override
64 {
65 overlays.push_back(overlay);
66 }
67
68 void remove_input_visualization(std::weak_ptr<mg::Renderable> const& overlay) override
69 {
70 auto l = overlay.lock();
71 assert(l);
72
73 auto it = std::find(overlays.begin(), overlays.end(), l);
74 assert(it != overlays.end());
75
76 overlays.erase(it);
77 }
78
79 void expect_spots_centered_at(std::vector<geom::Point> spots)
80 {
81 int const touchspot_side_in_pixels = 64;
82 for (auto overlay : overlays)
83 {
84 auto top_left_pos = overlay->screen_position().top_left;
85 auto center_pos = geom::Point{top_left_pos.x.as_int() + touchspot_side_in_pixels/2,
86 top_left_pos.y.as_int() + touchspot_side_in_pixels/2};
87 auto it = std::find(spots.begin(), spots.end(), center_pos);
88 EXPECT_FALSE(it == spots.end());
89 spots.erase(it);
90 }
91 // If there are left over spots then we didn't have an overlay corresponding to one
92 EXPECT_EQ(0, spots.size());
93 }
94
95 std::vector<std::shared_ptr<mg::Renderable>> overlays;
96};
97
98struct TestTouchspotController : public ::testing::Test
99{
100 TestTouchspotController()
101 : allocator(std::make_shared<MockBufferAllocator>()),
102 writer(std::make_shared<StubBufferWriter>()),
103 scene(std::make_shared<StubScene>())
104 {
105 }
106 std::shared_ptr<MockBufferAllocator> const allocator;
107 std::shared_ptr<mg::BufferWriter> const writer;
108 std::shared_ptr<StubScene> const scene;
109};
110
111MATCHER(SoftwareBuffer, "")
112{
113 auto properties = static_cast<mg::BufferProperties const&>(arg);
114 if (properties.usage != mg::BufferUsage::software)
115 return false;
116 return true;
117}
118
119}
120
121TEST_F(TestTouchspotController, allocates_software_buffer_for_touchspots)
122{
123 using namespace ::testing;
124
125 EXPECT_CALL(*allocator, alloc_buffer(SoftwareBuffer())).Times(1)
126 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
127 mi::TouchspotController controller(allocator, writer, scene);
128}
129
130TEST_F(TestTouchspotController, touches_result_in_renderables_in_stack)
131{
132 using namespace ::testing;
133
134 EXPECT_CALL(*allocator, alloc_buffer(SoftwareBuffer())).Times(1)
135 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
136 mi::TouchspotController controller(allocator, writer, scene);
137 controller.enable();
138
139 controller.visualize_touches({ {{0,0}, 1} });
140
141 scene->expect_spots_centered_at({{0, 0}});
142}
143
144TEST_F(TestTouchspotController, spots_move)
145{
146 using namespace ::testing;
147
148 EXPECT_CALL(*allocator, alloc_buffer(SoftwareBuffer())).Times(1)
149 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
150 mi::TouchspotController controller(allocator, writer, scene);
151 controller.enable();
152
153 controller.visualize_touches({ {{0,0}, 1} });
154 scene->expect_spots_centered_at({{0, 0}});
155 controller.visualize_touches({ {{1,1}, 1} });
156 scene->expect_spots_centered_at({{1, 1}});
157}
158
159TEST_F(TestTouchspotController, multiple_spots)
160{
161 using namespace ::testing;
162
163 EXPECT_CALL(*allocator, alloc_buffer(SoftwareBuffer())).Times(1)
164 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
165 mi::TouchspotController controller(allocator, writer, scene);
166 controller.enable();
167
168 controller.visualize_touches({ {{0,0}, 1}, {{1, 1}, 1}, {{3, 3}, 1} });
169 scene->expect_spots_centered_at({{0, 0}, {1, 1}, {3, 3}});
170 controller.visualize_touches({ {{0,0}, 1}, {{1, 1}, 1}, {{3, 3}, 1}, {{5, 5}, 1} });
171 scene->expect_spots_centered_at({{0, 0}, {1, 1}, {3, 3}, {5, 5}});
172 controller.visualize_touches({ {{1,1}, 1} });
173 scene->expect_spots_centered_at({{1, 1}});
174 controller.visualize_touches({});
175 scene->expect_spots_centered_at({});
176}
177
178// This leaves some semantics undefined, i,e. if the touchspot controller is enabled/disabled
179// during a gesture do the spots appear/dissapear? I've been unable to develop a strong opinion
180// on this semantic, so I am leaving it unspecified ~racarr
181TEST_F(TestTouchspotController, touches_do_not_result_in_renderables_in_stack_when_disabled)
182{
183 using namespace ::testing;
184
185 EXPECT_CALL(*allocator, alloc_buffer(SoftwareBuffer())).Times(1)
186 .WillOnce(Return(std::make_shared<mtd::StubBuffer>()));
187 mi::TouchspotController controller(allocator, writer, scene);
188 controller.enable();
189
190 controller.disable();
191 controller.visualize_touches({ {{0,0}, 1} });
192
193 scene->expect_spots_centered_at({});
194
195 controller.enable();
196 controller.visualize_touches({ {{0,0}, 1} });
197
198 scene->expect_spots_centered_at({{0, 0}});
199}
0200
=== modified file 'tests/unit-tests/scene/test_surface_stack.cpp'
--- tests/unit-tests/scene/test_surface_stack.cpp 2014-09-10 12:50:53 +0000
+++ tests/unit-tests/scene/test_surface_stack.cpp 2014-09-18 16:04:44 +0000
@@ -28,6 +28,7 @@
28#include "mir_test_doubles/stub_input_channel.h"28#include "mir_test_doubles/stub_input_channel.h"
29#include "mir_test/fake_shared.h"29#include "mir_test/fake_shared.h"
30#include "mir_test_doubles/stub_buffer_stream.h"30#include "mir_test_doubles/stub_buffer_stream.h"
31#include "mir_test_doubles/stub_renderable.h"
31#include "mir_test_doubles/mock_buffer_stream.h"32#include "mir_test_doubles/mock_buffer_stream.h"
32#include "mir_test_doubles/null_surface_configurator.h"33#include "mir_test_doubles/null_surface_configurator.h"
3334
@@ -103,6 +104,7 @@
103 MOCK_METHOD1(surface_added, void(ms::Surface*));104 MOCK_METHOD1(surface_added, void(ms::Surface*));
104 MOCK_METHOD1(surface_removed, void(ms::Surface*));105 MOCK_METHOD1(surface_removed, void(ms::Surface*));
105 MOCK_METHOD0(surfaces_reordered, void());106 MOCK_METHOD0(surfaces_reordered, void());
107 MOCK_METHOD0(scene_changed, void());
106108
107 MOCK_METHOD1(surface_exists, void(ms::Surface*));109 MOCK_METHOD1(surface_exists, void(ms::Surface*));
108 MOCK_METHOD0(end_observation, void());110 MOCK_METHOD0(end_observation, void());
@@ -673,6 +675,100 @@
673 stack.add_surface(stub_surface1, default_params.depth, default_params.input_mode);675 stack.add_surface(stub_surface1, default_params.depth, default_params.input_mode);
674}676}
675677
678TEST_F(SurfaceStack, scene_observer_notified_of_add_and_remove_input_visualization)
679{
680 using namespace ::testing;
681
682 MockSceneObserver observer;
683 mtd::StubRenderable r;
684
685 InSequence seq;
686 EXPECT_CALL(observer, scene_changed()).Times(2);
687
688 stack.add_observer(mt::fake_shared(observer));
689
690 stack.add_input_visualization(mt::fake_shared(r));
691 stack.remove_input_visualization(mt::fake_shared(r));
692}
693
694TEST_F(SurfaceStack, overlays_do_not_appear_in_input_enumeration)
695{
696 mtd::StubRenderable r;
697
698 stack.add_surface(stub_surface1, default_params.depth, default_params.input_mode);
699 stack.add_surface(stub_surface2, default_params.depth, default_params.input_mode);
700
701 // Configure surface1 and surface2 to appear in input enumeration.
702 stub_surface1->configure(mir_surface_attrib_visibility, MirSurfaceVisibility::mir_surface_visibility_exposed);
703 stub_surface2->configure(mir_surface_attrib_visibility, MirSurfaceVisibility::mir_surface_visibility_exposed);
704
705 stack.add_input_visualization(mt::fake_shared(r));
706
707 unsigned int observed_input_targets = 0;
708 stack.for_each([&observed_input_targets](std::shared_ptr<mi::Surface> const&)
709 {
710 observed_input_targets++;
711 });
712 EXPECT_EQ(2, observed_input_targets);
713}
714
715TEST_F(SurfaceStack, overlays_appear_at_top_of_renderlist)
716{
717 using namespace ::testing;
718
719 mtd::StubRenderable r;
720
721 stack.add_surface(stub_surface1, default_params.depth, default_params.input_mode);
722 stack.add_input_visualization(mt::fake_shared(r));
723 stack.add_surface(stub_surface2, default_params.depth, default_params.input_mode);
724
725 EXPECT_THAT(
726 stack.scene_elements_for(compositor_id),
727 ElementsAre(
728 SceneElementFor(stub_surface1),
729 SceneElementFor(stub_surface2),
730 SceneElementFor(mt::fake_shared(r))));
731}
732
733TEST_F(SurfaceStack, removed_overlays_are_removed)
734{
735 using namespace ::testing;
736
737 mtd::StubRenderable r;
738
739 stack.add_surface(stub_surface1, default_params.depth, default_params.input_mode);
740 stack.add_input_visualization(mt::fake_shared(r));
741 stack.add_surface(stub_surface2, default_params.depth, default_params.input_mode);
742
743 EXPECT_THAT(
744 stack.scene_elements_for(compositor_id),
745 ElementsAre(
746 SceneElementFor(stub_surface1),
747 SceneElementFor(stub_surface2),
748 SceneElementFor(mt::fake_shared(r))));
749
750 stack.remove_input_visualization(mt::fake_shared(r));
751
752 EXPECT_THAT(
753 stack.scene_elements_for(compositor_id),
754 ElementsAre(
755 SceneElementFor(stub_surface1),
756 SceneElementFor(stub_surface2)));
757}
758
759TEST_F(SurfaceStack, scene_observers_notified_of_generic_scene_change)
760{
761 MockSceneObserver o1, o2;
762
763 EXPECT_CALL(o1, scene_changed()).Times(1);
764 EXPECT_CALL(o2, scene_changed()).Times(1);
765
766 stack.add_observer(mt::fake_shared(o1));
767 stack.add_observer(mt::fake_shared(o2));
768
769 stack.emit_scene_changed();
770}
771
676TEST_F(SurfaceStack, only_enumerates_exposed_input_surfaces)772TEST_F(SurfaceStack, only_enumerates_exposed_input_surfaces)
677{773{
678 using namespace ::testing;774 using namespace ::testing;

Subscribers

People subscribed via source and target branches