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

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: fix linux 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') | content/test/data/npapi/resize_during_paint.html » ('j') | 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 28 matching lines...) Expand all
39 #include "content/public/common/sandbox_init.h" 39 #include "content/public/common/sandbox_init.h"
40 #endif 40 #endif
41 41
42 using WebKit::WebBindings; 42 using WebKit::WebBindings;
43 43
44 using webkit::npapi::WebPluginResourceClient; 44 using webkit::npapi::WebPluginResourceClient;
45 #if defined(OS_MACOSX) 45 #if defined(OS_MACOSX)
46 using webkit::npapi::WebPluginAcceleratedSurface; 46 using webkit::npapi::WebPluginAcceleratedSurface;
47 #endif 47 #endif
48 48
49
50 WebPluginProxy::SharedTransportDIB::SharedTransportDIB(TransportDIB* dib)
51 : dib_(dib) {
52 }
53
54 WebPluginProxy::SharedTransportDIB::~SharedTransportDIB() {
55 }
56
49 WebPluginProxy::WebPluginProxy( 57 WebPluginProxy::WebPluginProxy(
50 PluginChannel* channel, 58 PluginChannel* channel,
51 int route_id, 59 int route_id,
52 const GURL& page_url, 60 const GURL& page_url,
53 gfx::NativeViewId containing_window, 61 gfx::NativeViewId containing_window,
54 int host_render_view_routing_id) 62 int host_render_view_routing_id)
55 : channel_(channel), 63 : channel_(channel),
56 route_id_(route_id), 64 route_id_(route_id),
57 window_npobject_(NULL), 65 window_npobject_(NULL),
58 plugin_element_(NULL), 66 plugin_element_(NULL),
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 CGContextClearRect(windowless_context(), rect.ToCGRect()); 384 CGContextClearRect(windowless_context(), rect.ToCGRect());
377 } 385 }
378 CGContextClipToRect(windowless_context(), rect.ToCGRect()); 386 CGContextClipToRect(windowless_context(), rect.ToCGRect());
379 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia 387 // 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 388 // port to share code with the Darwin / CG port. All ports will eventually use
381 // the common code below. 389 // the common code below.
382 delegate_->CGPaint(windowless_context(), rect); 390 delegate_->CGPaint(windowless_context(), rect);
383 if (windowless_contexts_[saved_index].get() == saved_context_weak) 391 if (windowless_contexts_[saved_index].get() == saved_context_weak)
384 CGContextRestoreGState(windowless_contexts_[saved_index]); 392 CGContextRestoreGState(windowless_contexts_[saved_index]);
385 #else 393 #else
386 windowless_canvas()->save(); 394 // See above comment about windowless_context_ changing.
395 // http::/crbug.com/139462
396 skia::PlatformCanvas* saved_canvas = windowless_canvas();
397 SkAutoRef local_ref(saved_canvas);
398 #if defined(USE_X11)
399 scoped_refptr<SharedTransportDIB> local_dib_ref(
400 windowless_dibs_[windowless_buffer_index_]);
401 #endif
402
403 saved_canvas->save();
387 404
388 // The given clip rect is relative to the plugin coordinate system. 405 // The given clip rect is relative to the plugin coordinate system.
389 SkRect sk_rect = { SkIntToScalar(rect.x()), 406 SkRect sk_rect = { SkIntToScalar(rect.x()),
390 SkIntToScalar(rect.y()), 407 SkIntToScalar(rect.y()),
391 SkIntToScalar(rect.right()), 408 SkIntToScalar(rect.right()),
392 SkIntToScalar(rect.bottom()) }; 409 SkIntToScalar(rect.bottom()) };
393 windowless_canvas()->clipRect(sk_rect); 410 saved_canvas->clipRect(sk_rect);
394 411
395 // Setup the background. 412 // Setup the background.
396 if (background_canvas_.get() && background_canvas_.get()->getDevice()) { 413 if (background_canvas_.get() && background_canvas_.get()->getDevice()) {
397 // When a background canvas is given, we're in transparent mode. This means 414 // 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 415 // 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 416 // into (which is windowless_canvases_) so it can do blending. So we copy
400 // the background bitmap into the windowless canvas. 417 // the background bitmap into the windowless canvas.
401 const SkBitmap& background_bitmap = 418 const SkBitmap& background_bitmap =
402 skia::GetTopDevice(*background_canvas_)->accessBitmap(false); 419 skia::GetTopDevice(*background_canvas_)->accessBitmap(false);
403 windowless_canvas()->drawBitmap(background_bitmap, 0, 0); 420 saved_canvas->drawBitmap(background_bitmap, 0, 0);
404 } else { 421 } else {
405 // In non-transparent mode, the plugin doesn't care what's underneath, so we 422 // In non-transparent mode, the plugin doesn't care what's underneath, so we
406 // can just give it black. 423 // can just give it black.
407 SkPaint black_fill_paint; 424 SkPaint black_fill_paint;
408 black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00); 425 black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00);
409 windowless_canvas()->drawPaint(black_fill_paint); 426 saved_canvas->drawPaint(black_fill_paint);
410 } 427 }
411 428
412 // Bring the windowless canvas into the window coordinate system, which is 429 // Bring the windowless canvas into the window coordinate system, which is
413 // how the plugin expects to draw (since the windowless API was originally 430 // how the plugin expects to draw (since the windowless API was originally
414 // designed just for scribbling over the web page). 431 // designed just for scribbling over the web page).
415 windowless_canvas()->translate(SkIntToScalar(-delegate_->GetRect().x()), 432 saved_canvas->translate(SkIntToScalar(-delegate_->GetRect().x()),
416 SkIntToScalar(-delegate_->GetRect().y())); 433 SkIntToScalar(-delegate_->GetRect().y()));
417 434
418 // Before we send the invalidate, paint so that renderer uses the updated 435 // Before we send the invalidate, paint so that renderer uses the updated
419 // bitmap. 436 // bitmap.
420 delegate_->Paint(windowless_canvas(), offset_rect); 437 delegate_->Paint(saved_canvas, offset_rect);
421 438
422 windowless_canvas()->restore(); 439 saved_canvas->restore();
423 #endif 440 #endif
424 } 441 }
425 442
426 void WebPluginProxy::UpdateGeometry( 443 void WebPluginProxy::UpdateGeometry(
427 const gfx::Rect& window_rect, 444 const gfx::Rect& window_rect,
428 const gfx::Rect& clip_rect, 445 const gfx::Rect& clip_rect,
429 const TransportDIB::Handle& windowless_buffer0, 446 const TransportDIB::Handle& windowless_buffer0,
430 const TransportDIB::Handle& windowless_buffer1, 447 const TransportDIB::Handle& windowless_buffer1,
431 int windowless_buffer_index, 448 int windowless_buffer_index,
432 const TransportDIB::Handle& background_buffer, 449 const TransportDIB::Handle& background_buffer,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 !damaged_rect_.IsEmpty()) { 482 !damaged_rect_.IsEmpty()) {
466 InvalidateRect(damaged_rect_); 483 InvalidateRect(damaged_rect_);
467 } 484 }
468 } 485 }
469 486
470 #if defined(OS_WIN) 487 #if defined(OS_WIN)
471 488
472 void WebPluginProxy::CreateCanvasFromHandle( 489 void WebPluginProxy::CreateCanvasFromHandle(
473 const TransportDIB::Handle& dib_handle, 490 const TransportDIB::Handle& dib_handle,
474 const gfx::Rect& window_rect, 491 const gfx::Rect& window_rect,
475 scoped_ptr<skia::PlatformCanvas>* canvas_out) { 492 SkAutoTUnref<skia::PlatformCanvas>* canvas) {
476 scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); 493 canvas->reset(new skia::PlatformCanvas);
477 if (!canvas->initialize( 494 if (!canvas->get()->initialize(
478 window_rect.width(), 495 window_rect.width(),
479 window_rect.height(), 496 window_rect.height(),
480 true, 497 true,
481 dib_handle)) { 498 dib_handle)) {
482 canvas_out->reset(); 499 canvas->reset(NULL);
483 } 500 }
484 canvas_out->reset(canvas.release());
485 // The canvas does not own the section so we need to close it now. 501 // The canvas does not own the section so we need to close it now.
486 CloseHandle(dib_handle); 502 CloseHandle(dib_handle);
487 } 503 }
488 504
489 void WebPluginProxy::SetWindowlessBuffers( 505 void WebPluginProxy::SetWindowlessBuffers(
490 const TransportDIB::Handle& windowless_buffer0, 506 const TransportDIB::Handle& windowless_buffer0,
491 const TransportDIB::Handle& windowless_buffer1, 507 const TransportDIB::Handle& windowless_buffer1,
492 const TransportDIB::Handle& background_buffer, 508 const TransportDIB::Handle& background_buffer,
493 const gfx::Rect& window_rect) { 509 const gfx::Rect& window_rect) {
494 CreateCanvasFromHandle(windowless_buffer0, 510 CreateCanvasFromHandle(windowless_buffer0,
495 window_rect, 511 window_rect,
496 &windowless_canvases_[0]); 512 &windowless_canvases_[0]);
497 if (!windowless_canvases_[0].get()) { 513 if (!windowless_canvases_[0].get()) {
498 windowless_canvases_[1].reset(); 514 windowless_canvases_[1].reset(NULL);
499 background_canvas_.reset(); 515 background_canvas_.reset(NULL);
500 return; 516 return;
501 } 517 }
502 CreateCanvasFromHandle(windowless_buffer1, 518 CreateCanvasFromHandle(windowless_buffer1,
503 window_rect, 519 window_rect,
504 &windowless_canvases_[1]); 520 &windowless_canvases_[1]);
505 if (!windowless_canvases_[1].get()) { 521 if (!windowless_canvases_[1].get()) {
506 windowless_canvases_[0].reset(); 522 windowless_canvases_[0].reset(NULL);
507 background_canvas_.reset(); 523 background_canvas_.reset(NULL);
508 return; 524 return;
509 } 525 }
510 526
511 if (background_buffer) { 527 if (background_buffer) {
512 CreateCanvasFromHandle(background_buffer, 528 CreateCanvasFromHandle(background_buffer,
513 window_rect, 529 window_rect,
514 &background_canvas_); 530 &background_canvas_);
515 if (!background_canvas_.get()) { 531 if (!background_canvas_.get()) {
516 windowless_canvases_[0].reset(); 532 windowless_canvases_[0].reset(NULL);
517 windowless_canvases_[1].reset(); 533 windowless_canvases_[1].reset(NULL);
518 return; 534 return;
519 } 535 }
520 } 536 }
521 } 537 }
522 538
523 #elif defined(OS_MACOSX) 539 #elif defined(OS_MACOSX)
524 540
525 void WebPluginProxy::CreateDIBAndCGContextFromHandle( 541 void WebPluginProxy::CreateDIBAndCGContextFromHandle(
526 const TransportDIB::Handle& dib_handle, 542 const TransportDIB::Handle& dib_handle,
527 const gfx::Rect& window_rect, 543 const gfx::Rect& window_rect,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 window_rect, 580 window_rect,
565 &background_dib_, 581 &background_dib_,
566 &background_context_); 582 &background_context_);
567 } 583 }
568 584
569 #elif defined(USE_X11) 585 #elif defined(USE_X11)
570 586
571 void WebPluginProxy::CreateDIBAndCanvasFromHandle( 587 void WebPluginProxy::CreateDIBAndCanvasFromHandle(
572 const TransportDIB::Handle& dib_handle, 588 const TransportDIB::Handle& dib_handle,
573 const gfx::Rect& window_rect, 589 const gfx::Rect& window_rect,
574 scoped_ptr<TransportDIB>* dib_out, 590 scoped_refptr<SharedTransportDIB>* dib_out,
575 scoped_ptr<skia::PlatformCanvas>* canvas_out) { 591 SkAutoTUnref<skia::PlatformCanvas>* canvas) {
576 TransportDIB* dib = TransportDIB::Map(dib_handle); 592 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 593 // 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. 594 // the time we receive the handle, e.g. in case of multiple resizes.
580 if (dib) { 595 if (dib) {
581 canvas = dib->GetPlatformCanvas(window_rect.width(), window_rect.height()); 596 canvas->reset(
597 dib->GetPlatformCanvas(window_rect.width(), window_rect.height()));
598 } else {
599 canvas->reset(NULL);
582 } 600 }
583 dib_out->reset(dib); 601 *dib_out = new SharedTransportDIB(dib);
584 canvas_out->reset(canvas);
585 } 602 }
586 603
587 void WebPluginProxy::CreateShmPixmapFromDIB( 604 void WebPluginProxy::CreateShmPixmapFromDIB(
588 TransportDIB* dib, 605 TransportDIB* dib,
589 const gfx::Rect& window_rect, 606 const gfx::Rect& window_rect,
590 XID* pixmap_out) { 607 XID* pixmap_out) {
591 if (dib) { 608 if (dib) {
592 Display* display = ui::GetXDisplay(); 609 Display* display = ui::GetXDisplay();
593 XID root_window = ui::GetX11RootWindow(); 610 XID root_window = ui::GetX11RootWindow();
594 XShmSegmentInfo shminfo = {0}; 611 XShmSegmentInfo shminfo = {0};
(...skipping 25 matching lines...) Expand all
620 &windowless_dibs_[1], 637 &windowless_dibs_[1],
621 &windowless_canvases_[1]); 638 &windowless_canvases_[1]);
622 CreateDIBAndCanvasFromHandle(background_buffer, 639 CreateDIBAndCanvasFromHandle(background_buffer,
623 window_rect, 640 window_rect,
624 &background_dib_, 641 &background_dib_,
625 &background_canvas_); 642 &background_canvas_);
626 643
627 // If SHM pixmaps support is available, create SHM pixmaps to pass to the 644 // If SHM pixmaps support is available, create SHM pixmaps to pass to the
628 // delegate for windowless plugin painting. 645 // delegate for windowless plugin painting.
629 if (delegate_->IsWindowless() && use_shm_pixmap_) { 646 if (delegate_->IsWindowless() && use_shm_pixmap_) {
630 CreateShmPixmapFromDIB(windowless_dibs_[0].get(), 647 CreateShmPixmapFromDIB(windowless_dibs_[0]->dib(),
631 window_rect, 648 window_rect,
632 &windowless_shm_pixmaps_[0]); 649 &windowless_shm_pixmaps_[0]);
633 CreateShmPixmapFromDIB(windowless_dibs_[1].get(), 650 CreateShmPixmapFromDIB(windowless_dibs_[1]->dib(),
634 window_rect, 651 window_rect,
635 &windowless_shm_pixmaps_[1]); 652 &windowless_shm_pixmaps_[1]);
636 } 653 }
637 } 654 }
638 655
639 #elif defined(OS_ANDROID) 656 #elif defined(OS_ANDROID)
640 657
641 void WebPluginProxy::SetWindowlessBuffers( 658 void WebPluginProxy::SetWindowlessBuffers(
642 const TransportDIB::Handle& windowless_buffer0, 659 const TransportDIB::Handle& windowless_buffer0,
643 const TransportDIB::Handle& windowless_buffer1, 660 const TransportDIB::Handle& windowless_buffer1,
(...skipping 136 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 797 // Retrieve the IME status from a plug-in and send it to a renderer process
781 // when the plug-in has updated it. 798 // when the plug-in has updated it.
782 int input_type; 799 int input_type;
783 gfx::Rect caret_rect; 800 gfx::Rect caret_rect;
784 if (!delegate_->GetIMEStatus(&input_type, &caret_rect)) 801 if (!delegate_->GetIMEStatus(&input_type, &caret_rect))
785 return; 802 return;
786 803
787 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect)); 804 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect));
788 } 805 }
789 #endif 806 #endif
OLDNEW
« no previous file with comments | « content/plugin/webplugin_proxy.h ('k') | content/test/data/npapi/resize_during_paint.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698