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

Side by Side Diff: remoting/client/plugin/pepper_view.cc

Issue 6359010: Add PepperViewProxy to protect PepperView and ChromotingInstance on shutdown (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: done Created 9 years, 11 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/plugin/pepper_view.h" 5 #include "remoting/client/plugin/pepper_view.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "ppapi/cpp/graphics_2d.h" 8 #include "ppapi/cpp/graphics_2d.h"
9 #include "ppapi/cpp/image_data.h" 9 #include "ppapi/cpp/image_data.h"
10 #include "ppapi/cpp/point.h" 10 #include "ppapi/cpp/point.h"
11 #include "ppapi/cpp/size.h" 11 #include "ppapi/cpp/size.h"
12 #include "remoting/base/tracer.h" 12 #include "remoting/base/tracer.h"
13 #include "remoting/client/client_context.h" 13 #include "remoting/client/client_context.h"
14 #include "remoting/client/plugin/chromoting_instance.h" 14 #include "remoting/client/plugin/chromoting_instance.h"
15 #include "remoting/client/plugin/pepper_util.h" 15 #include "remoting/client/plugin/pepper_util.h"
16 16
17 namespace remoting { 17 namespace remoting {
18 18
19 PepperView::PepperView(ChromotingInstance* instance, ClientContext* context) 19 PepperView::PepperView(ChromotingInstance* instance, ClientContext* context)
20 : instance_(instance), 20 : instance_(instance),
21 context_(context), 21 context_(context),
22 viewport_x_(0), 22 viewport_x_(0),
23 viewport_y_(0), 23 viewport_y_(0),
24 viewport_width_(0), 24 viewport_width_(0),
25 viewport_height_(0), 25 viewport_height_(0),
26 is_static_fill_(false), 26 is_static_fill_(false),
27 static_fill_color_(0) { 27 static_fill_color_(0),
28 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
28 } 29 }
29 30
30 PepperView::~PepperView() { 31 PepperView::~PepperView() {
31 } 32 }
32 33
33 bool PepperView::Initialize() { 34 bool PepperView::Initialize() {
34 return true; 35 return true;
35 } 36 }
36 37
37 void PepperView::TearDown() { 38 void PepperView::TearDown() {
39 DCHECK(instance_->CurrentlyOnPluginThread());
40
41 task_factory_.RevokeAll();
38 } 42 }
39 43
40 void PepperView::Paint() { 44 void PepperView::Paint() {
41 if (!instance_->CurrentlyOnPluginThread()) { 45 DCHECK(instance_->CurrentlyOnPluginThread());
42 RunTaskOnPluginThread(NewTracedMethod(this, &PepperView::Paint));
43 return;
44 }
45 46
46 TraceContext::tracer()->PrintString("Start Paint."); 47 TraceContext::tracer()->PrintString("Start Paint.");
47 // TODO(ajwong): We're assuming the native format is BGRA_PREMUL below. This 48 // TODO(ajwong): We're assuming the native format is BGRA_PREMUL below. This
48 // is wrong. 49 // is wrong.
49 if (is_static_fill_) { 50 if (is_static_fill_) {
50 LOG(ERROR) << "Static filling " << static_fill_color_; 51 LOG(ERROR) << "Static filling " << static_fill_color_;
51 pp::ImageData image(instance_, pp::ImageData::GetNativeImageDataFormat(), 52 pp::ImageData image(instance_, pp::ImageData::GetNativeImageDataFormat(),
52 pp::Size(viewport_width_, viewport_height_), 53 pp::Size(viewport_width_, viewport_height_),
53 false); 54 false);
54 if (image.is_null()) { 55 if (image.is_null()) {
55 LOG(ERROR) << "Unable to allocate image of size: " 56 LOG(ERROR) << "Unable to allocate image of size: "
56 << viewport_width_ << "x" << viewport_height_; 57 << viewport_width_ << "x" << viewport_height_;
57 return; 58 return;
58 } 59 }
59 60
60 for (int y = 0; y < image.size().height(); y++) { 61 for (int y = 0; y < image.size().height(); y++) {
61 for (int x = 0; x < image.size().width(); x++) { 62 for (int x = 0; x < image.size().width(); x++) {
62 *image.GetAddr32(pp::Point(x, y)) = static_fill_color_; 63 *image.GetAddr32(pp::Point(x, y)) = static_fill_color_;
63 } 64 }
64 } 65 }
65 66
66 // For ReplaceContents, make sure the image size matches the device context 67 // For ReplaceContents, make sure the image size matches the device context
67 // size! Otherwise, this will just silently do nothing. 68 // size! Otherwise, this will just silently do nothing.
68 graphics2d_.ReplaceContents(&image); 69 graphics2d_.ReplaceContents(&image);
69 graphics2d_.Flush(TaskToCompletionCallback( 70 graphics2d_.Flush(TaskToCompletionCallback(
70 NewTracedMethod(this, &PepperView::OnPaintDone))); 71 task_factory_.NewRunnableMethod(&PepperView::OnPaintDone)));
71 } else { 72 } else {
72 // TODO(ajwong): We need to keep a backing store image of the viewport that 73 // TODO(ajwong): We need to keep a backing store image of the viewport that
73 // has the data here which can be redrawn. 74 // has the data here which can be redrawn.
74 return; 75 return;
75 } 76 }
76 TraceContext::tracer()->PrintString("End Paint."); 77 TraceContext::tracer()->PrintString("End Paint.");
77 } 78 }
78 79
79 void PepperView::PaintFrame(media::VideoFrame* frame, UpdatedRects* rects) { 80 void PepperView::PaintFrame(media::VideoFrame* frame, UpdatedRects* rects) {
80 DCHECK(instance_->CurrentlyOnPluginThread()); 81 DCHECK(instance_->CurrentlyOnPluginThread());
(...skipping 21 matching lines...) Expand all
102 // Force alpha to be set to 255. 103 // Force alpha to be set to 255.
103 *image.GetAddr32(pp::Point(x, y)) = 104 *image.GetAddr32(pp::Point(x, y)) =
104 frame_data[y*frame_width + x] | 0xFF000000; 105 frame_data[y*frame_width + x] | 0xFF000000;
105 } 106 }
106 } 107 }
107 108
108 // For ReplaceContents, make sure the image size matches the device context 109 // For ReplaceContents, make sure the image size matches the device context
109 // size! Otherwise, this will just silently do nothing. 110 // size! Otherwise, this will just silently do nothing.
110 graphics2d_.ReplaceContents(&image); 111 graphics2d_.ReplaceContents(&image);
111 graphics2d_.Flush(TaskToCompletionCallback( 112 graphics2d_.Flush(TaskToCompletionCallback(
112 NewTracedMethod(this, &PepperView::OnPaintDone))); 113 task_factory_.NewRunnableMethod(&PepperView::OnPaintDone)));
113 114
114 TraceContext::tracer()->PrintString("End Paint Frame."); 115 TraceContext::tracer()->PrintString("End Paint Frame.");
115 } 116 }
116 117
117 void PepperView::SetSolidFill(uint32 color) { 118 void PepperView::SetSolidFill(uint32 color) {
118 if (!instance_->CurrentlyOnPluginThread()) { 119 DCHECK(instance_->CurrentlyOnPluginThread());
119 RunTaskOnPluginThread(
120 NewTracedMethod(this, &PepperView::SetSolidFill, color));
121 return;
122 }
123 120
124 is_static_fill_ = true; 121 is_static_fill_ = true;
125 static_fill_color_ = color; 122 static_fill_color_ = color;
126 } 123 }
127 124
128 void PepperView::UnsetSolidFill() { 125 void PepperView::UnsetSolidFill() {
129 if (!instance_->CurrentlyOnPluginThread()) { 126 DCHECK(instance_->CurrentlyOnPluginThread());
130 RunTaskOnPluginThread(
131 NewTracedMethod(this, &PepperView::UnsetSolidFill));
132 return;
133 }
134 127
135 is_static_fill_ = false; 128 is_static_fill_ = false;
136 } 129 }
137 130
138 void PepperView::SetConnectionState(ConnectionState state) { 131 void PepperView::SetConnectionState(ConnectionState state) {
139 if (!instance_->CurrentlyOnPluginThread()) { 132 DCHECK(instance_->CurrentlyOnPluginThread());
140 RunTaskOnPluginThread(
141 NewRunnableMethod(this, &PepperView::SetConnectionState, state));
142 return;
143 }
144 133
145 ChromotingScriptableObject* scriptable_obj = instance_->GetScriptableObject(); 134 ChromotingScriptableObject* scriptable_obj = instance_->GetScriptableObject();
146 switch (state) { 135 switch (state) {
147 case CREATED: 136 case CREATED:
148 SetSolidFill(kCreatedColor); 137 SetSolidFill(kCreatedColor);
149 scriptable_obj->SetConnectionInfo(STATUS_CONNECTING, QUALITY_UNKNOWN); 138 scriptable_obj->SetConnectionInfo(STATUS_CONNECTING, QUALITY_UNKNOWN);
150 break; 139 break;
151 140
152 case CONNECTED: 141 case CONNECTED:
153 UnsetSolidFill(); 142 UnsetSolidFill();
154 scriptable_obj->SetConnectionInfo(STATUS_CONNECTED, QUALITY_UNKNOWN); 143 scriptable_obj->SetConnectionInfo(STATUS_CONNECTED, QUALITY_UNKNOWN);
155 break; 144 break;
156 145
157 case DISCONNECTED: 146 case DISCONNECTED:
158 SetSolidFill(kDisconnectedColor); 147 SetSolidFill(kDisconnectedColor);
159 scriptable_obj->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN); 148 scriptable_obj->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN);
160 break; 149 break;
161 150
162 case FAILED: 151 case FAILED:
163 SetSolidFill(kFailedColor); 152 SetSolidFill(kFailedColor);
164 scriptable_obj->SetConnectionInfo(STATUS_FAILED, QUALITY_UNKNOWN); 153 scriptable_obj->SetConnectionInfo(STATUS_FAILED, QUALITY_UNKNOWN);
165 break; 154 break;
166 } 155 }
167 } 156 }
168 157
169 void PepperView::SetViewport(int x, int y, int width, int height) { 158 void PepperView::SetViewport(int x, int y, int width, int height) {
170 if (!instance_->CurrentlyOnPluginThread()) { 159 DCHECK(instance_->CurrentlyOnPluginThread());
171 RunTaskOnPluginThread(NewTracedMethod(this, &PepperView::SetViewport,
172 x, y, width, height));
173 return;
174 }
175 160
176 // TODO(ajwong): Should we ignore x & y updates? What do those even mean? 161 // TODO(ajwong): Should we ignore x & y updates? What do those even mean?
177 162
178 // TODO(ajwong): What does viewport x, y mean to a plugin anyways? 163 // TODO(ajwong): What does viewport x, y mean to a plugin anyways?
179 viewport_x_ = x; 164 viewport_x_ = x;
180 viewport_y_ = y; 165 viewport_y_ = y;
181 viewport_width_ = width; 166 viewport_width_ = width;
182 viewport_height_ = height; 167 viewport_height_ = height;
183 168
184 graphics2d_ = pp::Graphics2D(instance_, 169 graphics2d_ = pp::Graphics2D(instance_,
185 pp::Size(viewport_width_, viewport_height_), 170 pp::Size(viewport_width_, viewport_height_),
186 false); 171 false);
187 if (!instance_->BindGraphics(graphics2d_)) { 172 if (!instance_->BindGraphics(graphics2d_)) {
188 LOG(ERROR) << "Couldn't bind the device context."; 173 LOG(ERROR) << "Couldn't bind the device context.";
189 return; 174 return;
190 } 175 }
191 } 176 }
192 177
193 void PepperView::AllocateFrame(media::VideoFrame::Format format, 178 void PepperView::AllocateFrame(media::VideoFrame::Format format,
194 size_t width, 179 size_t width,
195 size_t height, 180 size_t height,
196 base::TimeDelta timestamp, 181 base::TimeDelta timestamp,
197 base::TimeDelta duration, 182 base::TimeDelta duration,
198 scoped_refptr<media::VideoFrame>* frame_out, 183 scoped_refptr<media::VideoFrame>* frame_out,
199 Task* done) { 184 Task* done) {
185 DCHECK(instance_->CurrentlyOnPluginThread());
186
200 // TODO(ajwong): Implement this to be backed by an pp::ImageData rather than 187 // TODO(ajwong): Implement this to be backed by an pp::ImageData rather than
201 // generic memory. 188 // generic memory.
202 media::VideoFrame::CreateFrame(media::VideoFrame::RGB32, 189 media::VideoFrame::CreateFrame(media::VideoFrame::RGB32,
203 width, height, 190 width, height,
204 base::TimeDelta(), base::TimeDelta(), 191 base::TimeDelta(), base::TimeDelta(),
205 frame_out); 192 frame_out);
206 if (*frame_out) { 193 if (*frame_out) {
207 (*frame_out)->AddRef(); 194 (*frame_out)->AddRef();
208 } 195 }
209 done->Run(); 196 done->Run();
210 delete done; 197 delete done;
211 } 198 }
212 199
213 void PepperView::ReleaseFrame(media::VideoFrame* frame) { 200 void PepperView::ReleaseFrame(media::VideoFrame* frame) {
201 DCHECK(instance_->CurrentlyOnPluginThread());
202
214 if (frame) { 203 if (frame) {
215 LOG(WARNING) << "Frame released."; 204 LOG(WARNING) << "Frame released.";
216 frame->Release(); 205 frame->Release();
217 } 206 }
218 } 207 }
219 208
220 void PepperView::OnPartialFrameOutput(media::VideoFrame* frame, 209 void PepperView::OnPartialFrameOutput(media::VideoFrame* frame,
221 UpdatedRects* rects, 210 UpdatedRects* rects,
222 Task* done) { 211 Task* done) {
223 if (!instance_->CurrentlyOnPluginThread()) { 212 DCHECK(instance_->CurrentlyOnPluginThread());
224 RunTaskOnPluginThread(
225 NewTracedMethod(this, &PepperView::OnPartialFrameOutput,
226 make_scoped_refptr(frame), rects, done));
227 return;
228 }
229 213
230 TraceContext::tracer()->PrintString("Calling PaintFrame"); 214 TraceContext::tracer()->PrintString("Calling PaintFrame");
231 // TODO(ajwong): Clean up this API to be async so we don't need to use a 215 // TODO(ajwong): Clean up this API to be async so we don't need to use a
232 // member variable as a hack. 216 // member variable as a hack.
233 PaintFrame(frame, rects); 217 PaintFrame(frame, rects);
234 done->Run(); 218 done->Run();
235 delete done; 219 delete done;
236 } 220 }
237 221
238 void PepperView::OnPaintDone() { 222 void PepperView::OnPaintDone() {
223 DCHECK(instance_->CurrentlyOnPluginThread());
224
239 // TODO(ajwong):Probably should set some variable to allow repaints to 225 // TODO(ajwong):Probably should set some variable to allow repaints to
240 // actually paint. 226 // actually paint.
241 TraceContext::tracer()->PrintString("Paint flushed"); 227 TraceContext::tracer()->PrintString("Paint flushed");
242 return; 228 return;
243 } 229 }
244 230
245 } // namespace remoting 231 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698