+class html_client
+ : public CefClient
+ , public CefRenderHandler
+ , public CefLifeSpanHandler
+ , public CefLoadHandler
+{
+ std::wstring url_;
+ spl::shared_ptr<diagnostics::graph> graph_;
+ boost::timer tick_timer_;
+ boost::timer frame_timer_;
+ boost::timer paint_timer_;
+
+ spl::shared_ptr<core::frame_factory> frame_factory_;
+ core::video_format_desc format_desc_;
+ tbb::concurrent_queue<std::wstring> javascript_before_load_;
+ tbb::atomic<bool> loaded_;
+ tbb::atomic<bool> removed_;
+ tbb::atomic<bool> animation_frame_requested_;
+ std::queue<core::draw_frame> frames_;
+ mutable boost::mutex frames_mutex_;
+
+ core::draw_frame last_frame_;
+ core::draw_frame last_progressive_frame_;
+ mutable boost::mutex last_frame_mutex_;
+
+ CefRefPtr<CefBrowser> browser_;
+
+ executor executor_;
+
+public:
+
+ html_client(
+ spl::shared_ptr<core::frame_factory> frame_factory,
+ const core::video_format_desc& format_desc,
+ const std::wstring& url)
+ : url_(url)
+ , frame_factory_(std::move(frame_factory))
+ , format_desc_(format_desc)
+ , last_frame_(core::draw_frame::empty())
+ , last_progressive_frame_(core::draw_frame::empty())
+ , executor_(L"html_producer")
+ {
+ graph_->set_color("browser-tick-time", diagnostics::color(0.1f, 1.0f, 0.1f));
+ graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f));
+ graph_->set_color("late-frame", diagnostics::color(0.6f, 0.3f, 0.9f));
+ graph_->set_text(print());
+ diagnostics::register_graph(graph_);
+
+ loaded_ = false;
+ removed_ = false;
+ animation_frame_requested_ = false;
+ executor_.begin_invoke([&]{ update(); });
+ }
+
+ core::draw_frame receive()
+ {
+ auto frame = last_frame();
+ executor_.begin_invoke([&]{ update(); });
+ return frame;
+ }
+
+ core::draw_frame last_frame() const
+ {
+ return lock(last_frame_mutex_, [&]