OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "remoting/client/gl_renderer.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "base/threading/thread_task_runner_handle.h" | |
10 #include "remoting/client/gl_canvas.h" | |
11 #include "remoting/client/gl_math.h" | |
12 #include "remoting/client/gl_renderer_delegate.h" | |
13 #include "remoting/client/sys_opengl.h" | |
14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | |
15 | |
16 namespace remoting { | |
17 | |
18 GlRenderer::GlRenderer() : | |
19 weak_factory_(this) { | |
20 weak_ptr_ = weak_factory_.GetWeakPtr(); | |
21 thread_checker_.DetachFromThread(); | |
22 } | |
23 | |
24 GlRenderer::~GlRenderer() { | |
25 DCHECK(thread_checker_.CalledOnValidThread()); | |
Sergey Ulanov
2016/07/27 17:45:33
Don't need this. thread_checker already verifies t
Yuwei
2016/07/27 18:23:10
Done.
| |
26 } | |
27 | |
28 void GlRenderer::SetDelegate(base::WeakPtr<GlRendererDelegate> delegate) { | |
29 DCHECK(!delegate_); | |
30 delegate_ = delegate; | |
31 } | |
32 | |
33 void GlRenderer::RequestCanvasSize() { | |
34 DCHECK(thread_checker_.CalledOnValidThread()); | |
35 if (delegate_) { | |
36 delegate_->OnSizeChanged(canvas_width_, canvas_height_); | |
37 } | |
38 } | |
39 | |
40 void GlRenderer::OnPixelTransformationChanged( | |
41 const std::array<float, 9>& matrix) { | |
42 DCHECK(thread_checker_.CalledOnValidThread()); | |
43 std::array<float, 9> normalized_matrix = matrix; | |
44 NormalizeTransformationMatrix(view_width_, view_height_, canvas_width_, | |
45 canvas_height_, &normalized_matrix); | |
46 canvas_->SetNormalizedTransformation(normalized_matrix); | |
47 RequestRender(); | |
48 } | |
49 | |
50 void GlRenderer::OnCursorMoved(int x, int y) { | |
51 DCHECK(thread_checker_.CalledOnValidThread()); | |
52 cursor_.SetCursorPosition(x, y); | |
53 RequestRender(); | |
54 } | |
55 | |
56 void GlRenderer::OnCursorInputFeedback(int x, int y, float diameter) { | |
57 DCHECK(thread_checker_.CalledOnValidThread()); | |
58 cursor_feedback_.StartAnimation(((float) x) / canvas_width_, | |
Sergey Ulanov
2016/07/27 17:45:33
Do not use c-style casts. https://google.github.io
Yuwei
2016/07/27 18:23:10
Done.
| |
59 ((float) y) / canvas_height_, | |
60 diameter / canvas_width_, | |
61 diameter / canvas_height_); | |
62 RequestRender(); | |
63 } | |
64 | |
65 void GlRenderer::OnCursorVisibilityChanged(bool visible) { | |
66 DCHECK(thread_checker_.CalledOnValidThread()); | |
67 cursor_.SetCursorVisible(visible); | |
68 RequestRender(); | |
69 } | |
70 | |
71 void GlRenderer::OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame, | |
72 const base::Closure& done) { | |
73 DCHECK(thread_checker_.CalledOnValidThread()); | |
74 DCHECK(frame->size().width() > 0 && frame->size().height() > 0); | |
75 if (canvas_width_ != frame->size().width() || | |
76 canvas_height_ != frame->size().height()) { | |
77 if (delegate_) { | |
78 delegate_->OnSizeChanged(frame->size().width(), frame->size().height()); | |
79 } | |
80 canvas_width_ = frame->size().width(); | |
81 canvas_height_ = frame->size().height(); | |
82 cursor_.SetCanvasSize(canvas_width_, canvas_height_); | |
83 } | |
84 | |
85 desktop_.SetVideoFrame(std::move(frame)); | |
86 pending_done_callbacks_.push(done); | |
87 RequestRender(); | |
88 } | |
89 | |
90 void GlRenderer::OnCursorShapeChanged(const protocol::CursorShapeInfo& shape) { | |
91 DCHECK(thread_checker_.CalledOnValidThread()); | |
92 cursor_.SetCursorShape(shape); | |
93 RequestRender(); | |
94 } | |
95 | |
96 void GlRenderer::OnSurfaceCreated(int gl_version) { | |
97 DCHECK(thread_checker_.CalledOnValidThread()); | |
98 // Set the background clear color to black. | |
99 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
100 canvas_.reset(new GlCanvas(gl_version)); | |
101 desktop_.SetCanvas(canvas_.get()); | |
102 cursor_.SetCanvas(canvas_.get()); | |
103 cursor_feedback_.SetCanvas(canvas_.get()); | |
104 } | |
105 | |
106 void GlRenderer::OnSurfaceChanged(int view_width, int view_height) { | |
107 DCHECK(thread_checker_.CalledOnValidThread()); | |
108 DCHECK(view_width > 0 && view_height > 0); | |
109 glViewport(0, 0, view_width, view_height); | |
110 view_width_ = view_width; | |
111 view_height_ = view_height; | |
112 RequestRender(); | |
113 } | |
114 | |
115 void GlRenderer::OnSurfaceDestroyed() { | |
116 DCHECK(thread_checker_.CalledOnValidThread()); | |
117 cursor_feedback_.SetCanvas(nullptr); | |
118 cursor_.SetCanvas(nullptr); | |
119 desktop_.SetCanvas(nullptr); | |
120 canvas_.reset(); | |
121 } | |
122 | |
123 base::WeakPtr<GlRenderer> GlRenderer::GetWeakPtr() { | |
124 return weak_ptr_; | |
125 } | |
126 | |
127 void GlRenderer::RequestRender() { | |
128 if (render_scheduled_) { | |
129 return; | |
130 } | |
131 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
132 FROM_HERE, base::Bind(&GlRenderer::OnRender, weak_ptr_)); | |
133 render_scheduled_ = true; | |
134 } | |
135 | |
136 void GlRenderer::OnRender() { | |
137 DCHECK(thread_checker_.CalledOnValidThread()); | |
138 render_scheduled_ = false; | |
139 if (!delegate_ || !delegate_->CanRenderFrame()) { | |
140 return; | |
141 } | |
142 | |
143 glClear(GL_COLOR_BUFFER_BIT); | |
144 desktop_.Draw(); | |
145 cursor_.Draw(); | |
146 if (cursor_feedback_.Draw()) { | |
147 RequestRender(); | |
148 } | |
149 | |
150 delegate_->OnFrameRendered(); | |
151 | |
152 while (!pending_done_callbacks_.empty()) { | |
153 pending_done_callbacks_.front().Run(); | |
154 pending_done_callbacks_.pop(); | |
155 } | |
156 } | |
157 | |
158 } // namespace remoting | |
OLD | NEW |