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

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

Issue 11361170: Get windowless plugins working when accelerated compositing is turned on. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 1 month 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/renderer/webplugin_delegate_proxy.h » ('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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 int route_id, 60 int route_id,
61 const GURL& page_url, 61 const GURL& page_url,
62 int host_render_view_routing_id) 62 int host_render_view_routing_id)
63 : channel_(channel), 63 : channel_(channel),
64 route_id_(route_id), 64 route_id_(route_id),
65 window_npobject_(NULL), 65 window_npobject_(NULL),
66 plugin_element_(NULL), 66 plugin_element_(NULL),
67 delegate_(NULL), 67 delegate_(NULL),
68 waiting_for_paint_(false), 68 waiting_for_paint_(false),
69 page_url_(page_url), 69 page_url_(page_url),
70 transparent_(false),
71 windowless_buffer_index_(0), 70 windowless_buffer_index_(0),
72 host_render_view_routing_id_(host_render_view_routing_id), 71 host_render_view_routing_id_(host_render_view_routing_id),
73 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 72 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
74 #if defined(USE_X11) 73 #if defined(USE_X11)
75 windowless_shm_pixmaps_[0] = None; 74 windowless_shm_pixmaps_[0] = None;
76 windowless_shm_pixmaps_[1] = None; 75 windowless_shm_pixmaps_[1] = None;
77 use_shm_pixmap_ = false; 76 use_shm_pixmap_ = false;
78 77
79 // If the X server supports SHM pixmaps 78 // If the X server supports SHM pixmaps
80 // and the color depth and masks match, 79 // and the color depth and masks match,
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 // (since the plugin can make a synchronous call during paint event handling), 354 // (since the plugin can make a synchronous call during paint event handling),
356 // in which case we don't want to try to restore later. Not an owning ref 355 // in which case we don't want to try to restore later. Not an owning ref
357 // since owning the ref without owning the shared backing memory doesn't make 356 // since owning the ref without owning the shared backing memory doesn't make
358 // sense, so this should only be used for pointer comparisons. 357 // sense, so this should only be used for pointer comparisons.
359 CGContextRef saved_context_weak = windowless_context(); 358 CGContextRef saved_context_weak = windowless_context();
360 // We also save the buffer index for the comparison because if we flip buffers 359 // We also save the buffer index for the comparison because if we flip buffers
361 // but haven't reallocated them then we do need to restore the context because 360 // but haven't reallocated them then we do need to restore the context because
362 // it is going to continue to be used. 361 // it is going to continue to be used.
363 int saved_index = windowless_buffer_index_; 362 int saved_index = windowless_buffer_index_;
364 363
365 if (background_context_.get()) {
366 base::mac::ScopedCFTypeRef<CGImageRef> image(
367 CGBitmapContextCreateImage(background_context_));
368 CGRect source_rect = rect.ToCGRect();
369 // Flip the rect we use to pull from the canvas, since it's upside-down.
370 source_rect.origin.y = CGImageGetHeight(image) - rect.y() - rect.height();
371 base::mac::ScopedCFTypeRef<CGImageRef> sub_image(
372 CGImageCreateWithImageInRect(image, source_rect));
373 CGContextDrawImage(windowless_context(), rect.ToCGRect(), sub_image);
374 } else if (transparent_) {
375 CGContextClearRect(windowless_context(), rect.ToCGRect());
376 }
377 CGContextClipToRect(windowless_context(), rect.ToCGRect()); 364 CGContextClipToRect(windowless_context(), rect.ToCGRect());
378 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia 365 // TODO(caryclark): This is a temporary workaround to allow the Darwin / Skia
379 // port to share code with the Darwin / CG port. All ports will eventually use 366 // port to share code with the Darwin / CG port. All ports will eventually use
380 // the common code below. 367 // the common code below.
381 delegate_->CGPaint(windowless_context(), rect); 368 delegate_->CGPaint(windowless_context(), rect);
382 if (windowless_contexts_[saved_index].get() == saved_context_weak) 369 if (windowless_contexts_[saved_index].get() == saved_context_weak)
383 CGContextRestoreGState(windowless_contexts_[saved_index]); 370 CGContextRestoreGState(windowless_contexts_[saved_index]);
384 #else 371 #else
385 // See above comment about windowless_context_ changing. 372 // See above comment about windowless_context_ changing.
386 // http::/crbug.com/139462 373 // http::/crbug.com/139462
387 skia::PlatformCanvas* saved_canvas = windowless_canvas(); 374 skia::PlatformCanvas* saved_canvas = windowless_canvas();
388 SkAutoRef local_ref(saved_canvas); 375 SkAutoRef local_ref(saved_canvas);
389 #if defined(USE_X11) 376 #if defined(USE_X11)
390 scoped_refptr<SharedTransportDIB> local_dib_ref( 377 scoped_refptr<SharedTransportDIB> local_dib_ref(
391 windowless_dibs_[windowless_buffer_index_]); 378 windowless_dibs_[windowless_buffer_index_]);
392 #endif 379 #endif
393 380
394 saved_canvas->save(); 381 saved_canvas->save();
395 382
396 // The given clip rect is relative to the plugin coordinate system. 383 // The given clip rect is relative to the plugin coordinate system.
397 SkRect sk_rect = { SkIntToScalar(rect.x()), 384 SkRect sk_rect = { SkIntToScalar(rect.x()),
398 SkIntToScalar(rect.y()), 385 SkIntToScalar(rect.y()),
399 SkIntToScalar(rect.right()), 386 SkIntToScalar(rect.right()),
400 SkIntToScalar(rect.bottom()) }; 387 SkIntToScalar(rect.bottom()) };
401 saved_canvas->clipRect(sk_rect); 388 saved_canvas->clipRect(sk_rect);
402 389
403 // Setup the background. 390 // Fill a transparent value so that if the plugin supports transparency that
404 if (background_canvas_.get() && background_canvas_.get()->getDevice()) { 391 // will work.
405 // When a background canvas is given, we're in transparent mode. This means 392 saved_canvas->drawColor(SkColorSetARGB(0, 0, 0, 0), SkXfermode::kSrc_Mode);
406 // the plugin wants to have the image of the page in the canvas it's drawing
407 // into (which is windowless_canvases_) so it can do blending. So we copy
408 // the background bitmap into the windowless canvas.
409 const SkBitmap& background_bitmap =
410 skia::GetTopDevice(*background_canvas_)->accessBitmap(false);
411 saved_canvas->drawBitmap(background_bitmap, 0, 0);
412 } else {
413 // In non-transparent mode, the plugin doesn't care what's underneath, so we
414 // can just give it black.
415 SkPaint black_fill_paint;
416 black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00);
417 saved_canvas->drawPaint(black_fill_paint);
418 }
419 393
420 // Bring the windowless canvas into the window coordinate system, which is 394 // Bring the windowless canvas into the window coordinate system, which is
421 // how the plugin expects to draw (since the windowless API was originally 395 // how the plugin expects to draw (since the windowless API was originally
422 // designed just for scribbling over the web page). 396 // designed just for scribbling over the web page).
423 saved_canvas->translate(SkIntToScalar(-delegate_->GetRect().x()), 397 saved_canvas->translate(SkIntToScalar(-delegate_->GetRect().x()),
424 SkIntToScalar(-delegate_->GetRect().y())); 398 SkIntToScalar(-delegate_->GetRect().y()));
425 399
426 // Before we send the invalidate, paint so that renderer uses the updated 400 // Before we send the invalidate, paint so that renderer uses the updated
427 // bitmap. 401 // bitmap.
428 delegate_->Paint(saved_canvas, offset_rect); 402 delegate_->Paint(saved_canvas, offset_rect);
429 403
430 saved_canvas->restore(); 404 saved_canvas->restore();
431 #endif 405 #endif
432 } 406 }
433 407
434 void WebPluginProxy::UpdateGeometry( 408 void WebPluginProxy::UpdateGeometry(
435 const gfx::Rect& window_rect, 409 const gfx::Rect& window_rect,
436 const gfx::Rect& clip_rect, 410 const gfx::Rect& clip_rect,
437 const TransportDIB::Handle& windowless_buffer0, 411 const TransportDIB::Handle& windowless_buffer0,
438 const TransportDIB::Handle& windowless_buffer1, 412 const TransportDIB::Handle& windowless_buffer1,
439 int windowless_buffer_index, 413 int windowless_buffer_index) {
440 const TransportDIB::Handle& background_buffer,
441 bool transparent) {
442 gfx::Rect old = delegate_->GetRect(); 414 gfx::Rect old = delegate_->GetRect();
443 gfx::Rect old_clip_rect = delegate_->GetClipRect(); 415 gfx::Rect old_clip_rect = delegate_->GetClipRect();
444 transparent_ = transparent;
445 416
446 // Update the buffers before doing anything that could call into plugin code, 417 // Update the buffers before doing anything that could call into plugin code,
447 // so that we don't process buffer changes out of order if plugins make 418 // so that we don't process buffer changes out of order if plugins make
448 // synchronous calls that lead to nested UpdateGeometry calls. 419 // synchronous calls that lead to nested UpdateGeometry calls.
449 if (TransportDIB::is_valid_handle(windowless_buffer0)) { 420 if (TransportDIB::is_valid_handle(windowless_buffer0)) {
450 // The plugin's rect changed, so now we have new buffers to draw into. 421 // The plugin's rect changed, so now we have new buffers to draw into.
451 SetWindowlessBuffers(windowless_buffer0, 422 SetWindowlessBuffers(windowless_buffer0,
452 windowless_buffer1, 423 windowless_buffer1,
453 background_buffer,
454 window_rect); 424 window_rect);
455 } 425 }
456 426
457 DCHECK(0 <= windowless_buffer_index && windowless_buffer_index <= 1); 427 DCHECK(0 <= windowless_buffer_index && windowless_buffer_index <= 1);
458 windowless_buffer_index_ = windowless_buffer_index; 428 windowless_buffer_index_ = windowless_buffer_index;
459 #if defined(USE_X11) 429 #if defined(USE_X11)
460 delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap()); 430 delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap());
461 #endif 431 #endif
462 432
463 #if defined(OS_MACOSX) 433 #if defined(OS_MACOSX)
(...skipping 25 matching lines...) Expand all
489 dib_handle)) { 459 dib_handle)) {
490 canvas->reset(NULL); 460 canvas->reset(NULL);
491 } 461 }
492 // The canvas does not own the section so we need to close it now. 462 // The canvas does not own the section so we need to close it now.
493 CloseHandle(dib_handle); 463 CloseHandle(dib_handle);
494 } 464 }
495 465
496 void WebPluginProxy::SetWindowlessBuffers( 466 void WebPluginProxy::SetWindowlessBuffers(
497 const TransportDIB::Handle& windowless_buffer0, 467 const TransportDIB::Handle& windowless_buffer0,
498 const TransportDIB::Handle& windowless_buffer1, 468 const TransportDIB::Handle& windowless_buffer1,
499 const TransportDIB::Handle& background_buffer,
500 const gfx::Rect& window_rect) { 469 const gfx::Rect& window_rect) {
501 CreateCanvasFromHandle(windowless_buffer0, 470 CreateCanvasFromHandle(windowless_buffer0,
502 window_rect, 471 window_rect,
503 &windowless_canvases_[0]); 472 &windowless_canvases_[0]);
504 if (!windowless_canvases_[0].get()) { 473 if (!windowless_canvases_[0].get()) {
505 windowless_canvases_[1].reset(NULL); 474 windowless_canvases_[1].reset(NULL);
506 background_canvas_.reset(NULL);
507 return; 475 return;
508 } 476 }
509 CreateCanvasFromHandle(windowless_buffer1, 477 CreateCanvasFromHandle(windowless_buffer1,
510 window_rect, 478 window_rect,
511 &windowless_canvases_[1]); 479 &windowless_canvases_[1]);
512 if (!windowless_canvases_[1].get()) { 480 if (!windowless_canvases_[1].get()) {
513 windowless_canvases_[0].reset(NULL); 481 windowless_canvases_[0].reset(NULL);
514 background_canvas_.reset(NULL);
515 return; 482 return;
516 } 483 }
517
518 if (background_buffer) {
519 CreateCanvasFromHandle(background_buffer,
520 window_rect,
521 &background_canvas_);
522 if (!background_canvas_.get()) {
523 windowless_canvases_[0].reset(NULL);
524 windowless_canvases_[1].reset(NULL);
525 return;
526 }
527 }
528 } 484 }
529 485
530 #elif defined(OS_MACOSX) 486 #elif defined(OS_MACOSX)
531 487
532 void WebPluginProxy::CreateDIBAndCGContextFromHandle( 488 void WebPluginProxy::CreateDIBAndCGContextFromHandle(
533 const TransportDIB::Handle& dib_handle, 489 const TransportDIB::Handle& dib_handle,
534 const gfx::Rect& window_rect, 490 const gfx::Rect& window_rect,
535 scoped_ptr<TransportDIB>* dib_out, 491 scoped_ptr<TransportDIB>* dib_out,
536 base::mac::ScopedCFTypeRef<CGContextRef>* cg_context_out) { 492 base::mac::ScopedCFTypeRef<CGContextRef>* cg_context_out) {
537 // Convert the shared memory handle to a handle that works in our process, 493 // Convert the shared memory handle to a handle that works in our process,
(...skipping 12 matching lines...) Expand all
550 CGContextTranslateCTM(cg_context, 0, window_rect.height()); 506 CGContextTranslateCTM(cg_context, 0, window_rect.height());
551 CGContextScaleCTM(cg_context, 1, -1); 507 CGContextScaleCTM(cg_context, 1, -1);
552 } 508 }
553 dib_out->reset(dib); 509 dib_out->reset(dib);
554 cg_context_out->reset(cg_context); 510 cg_context_out->reset(cg_context);
555 } 511 }
556 512
557 void WebPluginProxy::SetWindowlessBuffers( 513 void WebPluginProxy::SetWindowlessBuffers(
558 const TransportDIB::Handle& windowless_buffer0, 514 const TransportDIB::Handle& windowless_buffer0,
559 const TransportDIB::Handle& windowless_buffer1, 515 const TransportDIB::Handle& windowless_buffer1,
560 const TransportDIB::Handle& background_buffer,
561 const gfx::Rect& window_rect) { 516 const gfx::Rect& window_rect) {
562 CreateDIBAndCGContextFromHandle(windowless_buffer0, 517 CreateDIBAndCGContextFromHandle(windowless_buffer0,
563 window_rect, 518 window_rect,
564 &windowless_dibs_[0], 519 &windowless_dibs_[0],
565 &windowless_contexts_[0]); 520 &windowless_contexts_[0]);
566 CreateDIBAndCGContextFromHandle(windowless_buffer1, 521 CreateDIBAndCGContextFromHandle(windowless_buffer1,
567 window_rect, 522 window_rect,
568 &windowless_dibs_[1], 523 &windowless_dibs_[1],
569 &windowless_contexts_[1]); 524 &windowless_contexts_[1]);
570 CreateDIBAndCGContextFromHandle(background_buffer,
571 window_rect,
572 &background_dib_,
573 &background_context_);
574 } 525 }
575 526
576 #elif defined(USE_X11) 527 #elif defined(USE_X11)
577 528
578 void WebPluginProxy::CreateDIBAndCanvasFromHandle( 529 void WebPluginProxy::CreateDIBAndCanvasFromHandle(
579 const TransportDIB::Handle& dib_handle, 530 const TransportDIB::Handle& dib_handle,
580 const gfx::Rect& window_rect, 531 const gfx::Rect& window_rect,
581 scoped_refptr<SharedTransportDIB>* dib_out, 532 scoped_refptr<SharedTransportDIB>* dib_out,
582 SkAutoTUnref<skia::PlatformCanvas>* canvas) { 533 SkAutoTUnref<skia::PlatformCanvas>* canvas) {
583 TransportDIB* dib = TransportDIB::Map(dib_handle); 534 TransportDIB* dib = TransportDIB::Map(dib_handle);
(...skipping 26 matching lines...) Expand all
610 NULL, &shminfo, 561 NULL, &shminfo,
611 window_rect.width(), window_rect.height(), 562 window_rect.width(), window_rect.height(),
612 DefaultDepth(display, 563 DefaultDepth(display,
613 DefaultScreen(display))); 564 DefaultScreen(display)));
614 } 565 }
615 } 566 }
616 567
617 void WebPluginProxy::SetWindowlessBuffers( 568 void WebPluginProxy::SetWindowlessBuffers(
618 const TransportDIB::Handle& windowless_buffer0, 569 const TransportDIB::Handle& windowless_buffer0,
619 const TransportDIB::Handle& windowless_buffer1, 570 const TransportDIB::Handle& windowless_buffer1,
620 const TransportDIB::Handle& background_buffer,
621 const gfx::Rect& window_rect) { 571 const gfx::Rect& window_rect) {
622 CreateDIBAndCanvasFromHandle(windowless_buffer0, 572 CreateDIBAndCanvasFromHandle(windowless_buffer0,
623 window_rect, 573 window_rect,
624 &windowless_dibs_[0], 574 &windowless_dibs_[0],
625 &windowless_canvases_[0]); 575 &windowless_canvases_[0]);
626 CreateDIBAndCanvasFromHandle(windowless_buffer1, 576 CreateDIBAndCanvasFromHandle(windowless_buffer1,
627 window_rect, 577 window_rect,
628 &windowless_dibs_[1], 578 &windowless_dibs_[1],
629 &windowless_canvases_[1]); 579 &windowless_canvases_[1]);
630 CreateDIBAndCanvasFromHandle(background_buffer,
631 window_rect,
632 &background_dib_,
633 &background_canvas_);
634 580
635 // If SHM pixmaps support is available, create SHM pixmaps to pass to the 581 // If SHM pixmaps support is available, create SHM pixmaps to pass to the
636 // delegate for windowless plugin painting. 582 // delegate for windowless plugin painting.
637 if (delegate_->IsWindowless() && use_shm_pixmap_) { 583 if (delegate_->IsWindowless() && use_shm_pixmap_) {
638 CreateShmPixmapFromDIB(windowless_dibs_[0]->dib(), 584 CreateShmPixmapFromDIB(windowless_dibs_[0]->dib(),
639 window_rect, 585 window_rect,
640 &windowless_shm_pixmaps_[0]); 586 &windowless_shm_pixmaps_[0]);
641 CreateShmPixmapFromDIB(windowless_dibs_[1]->dib(), 587 CreateShmPixmapFromDIB(windowless_dibs_[1]->dib(),
642 window_rect, 588 window_rect,
643 &windowless_shm_pixmaps_[1]); 589 &windowless_shm_pixmaps_[1]);
644 } 590 }
645 } 591 }
646 592
647 #elif defined(OS_ANDROID) 593 #elif defined(OS_ANDROID)
648 594
649 void WebPluginProxy::SetWindowlessBuffers( 595 void WebPluginProxy::SetWindowlessBuffers(
650 const TransportDIB::Handle& windowless_buffer0, 596 const TransportDIB::Handle& windowless_buffer0,
651 const TransportDIB::Handle& windowless_buffer1, 597 const TransportDIB::Handle& windowless_buffer1,
652 const TransportDIB::Handle& background_buffer,
653 const gfx::Rect& window_rect) { 598 const gfx::Rect& window_rect) {
654 NOTIMPLEMENTED(); 599 NOTIMPLEMENTED();
655 } 600 }
656 601
657 #endif 602 #endif
658 603
659 void WebPluginProxy::CancelDocumentLoad() { 604 void WebPluginProxy::CancelDocumentLoad() {
660 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); 605 Send(new PluginHostMsg_CancelDocumentLoad(route_id_));
661 } 606 }
662 607
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 int input_type; 727 int input_type;
783 gfx::Rect caret_rect; 728 gfx::Rect caret_rect;
784 if (!delegate_->GetIMEStatus(&input_type, &caret_rect)) 729 if (!delegate_->GetIMEStatus(&input_type, &caret_rect))
785 return; 730 return;
786 731
787 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect)); 732 Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect));
788 } 733 }
789 #endif 734 #endif
790 735
791 } // namespace content 736 } // namespace content
OLDNEW
« no previous file with comments | « content/plugin/webplugin_proxy.h ('k') | content/renderer/webplugin_delegate_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698