Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Side by Side Diff: remoting/client/gl_renderer.cc

Issue 2591363002: Adding drawable to CRD andorid and iOS gl rendering pipeline. (Closed)
Patch Set: Minor cleanup of an unused const. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/client/gl_renderer.h" 5 #include "remoting/client/gl_renderer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
10 #include "remoting/client/gl_canvas.h" 10 #include "remoting/client/gl_canvas.h"
11 #include "remoting/client/gl_math.h" 11 #include "remoting/client/gl_math.h"
12 #include "remoting/client/gl_renderer_delegate.h" 12 #include "remoting/client/gl_renderer_delegate.h"
13 #include "remoting/client/sys_opengl.h" 13 #include "remoting/client/sys_opengl.h"
14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
15 15
16 namespace remoting { 16 namespace remoting {
17 17
18 GlRenderer::GlRenderer() : 18 GlRenderer::GlRenderer() :
19 weak_factory_(this) { 19 weak_factory_(this) {
20 weak_ptr_ = weak_factory_.GetWeakPtr();
21 thread_checker_.DetachFromThread(); 20 thread_checker_.DetachFromThread();
22 } 21 }
23 22
24 GlRenderer::~GlRenderer() { 23 GlRenderer::~GlRenderer() {
25 } 24 }
26 25
26 GlRenderer* GlRenderer::CreateGlRendererWithDesktop() {
Yuwei 2016/12/21 23:41:59 I think it makes more sense to create a new class
nicholss 2017/01/09 18:50:24 I think that makes sense but not required for this
27 GlRenderer* renderer = new GlRenderer();
28 renderer->AddDrawable(renderer->desktop_.GetWeakPtr());
29 renderer->AddDrawable(renderer->cursor_.GetWeakPtr());
30 renderer->AddDrawable(renderer->cursor_feedback_.GetWeakPtr());
31 return renderer;
32 }
33
27 void GlRenderer::SetDelegate(base::WeakPtr<GlRendererDelegate> delegate) { 34 void GlRenderer::SetDelegate(base::WeakPtr<GlRendererDelegate> delegate) {
28 DCHECK(!delegate_); 35 DCHECK(!delegate_);
29 delegate_ = delegate; 36 delegate_ = delegate;
30 } 37 }
31 38
32 void GlRenderer::RequestCanvasSize() { 39 void GlRenderer::RequestCanvasSize() {
33 DCHECK(thread_checker_.CalledOnValidThread()); 40 DCHECK(thread_checker_.CalledOnValidThread());
34 if (delegate_) { 41 if (delegate_) {
35 delegate_->OnSizeChanged(canvas_width_, canvas_height_); 42 delegate_->OnSizeChanged(canvas_width_, canvas_height_);
36 } 43 }
37 } 44 }
38 45
39 void GlRenderer::OnPixelTransformationChanged( 46 void GlRenderer::OnPixelTransformationChanged(
40 const std::array<float, 9>& matrix) { 47 const std::array<float, 9>& matrix) {
41 DCHECK(thread_checker_.CalledOnValidThread()); 48 DCHECK(thread_checker_.CalledOnValidThread());
42 if (!canvas_) { 49 if (!canvas_) {
43 LOG(WARNING) << "Trying to set transformation matrix when the canvas is " 50 LOG(WARNING) << "Trying to set transformation matrix when the canvas is "
44 "not ready."; 51 "not ready.";
45 return; 52 return;
46 } 53 }
47 canvas_->SetTransformationMatrix(matrix); 54 canvas_->SetTransformationMatrix(matrix);
48 RequestRender(); 55 RequestRender();
49 } 56 }
50 57
58 // TODO(nicholss): This method seems like it should not be in this class.
51 void GlRenderer::OnCursorMoved(float x, float y) { 59 void GlRenderer::OnCursorMoved(float x, float y) {
52 DCHECK(thread_checker_.CalledOnValidThread()); 60 DCHECK(thread_checker_.CalledOnValidThread());
53 cursor_.SetCursorPosition(x, y); 61 cursor_.SetCursorPosition(x, y);
54 RequestRender(); 62 RequestRender();
55 } 63 }
56 64
65 // TODO(nicholss): This method seems like it should not be in this class.
57 void GlRenderer::OnCursorInputFeedback(float x, float y, float diameter) { 66 void GlRenderer::OnCursorInputFeedback(float x, float y, float diameter) {
58 DCHECK(thread_checker_.CalledOnValidThread()); 67 DCHECK(thread_checker_.CalledOnValidThread());
59 cursor_feedback_.StartAnimation(x, y, diameter); 68 cursor_feedback_.StartAnimation(x, y, diameter);
60 RequestRender(); 69 RequestRender();
61 } 70 }
62 71
72 // TODO(nicholss): This method seems like it should not be in this class.
63 void GlRenderer::OnCursorVisibilityChanged(bool visible) { 73 void GlRenderer::OnCursorVisibilityChanged(bool visible) {
64 DCHECK(thread_checker_.CalledOnValidThread()); 74 DCHECK(thread_checker_.CalledOnValidThread());
65 cursor_.SetCursorVisible(visible); 75 cursor_.SetCursorVisible(visible);
66 RequestRender(); 76 RequestRender();
67 } 77 }
68 78
79 // TODO(nicholss): This method seems like it should not be in this class.
69 void GlRenderer::OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame, 80 void GlRenderer::OnFrameReceived(std::unique_ptr<webrtc::DesktopFrame> frame,
70 const base::Closure& done) { 81 const base::Closure& done) {
71 DCHECK(thread_checker_.CalledOnValidThread()); 82 DCHECK(thread_checker_.CalledOnValidThread());
72 DCHECK(frame->size().width() > 0 && frame->size().height() > 0); 83 DCHECK(frame->size().width() > 0 && frame->size().height() > 0);
73 if (canvas_width_ != frame->size().width() || 84 if (canvas_width_ != frame->size().width() ||
74 canvas_height_ != frame->size().height()) { 85 canvas_height_ != frame->size().height()) {
75 if (delegate_) { 86 if (delegate_) {
76 delegate_->OnSizeChanged(frame->size().width(), frame->size().height()); 87 delegate_->OnSizeChanged(frame->size().width(), frame->size().height());
77 } 88 }
78 canvas_width_ = frame->size().width(); 89 canvas_width_ = frame->size().width();
79 canvas_height_ = frame->size().height(); 90 canvas_height_ = frame->size().height();
80 } 91 }
81 92
82 desktop_.SetVideoFrame(*frame); 93 desktop_.SetVideoFrame(*frame);
83 pending_done_callbacks_.push(done); 94 pending_done_callbacks_.push(done);
84 RequestRender(); 95 RequestRender();
85 } 96 }
86 97
98 // TODO(nicholss): This method seems like it should not be in this class.
87 void GlRenderer::OnCursorShapeChanged(const protocol::CursorShapeInfo& shape) { 99 void GlRenderer::OnCursorShapeChanged(const protocol::CursorShapeInfo& shape) {
88 DCHECK(thread_checker_.CalledOnValidThread()); 100 DCHECK(thread_checker_.CalledOnValidThread());
89 cursor_.SetCursorShape(shape); 101 cursor_.SetCursorShape(shape);
90 RequestRender(); 102 RequestRender();
91 } 103 }
92 104
93 void GlRenderer::OnSurfaceCreated(int gl_version) { 105 void GlRenderer::OnSurfaceCreated(int gl_version) {
94 DCHECK(thread_checker_.CalledOnValidThread()); 106 DCHECK(thread_checker_.CalledOnValidThread());
95 #ifndef NDEBUG 107 canvas_.reset(GlCanvas::CreateGlCanvas(gl_version));
96 // Set the background clear color to bright green for debugging purposes. 108 for (auto& drawable : drawables_) {
97 glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 109 drawable->SetCanvas(canvas_.get());
98 #else 110 }
99 // Set the background clear color to black.
100 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
101 #endif
102 canvas_.reset(new GlCanvas(gl_version));
103 desktop_.SetCanvas(canvas_.get());
104 cursor_.SetCanvas(canvas_.get());
105 cursor_feedback_.SetCanvas(canvas_.get());
106 } 111 }
107 112
108 void GlRenderer::OnSurfaceChanged(int view_width, int view_height) { 113 void GlRenderer::OnSurfaceChanged(int view_width, int view_height) {
109 DCHECK(thread_checker_.CalledOnValidThread()); 114 DCHECK(thread_checker_.CalledOnValidThread());
110 if (!canvas_) { 115 if (!canvas_) {
111 LOG(WARNING) << "Trying to set the view size when the canvas is not ready."; 116 LOG(WARNING) << "Trying to set the view size when the canvas is not ready.";
112 return; 117 return;
113 } 118 }
114 canvas_->SetViewSize(view_width, view_height); 119 canvas_->SetViewSize(view_width, view_height);
115 RequestRender(); 120 RequestRender();
116 } 121 }
117 122
118 void GlRenderer::OnSurfaceDestroyed() { 123 void GlRenderer::OnSurfaceDestroyed() {
119 DCHECK(thread_checker_.CalledOnValidThread()); 124 DCHECK(thread_checker_.CalledOnValidThread());
120 cursor_feedback_.SetCanvas(nullptr); 125 for (auto& drawable : drawables_) {
121 cursor_.SetCanvas(nullptr); 126 drawable->SetCanvas(nullptr);
122 desktop_.SetCanvas(nullptr); 127 }
123 canvas_.reset(); 128 canvas_.reset();
124 } 129 }
125 130
126 base::WeakPtr<GlRenderer> GlRenderer::GetWeakPtr() { 131 base::WeakPtr<GlRenderer> GlRenderer::GetWeakPtr() {
127 return weak_ptr_; 132 return weak_factory_.GetWeakPtr();
Yuwei 2016/12/21 23:41:59 Why removing |weak_ptr_|? We used |weak_ptr_| sinc
nicholss 2016/12/22 16:21:41 Nothing in the documentation says this call is thr
Yuwei 2016/12/22 19:01:10 Yep, this is an undocumented bug("feature"?). See
joedow 2016/12/22 19:18:09 Thanks for pointing that out Yuwei! That is a goo
Sergey Ulanov 2016/12/27 21:00:19 weak ptrs get bound to a thread when they are dere
nicholss 2017/01/09 18:50:24 reverted;
128 } 133 }
129 134
130 void GlRenderer::RequestRender() { 135 void GlRenderer::RequestRender() {
131 DCHECK(thread_checker_.CalledOnValidThread()); 136 DCHECK(thread_checker_.CalledOnValidThread());
132 if (render_scheduled_) { 137 if (render_scheduled_) {
133 return; 138 return;
134 } 139 }
135 base::ThreadTaskRunnerHandle::Get()->PostTask( 140 base::ThreadTaskRunnerHandle::Get()->PostTask(
136 FROM_HERE, base::Bind(&GlRenderer::OnRender, weak_ptr_)); 141 FROM_HERE, base::Bind(&GlRenderer::OnRender, GetWeakPtr()));
137 render_scheduled_ = true; 142 render_scheduled_ = true;
138 } 143 }
139 144
145 void GlRenderer::AddDrawable(base::WeakPtr<GlDrawable> drawable) {
146 drawable->SetCanvas(canvas_.get());
147 drawables_.push_back(drawable);
148 std::sort(drawables_.begin(), drawables_.end(),
149 drawable::SortDrawablesZOrder);
150 }
151
140 void GlRenderer::OnRender() { 152 void GlRenderer::OnRender() {
141 DCHECK(thread_checker_.CalledOnValidThread()); 153 DCHECK(thread_checker_.CalledOnValidThread());
142 render_scheduled_ = false; 154 render_scheduled_ = false;
143 if (!delegate_ || !delegate_->CanRenderFrame()) { 155 if (!delegate_ || !delegate_->CanRenderFrame()) {
144 return; 156 return;
145 } 157 }
146
147 if (canvas_) { 158 if (canvas_) {
148 glClear(GL_COLOR_BUFFER_BIT); 159 canvas_->Clear();
149 160 // Draw each drawable in order.
150 // Layers will be drawn from bottom to top. 161 for (auto& drawable : drawables_) {
151 desktop_.Draw(); 162 if (drawable->Draw()) {
152 163 RequestRender();
joedow 2016/12/22 00:29:03 Can you break out of the loop once a drawable indi
nicholss 2016/12/22 16:21:41 No, request render means: next draw loop, I have s
Yuwei 2016/12/22 19:01:10 I think it worth it to add a comment about the ret
joedow 2016/12/22 19:18:09 Ah yeah, I misread that. As long as RequestRender
153 // |cursor_feedback_| should be drawn before |cursor_| so that the cursor 164 }
154 // won't be covered by the feedback animation.
155 if (cursor_feedback_.Draw()) {
156 RequestRender();
157 } 165 }
158
159 cursor_.Draw();
160 } 166 }
161
162 delegate_->OnFrameRendered(); 167 delegate_->OnFrameRendered();
163 168
164 while (!pending_done_callbacks_.empty()) { 169 while (!pending_done_callbacks_.empty()) {
165 pending_done_callbacks_.front().Run(); 170 pending_done_callbacks_.front().Run();
166 pending_done_callbacks_.pop(); 171 pending_done_callbacks_.pop();
167 } 172 }
168 } 173 }
169 174
170 } // namespace remoting 175 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698