~chrisccoulson/oxide/lp1504853

« back to all changes in this revision

Viewing changes to shared/browser/oxide_content_browser_client.cc

Add a QAbstractEventDispatcher implementation that can be attached to threads created by Chromium, which don't otherwise have a Qt event loop. Our implementation basically just delegates to Chromium's message loop, and uses that to dispatch Qt tasks. This allows us to use Qt features such as timers, postEvent and QSocketNotifier on threads that weren't created by Qt. In addition to this:
- Attach our QAbstractEventDispatcher implementation to Chromium's IO thread and geolocation thread
- Kill the dedicated helper thread we created for WebContextDelegateWorker. This can all be handled directly on Chromium's IO thread now
- Kill the helper thread we created for geolocation, and split the location handling between Chromium's geolocation thread and IO thread. The reason we don't do it all on the geolocation thread is that it doesn't have an IO message pump, and so we can't use QSocketNotifier on it

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <vector>
22
22
 
23
23
#include "base/command_line.h"
24
 
#include "base/files/file_path.h"
25
24
#include "base/logging.h"
26
25
#include "base/memory/ref_counted.h"
27
26
#include "base/memory/scoped_ptr.h"
28
 
#include "base/message_loop/message_loop.h"
29
 
#include "base/scoped_native_library.h"
30
27
#include "content/browser/gpu/compositor_util.h"
31
28
#include "content/browser/gpu/gpu_data_manager_impl.h"
32
29
#include "content/browser/gpu/gpu_process_host.h"
33
 
#include "content/public/browser/browser_main_parts.h"
34
30
#include "content/public/browser/certificate_request_result_type.h"
35
31
#include "content/public/browser/render_frame_host.h"
36
32
#include "content/public/browser/render_process_host.h"
37
33
#include "content/public/browser/resource_dispatcher_host.h"
38
34
#include "content/public/common/content_switches.h"
39
35
#include "content/public/common/web_preferences.h"
40
 
#include "net/base/net_module.h"
41
 
#include "third_party/khronos/EGL/egl.h"
42
 
#include "third_party/WebKit/public/platform/WebScreenInfo.h"
43
 
#include "ui/gfx/display.h"
44
 
#include "ui/gfx/screen.h"
45
 
#include "ui/gfx/screen_type_delegate.h"
46
36
#include "ui/gl/gl_context.h"
47
37
#include "ui/gl/gl_implementation.h"
48
38
#include "ui/gl/gl_share_group.h"
49
 
#include "ui/gl/gl_surface.h"
50
39
 
51
 
#include "shared/browser/compositor/oxide_compositor_utils.h"
52
40
#include "shared/common/oxide_constants.h"
53
41
#include "shared/common/oxide_content_client.h"
54
42
#include "shared/common/oxide_messages.h"
55
 
#include "shared/common/oxide_net_resource_provider.h"
56
43
#include "shared/gl/oxide_shared_gl_context.h"
57
44
 
58
45
#include "oxide_access_token_store.h"
59
46
#include "oxide_browser_context.h"
60
47
#include "oxide_browser_process_main.h"
61
 
#include "oxide_default_screen_info.h"
62
48
#include "oxide_form_factor.h"
63
 
#include "oxide_io_thread.h"
64
 
#include "oxide_message_pump.h"
65
49
#include "oxide_resource_dispatcher_host_delegate.h"
66
50
#include "oxide_script_message_dispatcher_browser.h"
67
51
#include "oxide_user_agent_override_provider.h"
78
62
 
79
63
namespace oxide {
80
64
 
81
 
namespace {
82
 
 
83
 
scoped_ptr<base::MessagePump> CreateMessagePumpForUI() {
84
 
  return make_scoped_ptr(
85
 
      ContentClient::instance()->browser()->CreateMessagePumpForUI());
86
 
}
87
 
 
88
 
class ScopedBindGLESAPI {
89
 
 public:
90
 
  ScopedBindGLESAPI();
91
 
  virtual ~ScopedBindGLESAPI();
92
 
 
93
 
 private:
94
 
  typedef EGLBoolean (*_eglBindAPI)(EGLenum);
95
 
  typedef EGLenum (*_eglQueryAPI)(void);
96
 
 
97
 
  bool has_egl_;
98
 
  base::ScopedNativeLibrary egl_lib_;
99
 
  EGLenum orig_api_;
100
 
};
101
 
 
102
 
ScopedBindGLESAPI::ScopedBindGLESAPI()
103
 
    : has_egl_(false),
104
 
      orig_api_(EGL_NONE) {
105
 
  egl_lib_.Reset(base::LoadNativeLibrary(base::FilePath("libEGL.so.1"), NULL));
106
 
  if (!egl_lib_.is_valid()) {
107
 
    return;
108
 
  }
109
 
 
110
 
  _eglBindAPI eglBindAPI = reinterpret_cast<_eglBindAPI>(
111
 
      egl_lib_.GetFunctionPointer("eglBindAPI"));
112
 
  _eglQueryAPI eglQueryAPI = reinterpret_cast<_eglQueryAPI>(
113
 
      egl_lib_.GetFunctionPointer("eglQueryAPI"));
114
 
  if (!eglBindAPI || !eglQueryAPI) {
115
 
    return;
116
 
  }
117
 
 
118
 
  orig_api_ = eglQueryAPI();
119
 
  if (orig_api_ == EGL_NONE) {
120
 
    return;
121
 
  }
122
 
 
123
 
  has_egl_ = true;
124
 
 
125
 
  eglBindAPI(EGL_OPENGL_ES_API);
126
 
}
127
 
 
128
 
ScopedBindGLESAPI::~ScopedBindGLESAPI() {
129
 
  if (!has_egl_) {
130
 
    return;
131
 
  }
132
 
 
133
 
  DCHECK(egl_lib_.is_valid());
134
 
  DCHECK_NE(orig_api_, EGL_NONE);
135
 
 
136
 
  _eglBindAPI eglBindAPI = reinterpret_cast<_eglBindAPI>(
137
 
      egl_lib_.GetFunctionPointer("eglBindAPI"));
138
 
  DCHECK(eglBindAPI);
139
 
 
140
 
  eglBindAPI(orig_api_);
141
 
}
142
 
 
143
 
class Screen : public gfx::Screen {
144
 
 public:
145
 
  Screen() {}
146
 
 
147
 
  bool IsDIPEnabled() FINAL {
148
 
    NOTIMPLEMENTED();
149
 
    return true;
150
 
  }
151
 
 
152
 
  gfx::Point GetCursorScreenPoint() FINAL {
153
 
    NOTIMPLEMENTED();
154
 
    return gfx::Point();
155
 
  }
156
 
 
157
 
  gfx::NativeWindow GetWindowUnderCursor() FINAL {
158
 
    NOTIMPLEMENTED();
159
 
    return NULL;
160
 
  }
161
 
 
162
 
  gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) FINAL {
163
 
    NOTIMPLEMENTED();
164
 
    return NULL;
165
 
  }
166
 
 
167
 
  int GetNumDisplays() const FINAL {
168
 
    NOTIMPLEMENTED();
169
 
    return 1;
170
 
  }
171
 
 
172
 
  std::vector<gfx::Display> GetAllDisplays() const FINAL {
173
 
    NOTIMPLEMENTED();
174
 
    return std::vector<gfx::Display>();
175
 
  }
176
 
 
177
 
  gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const FINAL {
178
 
    NOTIMPLEMENTED();
179
 
    return gfx::Display();
180
 
  }
181
 
 
182
 
  gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const FINAL {
183
 
    NOTIMPLEMENTED();
184
 
    return gfx::Display();
185
 
  }
186
 
 
187
 
  gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const FINAL {
188
 
    NOTIMPLEMENTED();
189
 
    return gfx::Display();
190
 
  }
191
 
 
192
 
  gfx::Display GetPrimaryDisplay() const FINAL {
193
 
    blink::WebScreenInfo info(GetDefaultWebScreenInfo());
194
 
 
195
 
    gfx::Display display;
196
 
    display.set_bounds(info.rect);
197
 
    display.set_work_area(info.availableRect);
198
 
    display.set_device_scale_factor(info.deviceScaleFactor);
199
 
 
200
 
    return display;
201
 
  }
202
 
 
203
 
  void AddObserver(gfx::DisplayObserver* observer) FINAL {
204
 
    NOTIMPLEMENTED();
205
 
  }
206
 
  void RemoveObserver(gfx::DisplayObserver* observer) FINAL {
207
 
    NOTIMPLEMENTED();
208
 
  }
209
 
};
210
 
 
211
 
class BrowserMainParts : public content::BrowserMainParts {
212
 
 public:
213
 
  BrowserMainParts() {}
214
 
  ~BrowserMainParts() {}
215
 
 
216
 
  void PreEarlyInitialization() FINAL {
217
 
    base::MessageLoop::InitMessagePumpForUIFactory(CreateMessagePumpForUI);
218
 
    main_message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI));
219
 
  }
220
 
 
221
 
  int PreCreateThreads() FINAL {
222
 
    // When using EGL, we need GLES for surfaceless contexts. Whilst the
223
 
    // default API is GLES and this will be the selected API on the GPU
224
 
    // thread, it is possible that the embedder has selected a different API
225
 
    // on the main thread. Temporarily switch to GLES whilst we initialize
226
 
    // the GL bits here
227
 
    ScopedBindGLESAPI gles_binder;
228
 
 
229
 
    // Work around a mesa race - see https://launchpad.net/bugs/1267893
230
 
    gfx::GLSurface::InitializeOneOff();
231
 
 
232
 
    gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
233
 
                                   &primary_screen_);
234
 
    io_thread_.reset(new IOThread());
235
 
 
236
 
    return 0;
237
 
  }
238
 
 
239
 
  void PreMainMessageLoopRun() FINAL {
240
 
    CompositorUtils::GetInstance()->Initialize();
241
 
    net::NetModule::SetResourceProvider(NetResourceProvider);
242
 
  }
243
 
 
244
 
  bool MainMessageLoopRun(int* result_code) FINAL {
245
 
    MessageLoopForUI::current()->Start();
246
 
    return true;
247
 
  }
248
 
 
249
 
  void PostMainMessageLoopRun() FINAL {
250
 
    CompositorUtils::GetInstance()->Destroy();
251
 
  }
252
 
 
253
 
  void PostDestroyThreads() FINAL {
254
 
    gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, NULL);
255
 
    io_thread_.reset();
256
 
  }
257
 
 
258
 
 private:
259
 
  scoped_ptr<base::MessageLoop> main_message_loop_;
260
 
  scoped_ptr<IOThread> io_thread_;
261
 
  Screen primary_screen_;
262
 
};
263
 
 
264
 
} // namespace
265
 
 
266
65
content::BrowserMainParts* ContentBrowserClient::CreateBrowserMainParts(
267
66
    const content::MainFunctionParams& parameters) {
268
 
  return new BrowserMainParts();
 
67
  return new BrowserMainParts(CreateBrowserMainPartsDelegate());
269
68
}
270
69
 
271
70
void ContentBrowserClient::RenderProcessWillLaunch(
467
266
  }
468
267
}
469
268
 
470
 
content::LocationProvider*
471
 
ContentBrowserClient::OverrideSystemLocationProvider() {
472
 
  return NULL;
473
 
}
474
 
 
475
269
gfx::GLShareGroup* ContentBrowserClient::GetGLShareGroup() {
476
270
  SharedGLContext* context =
477
271
      BrowserProcessMain::GetInstance()->GetSharedGLContext();