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

Side by Side Diff: chrome/renderer/pepper_devices.cc

Issue 6646025: Deleted WebPluginDelegatePepper. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 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
« no previous file with comments | « chrome/renderer/pepper_devices.h ('k') | chrome/renderer/pepper_devices_browsertest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 "chrome/renderer/pepper_devices.h"
6
7 #include "chrome/common/render_messages.h"
8 #include "chrome/common/render_messages_params.h"
9 #include "chrome/renderer/render_thread.h"
10 #include "chrome/renderer/webplugin_delegate_pepper.h"
11 #include "skia/ext/platform_canvas.h"
12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "webkit/plugins/npapi/plugin_instance.h"
14 #include "webkit/plugins/npapi/webplugin.h"
15
16 namespace {
17
18 const uint32 kBytesPerPixel = 4; // Only 8888 RGBA for now.
19
20 } // namespace
21
22 int Graphics2DDeviceContext::next_buffer_id_ = 0;
23
24 struct Graphics2DDeviceContext::FlushCallbackData {
25 FlushCallbackData(NPDeviceFlushContextCallbackPtr f,
26 NPP n,
27 NPDeviceContext2D* c,
28 NPUserData* u)
29 : function(f),
30 npp(n),
31 context(c),
32 user_data(u) {
33 }
34
35 NPDeviceFlushContextCallbackPtr function;
36 NPP npp;
37 NPDeviceContext2D* context;
38 NPUserData* user_data;
39 };
40
41 Graphics2DDeviceContext::Graphics2DDeviceContext(
42 WebPluginDelegatePepper* plugin_delegate)
43 : plugin_delegate_(plugin_delegate) {
44 }
45
46 Graphics2DDeviceContext::~Graphics2DDeviceContext() {}
47
48 NPError Graphics2DDeviceContext::Initialize(
49 gfx::Rect window_rect, const NPDeviceContext2DConfig* config,
50 NPDeviceContext2D* context) {
51 int width = window_rect.width();
52 int height = window_rect.height();
53 uint32 buffer_size = width * height * kBytesPerPixel;
54
55 // Allocate the transport DIB and the PlatformCanvas pointing to it.
56 #if defined(OS_MACOSX)
57 // On the Mac, shared memory has to be created in the browser in order to
58 // work in the sandbox. Do this by sending a message to the browser
59 // requesting a TransportDIB (see also
60 // chrome/renderer/webplugin_delegate_proxy.cc, method
61 // WebPluginDelegateProxy::CreateBitmap() for similar code). Note that the
62 // TransportDIB is _not_ cached in the browser; this is because this memory
63 // gets flushed by the renderer into another TransportDIB that represents the
64 // page, which is then in turn flushed to the screen by the browser process.
65 // When |transport_dib_| goes out of scope in the dtor, all of its shared
66 // memory gets reclaimed.
67 TransportDIB::Handle dib_handle;
68 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size,
69 false,
70 &dib_handle);
71 if (!RenderThread::current()->Send(msg))
72 return NPERR_GENERIC_ERROR;
73 if (!TransportDIB::is_valid(dib_handle))
74 return NPERR_OUT_OF_MEMORY_ERROR;
75 transport_dib_.reset(TransportDIB::Map(dib_handle));
76 #else
77 transport_dib_.reset(TransportDIB::Create(buffer_size, ++next_buffer_id_));
78 if (!transport_dib_.get())
79 return NPERR_OUT_OF_MEMORY_ERROR;
80 #endif // defined(OS_MACOSX)
81 canvas_.reset(transport_dib_->GetPlatformCanvas(width, height));
82 if (!canvas_.get())
83 return NPERR_OUT_OF_MEMORY_ERROR;
84
85 // Note that we need to get the address out of the bitmap rather than
86 // using plugin_buffer_->memory(). The memory() is when the bitmap data
87 // has had "Map" called on it. For Windows, this is separate than making a
88 // bitmap using the shared section.
89 const SkBitmap& plugin_bitmap =
90 canvas_->getTopPlatformDevice().accessBitmap(true);
91 SkAutoLockPixels locker(plugin_bitmap);
92
93 // TODO(brettw) this theoretically shouldn't be necessary. But the
94 // platform device on Windows will fill itself with green to help you
95 // catch areas you didn't paint.
96 plugin_bitmap.eraseARGB(0, 0, 0, 0);
97
98 // Save the canvas to the output context structure and save the
99 // OpenPaintContext for future reference.
100 context->region = plugin_bitmap.getAddr32(0, 0);
101 context->stride = width * kBytesPerPixel;
102 context->dirty.left = 0;
103 context->dirty.top = 0;
104 context->dirty.right = width;
105 context->dirty.bottom = height;
106 return NPERR_NO_ERROR;
107 }
108
109 NPError Graphics2DDeviceContext::Flush(SkBitmap* committed_bitmap,
110 NPDeviceContext2D* context,
111 NPDeviceFlushContextCallbackPtr callback,
112 NPP id, void* user_data) {
113 // Draw the bitmap to the backing store.
114 //
115 // TODO(brettw) we can optimize this in the case where the entire canvas is
116 // updated by actually taking ownership of the buffer and not telling the
117 // plugin we're done using it. This wat we can avoid the copy when the entire
118 // canvas has been updated.
119 SkIRect src_rect = { context->dirty.left,
120 context->dirty.top,
121 context->dirty.right,
122 context->dirty.bottom };
123 SkRect dest_rect = { SkIntToScalar(context->dirty.left),
124 SkIntToScalar(context->dirty.top),
125 SkIntToScalar(context->dirty.right),
126 SkIntToScalar(context->dirty.bottom) };
127 SkCanvas committed_canvas(*committed_bitmap);
128
129 // We want to replace the contents of the bitmap rather than blend.
130 SkPaint paint;
131 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
132 committed_canvas.drawBitmapRect(
133 canvas_->getTopPlatformDevice().accessBitmap(false),
134 &src_rect, dest_rect, &paint);
135
136 committed_bitmap->setIsOpaque(false);
137
138 // Cause the updated part of the screen to be repainted. This will happen
139 // asynchronously.
140 // TODO(brettw) is this the coorect coordinate system?
141 gfx::Rect dest_gfx_rect(context->dirty.left, context->dirty.top,
142 context->dirty.right - context->dirty.left,
143 context->dirty.bottom - context->dirty.top);
144
145 plugin_delegate_->instance()->webplugin()->InvalidateRect(dest_gfx_rect);
146
147 // Save the callback to execute later. See |unpainted_flush_callbacks_| in
148 // the header file.
149 if (callback) {
150 unpainted_flush_callbacks_.push_back(
151 FlushCallbackData(callback, id, context, user_data));
152 }
153
154 return NPERR_NO_ERROR;
155 }
156
157 void Graphics2DDeviceContext::RenderViewInitiatedPaint() {
158 // Move all "unpainted" callbacks to the painted state. See
159 // |unpainted_flush_callbacks_| in the header for more.
160 std::copy(unpainted_flush_callbacks_.begin(),
161 unpainted_flush_callbacks_.end(),
162 std::back_inserter(painted_flush_callbacks_));
163 unpainted_flush_callbacks_.clear();
164 }
165
166 void Graphics2DDeviceContext::RenderViewFlushedPaint() {
167 // Notify all "painted" callbacks. See |unpainted_flush_callbacks_| in the
168 // header for more.
169 for (size_t i = 0; i < painted_flush_callbacks_.size(); i++) {
170 const FlushCallbackData& data = painted_flush_callbacks_[i];
171 data.function(data.npp, data.context, NPERR_NO_ERROR, data.user_data);
172 }
173 painted_flush_callbacks_.clear();
174 }
175
176 AudioDeviceContext::AudioDeviceContext()
177 : context_(NULL),
178 stream_id_(0),
179 shared_memory_size_(0) {
180 }
181
182 AudioDeviceContext::~AudioDeviceContext() {
183 if (stream_id_) {
184 OnDestroy();
185 }
186 }
187
188 NPError AudioDeviceContext::Initialize(AudioMessageFilter* filter,
189 const NPDeviceContextAudioConfig* config,
190 NPDeviceContextAudio* context) {
191 DCHECK(filter);
192 // Make sure we don't call init more than once.
193 DCHECK_EQ(0, stream_id_);
194
195 if (!config || !context) {
196 return NPERR_INVALID_PARAM;
197 }
198 filter_ = filter;
199 context_= context;
200
201 ViewHostMsg_Audio_CreateStream_Params params;
202 params.params.format = AudioParameters::AUDIO_PCM_LINEAR;
203 params.params.channels = config->outputChannelMap;
204 params.params.sample_rate = config->sampleRate;
205 switch (config->sampleType) {
206 case NPAudioSampleTypeInt16:
207 params.params.bits_per_sample = 16;
208 break;
209 case NPAudioSampleTypeFloat32:
210 params.params.bits_per_sample = 32;
211 break;
212 default:
213 return NPERR_INVALID_PARAM;
214 }
215
216 context->config = *config;
217 params.params.samples_per_packet = config->sampleFrameCount;
218
219 stream_id_ = filter_->AddDelegate(this);
220 filter->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params, true));
221 return NPERR_NO_ERROR;
222 }
223
224 void AudioDeviceContext::OnDestroy() {
225 // Make sure we don't call destroy more than once.
226 DCHECK_NE(0, stream_id_);
227 filter_->RemoveDelegate(stream_id_);
228 filter_->Send(new ViewHostMsg_CloseAudioStream(0, stream_id_));
229 stream_id_ = 0;
230 if (audio_thread_.get()) {
231 socket_->Close();
232 audio_thread_->Join();
233 }
234 }
235
236 void AudioDeviceContext::OnRequestPacket(AudioBuffersState buffers_state) {
237 FireAudioCallback();
238 filter_->Send(new ViewHostMsg_NotifyAudioPacketReady(0, stream_id_,
239 shared_memory_size_));
240 }
241
242 void AudioDeviceContext::OnStateChanged(
243 const ViewMsg_AudioStreamState_Params& state) {
244 }
245
246 void AudioDeviceContext::OnCreated(
247 base::SharedMemoryHandle handle, uint32 length) {
248 #if defined(OS_WIN)
249 DCHECK(handle);
250 #else
251 DCHECK_NE(-1, handle.fd);
252 #endif
253 DCHECK(length);
254 DCHECK(context_);
255
256 shared_memory_.reset(new base::SharedMemory(handle, false));
257 shared_memory_->Map(length);
258 shared_memory_size_ = length;
259
260 context_->outBuffer = shared_memory_->memory();
261 FireAudioCallback();
262 filter_->Send(new ViewHostMsg_PlayAudioStream(0, stream_id_));
263 }
264
265 void AudioDeviceContext::OnLowLatencyCreated(
266 base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle,
267 uint32 length) {
268 #if defined(OS_WIN)
269 DCHECK(handle);
270 DCHECK(socket_handle);
271 #else
272 DCHECK_NE(-1, handle.fd);
273 DCHECK_NE(-1, socket_handle);
274 #endif
275 DCHECK(length);
276 DCHECK(context_);
277 DCHECK(!audio_thread_.get());
278 shared_memory_.reset(new base::SharedMemory(handle, false));
279 shared_memory_->Map(length);
280 shared_memory_size_ = length;
281
282 context_->outBuffer = shared_memory_->memory();
283 socket_.reset(new base::SyncSocket(socket_handle));
284 // Allow the client to pre-populate the buffer.
285 FireAudioCallback();
286 if (context_->config.startThread) {
287 audio_thread_.reset(
288 new base::DelegateSimpleThread(this, "plugin_audio_thread"));
289 audio_thread_->Start();
290 }
291 filter_->Send(new ViewHostMsg_PlayAudioStream(0, stream_id_));
292 }
293
294 void AudioDeviceContext::OnVolume(double volume) {
295 }
296
297 void AudioDeviceContext::Run() {
298 int pending_data;
299 while (sizeof(pending_data) == socket_->Receive(&pending_data,
300 sizeof(pending_data)) &&
301 pending_data >= 0) {
302 FireAudioCallback();
303 }
304 }
OLDNEW
« no previous file with comments | « chrome/renderer/pepper_devices.h ('k') | chrome/renderer/pepper_devices_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698