OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "components/view_manager/native_viewport/native_viewport.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "components/view_manager/event_dispatcher.h" | |
9 #include "components/view_manager/gles2/gpu_state.h" | |
10 #include "components/view_manager/native_viewport/platform_viewport_headless.h" | |
11 #include "ui/events/event.h" | |
12 #include "ui/gfx/geometry/size.h" | |
13 | |
14 namespace view_manager { | |
15 | |
16 NativeViewport::NativeViewport( | |
17 const gfx::Size& size, | |
18 bool is_headless, | |
19 const scoped_refptr<gles2::GpuState>& gpu_state, | |
20 EventDispatcher* event_dispatcher, | |
21 const ViewDestroyedCallback& view_destroyed_callback) | |
22 : context_provider_( | |
23 new native_viewport::OnscreenContextProvider(gpu_state)), | |
24 size_(size), | |
25 device_scale_factor_(1.f), | |
26 metrics_ready_(false), | |
27 event_dispatcher_(event_dispatcher), | |
28 view_destroyed_callback_(view_destroyed_callback), | |
29 weak_factory_(this) { | |
30 if (is_headless) { | |
31 platform_viewport_ = | |
32 native_viewport::PlatformViewportHeadless::Create(this); | |
33 } else { | |
34 platform_viewport_ = native_viewport::PlatformViewport::Create(this); | |
35 } | |
36 platform_viewport_->Init(gfx::Rect(size)); | |
37 } | |
38 | |
39 NativeViewport::~NativeViewport() { | |
40 // Destroy before |platform_viewport_| because this will destroy | |
41 // CommandBufferDriver objects that contain child windows. Otherwise if this | |
42 // class destroys its window first, X errors will occur. | |
43 context_provider_.reset(); | |
44 | |
45 // Destroy the NativeViewport early on as it may call us back during | |
46 // destruction and we want to be in a known state. | |
47 platform_viewport_.reset(); | |
48 } | |
49 | |
50 void NativeViewport::RequestMetrics( | |
51 const RequestMetricsCallback& callback) { | |
52 if (metrics_ready_) { | |
53 // Make sure we can't re-entrantly call this callback again. | |
54 metrics_ready_ = false; | |
55 callback.Run(size_, device_scale_factor_); | |
56 return; | |
57 } | |
58 metrics_callback_ = callback; | |
59 } | |
60 | |
61 void NativeViewport::Show() { | |
62 platform_viewport_->Show(); | |
63 } | |
64 | |
65 void NativeViewport::Hide() { | |
66 platform_viewport_->Hide(); | |
67 } | |
68 | |
69 void NativeViewport::Close() { | |
70 DCHECK(platform_viewport_); | |
71 platform_viewport_->Close(); | |
72 } | |
73 | |
74 void NativeViewport::SetSize(const gfx::Size& size) { | |
75 platform_viewport_->SetBounds(gfx::Rect(size)); | |
76 } | |
77 | |
78 void NativeViewport::GetContextProvider( | |
79 mojo::InterfaceRequest<mojo::ContextProvider> request) { | |
80 context_provider_->Bind(request.Pass()); | |
81 } | |
82 | |
83 void NativeViewport::OnMetricsChanged(const gfx::Size& size, | |
84 float device_scale_factor) { | |
85 if (size_ == size && device_scale_factor_ == device_scale_factor) | |
86 return; | |
87 | |
88 size_ = size; | |
89 device_scale_factor_ = device_scale_factor; | |
90 metrics_ready_ = true; | |
91 if (!metrics_callback_.is_null()) { | |
92 metrics_ready_ = false; | |
93 metrics_callback_.Run(size_, device_scale_factor_); | |
94 // TODO(fsamuel): calling the callback can reentrantly change the | |
95 // metrics_callback. | |
96 //metrics_callback_.reset(); | |
97 } | |
98 } | |
99 | |
100 void NativeViewport::OnAcceleratedWidgetAvailable( | |
101 gfx::AcceleratedWidget widget, | |
102 float device_pixel_ratio) { | |
103 context_provider_->SetAcceleratedWidget(widget); | |
104 // TODO: The metrics here might not match the actual window size on android | |
105 // where we don't know the actual size until the first OnMetricsChanged call. | |
106 OnMetricsChanged(size_, device_pixel_ratio); | |
107 } | |
108 | |
109 void NativeViewport::OnAcceleratedWidgetDestroyed() { | |
110 context_provider_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); | |
111 } | |
112 | |
113 bool NativeViewport::OnEvent(mojo::EventPtr event) { | |
114 if (event.is_null() || !event_dispatcher_) | |
115 return false; | |
116 | |
117 mojo::Callback<void()> callback; | |
sky
2015/06/04 22:37:58
Alot of this code can be cleaned up too.
Fady Samuel
2015/06/05 22:14:31
Done.
| |
118 switch (event->action) { | |
119 case mojo::EVENT_TYPE_POINTER_MOVE: { | |
120 // TODO(sky): add logic to remember last event location and not send if | |
121 // the same. | |
122 if (pointers_waiting_on_ack_.count(event->pointer_data->pointer_id)) | |
123 return false; | |
124 | |
125 pointers_waiting_on_ack_.insert(event->pointer_data->pointer_id); | |
126 callback = | |
127 base::Bind(&NativeViewport::AckEvent, weak_factory_.GetWeakPtr(), | |
128 event->pointer_data->pointer_id); | |
129 break; | |
130 } | |
131 | |
132 case mojo::EVENT_TYPE_POINTER_CANCEL: | |
133 pointers_waiting_on_ack_.clear(); | |
134 break; | |
135 | |
136 case mojo::EVENT_TYPE_POINTER_UP: | |
137 pointers_waiting_on_ack_.erase(event->pointer_data->pointer_id); | |
138 break; | |
139 | |
140 default: | |
141 break; | |
142 } | |
143 | |
144 event_dispatcher_->OnEvent(event.Pass(), callback); | |
145 return false; | |
146 } | |
147 | |
148 void NativeViewport::OnDestroyed() { | |
149 if (!view_destroyed_callback_.is_null()) | |
150 view_destroyed_callback_.Run(); | |
151 } | |
152 | |
153 void NativeViewport::AckEvent(int32 pointer_id) { | |
154 pointers_waiting_on_ack_.erase(pointer_id); | |
155 } | |
156 | |
157 } // namespace view_manager | |
OLD | NEW |