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

Side by Side Diff: content/plugin/webplugin_proxy.cc

Issue 10855141: Fix race condition with windowless plugin buffers. The problem, which is already fixed for Mac, is … (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 4 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 | « content/plugin/webplugin_proxy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/plugin/webplugin_proxy.h" 5 #include "content/plugin/webplugin_proxy.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 CGContextClearRect(windowless_context(), rect.ToCGRect()); 376 CGContextClearRect(windowless_context(), rect.ToCGRect());
377 } 377 }
378 CGContextClipToRect(windowless_context(), rect.ToCGRect()); 378 CGContextClipToRect(windowless_context(), rect.ToCGRect());
379 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia 379 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia
380 // port to share code with the Darwin / CG port. All ports will eventually use 380 // port to share code with the Darwin / CG port. All ports will eventually use
381 // the common code below. 381 // the common code below.
382 delegate_->CGPaint(windowless_context(), rect); 382 delegate_->CGPaint(windowless_context(), rect);
383 if (windowless_contexts_[saved_index].get() == saved_context_weak) 383 if (windowless_contexts_[saved_index].get() == saved_context_weak)
384 CGContextRestoreGState(windowless_contexts_[saved_index]); 384 CGContextRestoreGState(windowless_contexts_[saved_index]);
385 #else 385 #else
386 windowless_canvas()->save(); 386 // See above comment about windowless_context_ changing.
387 // http::/crbug.com139462
388 skia::PlatformCanvas* saved_canvas = windowless_canvas();
reed1 2012/08/14 17:19:04 Do we want to keep this commented line? // SkAutoR
jam 2012/08/14 17:29:30 doh, this is actually the fix. if it didn't repro
Tom Hudson 2012/08/14 17:34:55 It may be the ref isn't necessary. It used to be w
jam 2012/08/14 17:40:28 Paint() is the only function in this scope that ca
jam 2012/08/14 20:43:09 ok, turns out this section was a red herring! If I
389 // SkAutoRef local_ref(saved_canvas);
390
391 saved_canvas->save();
387 392
388 // The given clip rect is relative to the plugin coordinate system. 393 // The given clip rect is relative to the plugin coordinate system.
389 SkRect sk_rect = { SkIntToScalar(rect.x()), 394 SkRect sk_rect = { SkIntToScalar(rect.x()),
390 SkIntToScalar(rect.y()), 395 SkIntToScalar(rect.y()),
391 SkIntToScalar(rect.right()), 396 SkIntToScalar(rect.right()),
392 SkIntToScalar(rect.bottom()) }; 397 SkIntToScalar(rect.bottom()) };
393 windowless_canvas()->clipRect(sk_rect); 398 saved_canvas->clipRect(sk_rect);
394 399
395 // Setup the background. 400 // Setup the background.
396 if (background_canvas_.get() && background_canvas_.get()->getDevice()) { 401 if (background_canvas_.get() && background_canvas_.get()->getDevice()) {
397 // When a background canvas is given, we're in transparent mode. This means 402 // When a background canvas is given, we're in transparent mode. This means
398 // the plugin wants to have the image of the page in the canvas it's drawing 403 // the plugin wants to have the image of the page in the canvas it's drawing
399 // into (which is windowless_canvases_) so it can do blending. So we copy 404 // into (which is windowless_canvases_) so it can do blending. So we copy
400 // the background bitmap into the windowless canvas. 405 // the background bitmap into the windowless canvas.
401 const SkBitmap& background_bitmap = 406 const SkBitmap& background_bitmap =
402 skia::GetTopDevice(*background_canvas_)->accessBitmap(false); 407 skia::GetTopDevice(*background_canvas_)->accessBitmap(false);
403 windowless_canvas()->drawBitmap(background_bitmap, 0, 0); 408 saved_canvas->drawBitmap(background_bitmap, 0, 0);
404 } else { 409 } else {
405 // In non-transparent mode, the plugin doesn't care what's underneath, so we 410 // In non-transparent mode, the plugin doesn't care what's underneath, so we
406 // can just give it black. 411 // can just give it black.
407 SkPaint black_fill_paint; 412 SkPaint black_fill_paint;
408 black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00); 413 black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00);
reed1 2012/08/14 17:19:04 FYI -- canvas->drawColor(0xFF000000); works too
409 windowless_canvas()->drawPaint(black_fill_paint); 414 saved_canvas->drawPaint(black_fill_paint);
410 } 415 }
411 416
412 // Bring the windowless canvas into the window coordinate system, which is 417 // Bring the windowless canvas into the window coordinate system, which is
413 // how the plugin expects to draw (since the windowless API was originally 418 // how the plugin expects to draw (since the windowless API was originally
414 // designed just for scribbling over the web page). 419 // designed just for scribbling over the web page).
415 windowless_canvas()->translate(SkIntToScalar(-delegate_->GetRect().x()), 420 saved_canvas->translate(SkIntToScalar(-delegate_->GetRect().x()),
416 SkIntToScalar(-delegate_->GetRect().y())); 421 SkIntToScalar(-delegate_->GetRect().y()));
417 422
418 // Before we send the invalidate, paint so that renderer uses the updated 423 // Before we send the invalidate, paint so that renderer uses the updated
419 // bitmap. 424 // bitmap.
420 delegate_->Paint(windowless_canvas(), offset_rect); 425 delegate_->Paint(saved_canvas, offset_rect);
421 426
422 windowless_canvas()->restore(); 427 saved_canvas->restore();
423 #endif 428 #endif
424 } 429 }
425 430
426 void WebPluginProxy::UpdateGeometry( 431 void WebPluginProxy::UpdateGeometry(
427 const gfx::Rect& window_rect, 432 const gfx::Rect& window_rect,
428 const gfx::Rect& clip_rect, 433 const gfx::Rect& clip_rect,
429 const TransportDIB::Handle& windowless_buffer0, 434 const TransportDIB::Handle& windowless_buffer0,
430 const TransportDIB::Handle& windowless_buffer1, 435 const TransportDIB::Handle& windowless_buffer1,
431 int windowless_buffer_index, 436 int windowless_buffer_index,
432 const TransportDIB::Handle& background_buffer, 437 const TransportDIB::Handle& background_buffer,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 !damaged_rect_.IsEmpty()) { 470 !damaged_rect_.IsEmpty()) {
466 InvalidateRect(damaged_rect_); 471 InvalidateRect(damaged_rect_);
467 } 472 }
468 } 473 }
469 474
470 #if defined(OS_WIN) 475 #if defined(OS_WIN)
471 476
472 void WebPluginProxy::CreateCanvasFromHandle( 477 void WebPluginProxy::CreateCanvasFromHandle(
473 const TransportDIB::Handle& dib_handle, 478 const TransportDIB::Handle& dib_handle,
474 const gfx::Rect& window_rect, 479 const gfx::Rect& window_rect,
475 scoped_ptr<skia::PlatformCanvas>* canvas_out) { 480 SkRefPtr<skia::PlatformCanvas>* canvas) {
476 scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); 481 *canvas = new skia::PlatformCanvas;
477 if (!canvas->initialize( 482 if (!canvas->get()->initialize(
478 window_rect.width(), 483 window_rect.width(),
479 window_rect.height(), 484 window_rect.height(),
480 true, 485 true,
481 dib_handle)) { 486 dib_handle)) {
482 canvas_out->reset(); 487 *canvas = NULL;
483 } 488 }
484 canvas_out->reset(canvas.release());
485 // The canvas does not own the section so we need to close it now. 489 // The canvas does not own the section so we need to close it now.
486 CloseHandle(dib_handle); 490 CloseHandle(dib_handle);
487 } 491 }
488 492
489 void WebPluginProxy::SetWindowlessBuffers( 493 void WebPluginProxy::SetWindowlessBuffers(
490 const TransportDIB::Handle& windowless_buffer0, 494 const TransportDIB::Handle& windowless_buffer0,
491 const TransportDIB::Handle& windowless_buffer1, 495 const TransportDIB::Handle& windowless_buffer1,
492 const TransportDIB::Handle& background_buffer, 496 const TransportDIB::Handle& background_buffer,
493 const gfx::Rect& window_rect) { 497 const gfx::Rect& window_rect) {
494 CreateCanvasFromHandle(windowless_buffer0, 498 CreateCanvasFromHandle(windowless_buffer0,
495 window_rect, 499 window_rect,
496 &windowless_canvases_[0]); 500 &windowless_canvases_[0]);
497 if (!windowless_canvases_[0].get()) { 501 if (!windowless_canvases_[0].get()) {
498 windowless_canvases_[1].reset(); 502 windowless_canvases_[1] = NULL;
499 background_canvas_.reset(); 503 background_canvas_ = NULL;
500 return; 504 return;
501 } 505 }
502 CreateCanvasFromHandle(windowless_buffer1, 506 CreateCanvasFromHandle(windowless_buffer1,
503 window_rect, 507 window_rect,
504 &windowless_canvases_[1]); 508 &windowless_canvases_[1]);
505 if (!windowless_canvases_[1].get()) { 509 if (!windowless_canvases_[1].get()) {
506 windowless_canvases_[0].reset(); 510 windowless_canvases_[0] = NULL;
507 background_canvas_.reset(); 511 background_canvas_ = NULL;
508 return; 512 return;
509 } 513 }
510 514
511 if (background_buffer) { 515 if (background_buffer) {
512 CreateCanvasFromHandle(background_buffer, 516 CreateCanvasFromHandle(background_buffer,
513 window_rect, 517 window_rect,
514 &background_canvas_); 518 &background_canvas_);
515 if (!background_canvas_.get()) { 519 if (!background_canvas_.get()) {
516 windowless_canvases_[0].reset(); 520 windowless_canvases_[0] = NULL;
517 windowless_canvases_[1].reset(); 521 windowless_canvases_[1] = NULL;
518 return; 522 return;
519 } 523 }
520 } 524 }
521 } 525 }
522 526
523 #elif defined(OS_MACOSX) 527 #elif defined(OS_MACOSX)
524 528
525 void WebPluginProxy::CreateDIBAndCGContextFromHandle( 529 void WebPluginProxy::CreateDIBAndCGContextFromHandle(
526 const TransportDIB::Handle& dib_handle, 530 const TransportDIB::Handle& dib_handle,
527 const gfx::Rect& window_rect, 531 const gfx::Rect& window_rect,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 &background_dib_, 569 &background_dib_,
566 &background_context_); 570 &background_context_);
567 } 571 }
568 572
569 #elif defined(USE_X11) 573 #elif defined(USE_X11)
570 574
571 void WebPluginProxy::CreateDIBAndCanvasFromHandle( 575 void WebPluginProxy::CreateDIBAndCanvasFromHandle(
572 const TransportDIB::Handle& dib_handle, 576 const TransportDIB::Handle& dib_handle,
573 const gfx::Rect& window_rect, 577 const gfx::Rect& window_rect,
574 scoped_ptr<TransportDIB>* dib_out, 578 scoped_ptr<TransportDIB>* dib_out,
575 scoped_ptr<skia::PlatformCanvas>* canvas_out) { 579 SkRefPtr<skia::PlatformCanvas>* canvas) {
576 TransportDIB* dib = TransportDIB::Map(dib_handle); 580 TransportDIB* dib = TransportDIB::Map(dib_handle);
577 skia::PlatformCanvas* canvas = NULL;
578 // dib may be NULL if the renderer has already destroyed the TransportDIB by 581 // dib may be NULL if the renderer has already destroyed the TransportDIB by
579 // the time we receive the handle, e.g. in case of multiple resizes. 582 // the time we receive the handle, e.g. in case of multiple resizes.
580 if (dib) { 583 if (dib) {
581 canvas = dib->GetPlatformCanvas(window_rect.width(), window_rect.height()); 584 *canvas = dib->GetPlatformCanvas(window_rect.width(), window_rect.height());
585 } else {
586 *canvas = NULL;
582 } 587 }
583 dib_out->reset(dib); 588 dib_out->reset(dib);
584 canvas_out->reset(canvas);
585 } 589 }
586 590
587 void WebPluginProxy::CreateShmPixmapFromDIB( 591 void WebPluginProxy::CreateShmPixmapFromDIB(
588 TransportDIB* dib, 592 TransportDIB* dib,
589 const gfx::Rect& window_rect, 593 const gfx::Rect& window_rect,
590 XID* pixmap_out) { 594 XID* pixmap_out) {
591 if (dib) { 595 if (dib) {
592 Display* display = ui::GetXDisplay(); 596 Display* display = ui::GetXDisplay();
593 XID root_window = ui::GetX11RootWindow(); 597 XID root_window = ui::GetX11RootWindow();
594 XShmSegmentInfo shminfo = {0}; 598 XShmSegmentInfo shminfo = {0};
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 // Retrieve the IME status from a plug-in and send it to a renderer process 784 // Retrieve the IME status from a plug-in and send it to a renderer process
781 // when the plug-in has updated it. 785 // when the plug-in has updated it.
782 int input_type; 786 int input_type;
783 gfx::Rect caret_rect; 787 gfx::Rect caret_rect;
784 if (!delegate_->GetIMEStatus(&input_type, &caret_rect)) 788 if (!delegate_->GetIMEStatus(&input_type, &caret_rect))
785 return; 789 return;
786 790
787 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect)); 791 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect));
788 } 792 }
789 #endif 793 #endif
OLDNEW
« no previous file with comments | « content/plugin/webplugin_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698