1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mandoline/ui/aura/surface_binding.h"
10 #include "base/lazy_instance.h"
11 #include "base/threading/thread_local.h"
12 #include "cc/output/compositor_frame.h"
13 #include "cc/output/output_surface.h"
14 #include "cc/output/output_surface_client.h"
15 #include "cc/output/software_output_device.h"
16 #include "cc/resources/shared_bitmap_manager.h"
17 #include "components/mus/public/cpp/view.h"
18 #include "components/mus/public/cpp/view_tree_connection.h"
19 #include "components/mus/public/interfaces/gpu.mojom.h"
20 #include "mandoline/ui/aura/window_tree_host_mojo.h"
21 #include "mojo/application/public/cpp/connect.h"
22 #include "mojo/application/public/interfaces/shell.mojom.h"
23 #include "mojo/cc/context_provider_mojo.h"
24 #include "mojo/cc/output_surface_mojo.h"
25 #include "mojo/converters/geometry/geometry_type_converters.h"
26 #include "mojo/converters/surfaces/surfaces_type_converters.h"
27 #include "mojo/public/cpp/bindings/binding.h"
31 void OnGotContentHandlerID(uint32_t content_handler_id
) {}
34 // PerConnectionState ----------------------------------------------------------
36 // State needed per ViewManager. Provides the real implementation of
37 // CreateOutputSurface. SurfaceBinding obtains a pointer to the
38 // PerConnectionState appropriate for the ViewManager. PerConnectionState is
39 // stored in a thread local map. When no more refereces to a PerConnectionState
40 // remain the PerConnectionState is deleted and the underlying map cleaned up.
41 class SurfaceBinding::PerConnectionState
42 : public base::RefCounted
<PerConnectionState
> {
44 static PerConnectionState
* Get(mojo::Shell
* shell
,
45 mus::ViewTreeConnection
* connection
);
47 scoped_ptr
<cc::OutputSurface
> CreateOutputSurface(mus::View
* view
);
50 typedef std::map
<mus::ViewTreeConnection
*, PerConnectionState
*>
53 friend class base::RefCounted
<PerConnectionState
>;
55 PerConnectionState(mojo::Shell
* shell
, mus::ViewTreeConnection
* connection
);
56 ~PerConnectionState();
60 static base::LazyInstance
<
61 base::ThreadLocalPointer
<ConnectionToStateMap
>>::Leaky view_states
;
64 mus::ViewTreeConnection
* connection_
;
66 // Set of state needed to create an OutputSurface.
69 DISALLOW_COPY_AND_ASSIGN(PerConnectionState
);
73 base::LazyInstance
<base::ThreadLocalPointer
<
74 SurfaceBinding::PerConnectionState::ConnectionToStateMap
>>::Leaky
75 SurfaceBinding::PerConnectionState::view_states
;
78 SurfaceBinding::PerConnectionState
* SurfaceBinding::PerConnectionState::Get(
80 mus::ViewTreeConnection
* connection
) {
81 ConnectionToStateMap
* view_map
= view_states
.Pointer()->Get();
83 view_map
= new ConnectionToStateMap
;
84 view_states
.Pointer()->Set(view_map
);
86 if (!(*view_map
)[connection
]) {
87 (*view_map
)[connection
] = new PerConnectionState(shell
, connection
);
88 (*view_map
)[connection
]->Init();
90 return (*view_map
)[connection
];
93 scoped_ptr
<cc::OutputSurface
>
94 SurfaceBinding::PerConnectionState::CreateOutputSurface(mus::View
* view
) {
95 // TODO(sky): figure out lifetime here. Do I need to worry about the return
96 // value outliving this?
97 mojo::CommandBufferPtr cb
;
98 gpu_
->CreateOffscreenGLES2Context(GetProxy(&cb
));
100 scoped_refptr
<cc::ContextProvider
> context_provider(
101 new mojo::ContextProviderMojo(cb
.PassInterface().PassHandle()));
102 return make_scoped_ptr(
103 new mojo::OutputSurfaceMojo(context_provider
, view
->RequestSurface()));
106 SurfaceBinding::PerConnectionState::PerConnectionState(
108 mus::ViewTreeConnection
* connection
)
111 SurfaceBinding::PerConnectionState::~PerConnectionState() {
112 ConnectionToStateMap
* view_map
= view_states
.Pointer()->Get();
114 DCHECK_EQ(this, (*view_map
)[connection_
]);
115 view_map
->erase(connection_
);
116 if (view_map
->empty()) {
118 view_states
.Pointer()->Set(nullptr);
122 void SurfaceBinding::PerConnectionState::Init() {
123 mojo::ServiceProviderPtr service_provider
;
124 mojo::URLRequestPtr
request(mojo::URLRequest::New());
125 request
->url
= mojo::String::From("mojo:mus");
126 shell_
->ConnectToApplication(request
.Pass(), GetProxy(&service_provider
),
128 base::Bind(&OnGotContentHandlerID
));
129 ConnectToService(service_provider
.get(), &gpu_
);
132 // SurfaceBinding --------------------------------------------------------------
134 SurfaceBinding::SurfaceBinding(mojo::Shell
* shell
, mus::View
* view
)
135 : view_(view
), state_(PerConnectionState::Get(shell
, view
->connection())) {}
137 SurfaceBinding::~SurfaceBinding() {
140 scoped_ptr
<cc::OutputSurface
> SurfaceBinding::CreateOutputSurface() {
141 return state_
->CreateOutputSurface(view_
);
144 } // namespace mandoline