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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp

Issue 2057283002: Fix canvas-related crash caused by bad object teardown sequence (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix test crash Created 4 years, 6 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
« no previous file with comments | « third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp ('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 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 , m_isDeferralEnabled(true) 110 , m_isDeferralEnabled(true)
111 , m_isRegisteredTaskObserver(false) 111 , m_isRegisteredTaskObserver(false)
112 , m_renderingTaskCompletedForCurrentFrame(false) 112 , m_renderingTaskCompletedForCurrentFrame(false)
113 , m_softwareRenderingWhileHidden(false) 113 , m_softwareRenderingWhileHidden(false)
114 , m_lastImageId(0) 114 , m_lastImageId(0)
115 , m_lastFilter(GL_LINEAR) 115 , m_lastFilter(GL_LINEAR)
116 , m_accelerationMode(accelerationMode) 116 , m_accelerationMode(accelerationMode)
117 , m_opacityMode(opacityMode) 117 , m_opacityMode(opacityMode)
118 , m_size(size) 118 , m_size(size)
119 { 119 {
120 ASSERT(m_contextProvider); 120 DCHECK(m_contextProvider);
121 // Used by browser tests to detect the use of a Canvas2DLayerBridge. 121 // Used by browser tests to detect the use of a Canvas2DLayerBridge.
122 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL); 122 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_GLOBAL);
123 startRecording(); 123 startRecording();
124 } 124 }
125 125
126 Canvas2DLayerBridge::~Canvas2DLayerBridge() 126 Canvas2DLayerBridge::~Canvas2DLayerBridge()
127 { 127 {
128 ASSERT(m_destructionInProgress); 128 DCHECK(m_destructionInProgress);
129 #if USE_IOSURFACE_FOR_2D_CANVAS 129 #if USE_IOSURFACE_FOR_2D_CANVAS
130 clearCHROMIUMImageCache(); 130 clearCHROMIUMImageCache();
131 #endif // USE_IOSURFACE_FOR_2D_CANVAS 131 #endif // USE_IOSURFACE_FOR_2D_CANVAS
132 132
133 m_layer.reset(); 133 m_layer.reset();
134 ASSERT(m_mailboxes.size() == 0); 134 DCHECK_EQ(0u, m_mailboxes.size());
135 } 135 }
136 136
137 void Canvas2DLayerBridge::startRecording() 137 void Canvas2DLayerBridge::startRecording()
138 { 138 {
139 ASSERT(m_isDeferralEnabled); 139 DCHECK(m_isDeferralEnabled);
140 m_recorder = adoptPtr(new SkPictureRecorder); 140 m_recorder = adoptPtr(new SkPictureRecorder);
141 m_recorder->beginRecording(m_size.width(), m_size.height(), nullptr); 141 m_recorder->beginRecording(m_size.width(), m_size.height(), nullptr);
142 if (m_imageBuffer) { 142 if (m_imageBuffer) {
143 m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas()); 143 m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas());
144 } 144 }
145 m_recordingPixelCount = 0; 145 m_recordingPixelCount = 0;
146 } 146 }
147 147
148 void Canvas2DLayerBridge::setLoggerForTesting(PassOwnPtr<Logger> logger) 148 void Canvas2DLayerBridge::setLoggerForTesting(PassOwnPtr<Logger> logger)
149 { 149 {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 338
339 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag e->getTextureHandle(true))->fID; 339 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag e->getTextureHandle(true))->fID;
340 gl->BindTexture(GL_TEXTURE_2D, textureID); 340 gl->BindTexture(GL_TEXTURE_2D, textureID);
341 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter()); 341 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter());
342 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter()); 342 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter());
343 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 343 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
344 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 344 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
345 345
346 // Re-use the texture's existing mailbox, if there is one. 346 // Re-use the texture's existing mailbox, if there is one.
347 if (mailboxInfo.m_image->getTexture()->getCustomData()) { 347 if (mailboxInfo.m_image->getTexture()->getCustomData()) {
348 ASSERT(mailboxInfo.m_image->getTexture()->getCustomData()->size() == siz eof(mailboxInfo.m_mailbox.name)); 348 DCHECK(mailboxInfo.m_image->getTexture()->getCustomData()->size() == siz eof(mailboxInfo.m_mailbox.name));
349 memcpy(&mailboxInfo.m_mailbox.name[0], mailboxInfo.m_image->getTexture() ->getCustomData()->data(), sizeof(mailboxInfo.m_mailbox.name)); 349 memcpy(&mailboxInfo.m_mailbox.name[0], mailboxInfo.m_image->getTexture() ->getCustomData()->data(), sizeof(mailboxInfo.m_mailbox.name));
350 } else { 350 } else {
351 gl->GenMailboxCHROMIUM(mailboxInfo.m_mailbox.name); 351 gl->GenMailboxCHROMIUM(mailboxInfo.m_mailbox.name);
352 RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&mailboxIn fo.m_mailbox.name[0], sizeof(mailboxInfo.m_mailbox.name))); 352 RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&mailboxIn fo.m_mailbox.name[0], sizeof(mailboxInfo.m_mailbox.name)));
353 mailboxInfo.m_image->getTexture()->setCustomData(mailboxNameData.get()); 353 mailboxInfo.m_image->getTexture()->setCustomData(mailboxNameData.get());
354 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo.m_mailbox.name); 354 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo.m_mailbox.name);
355 } 355 }
356 356
357 if (isHidden()) { 357 if (isHidden()) {
358 // With hidden canvases, we release the SkImage immediately because 358 // With hidden canvases, we release the SkImage immediately because
(...skipping 28 matching lines...) Expand all
387 if (bridge) { 387 if (bridge) {
388 bridge->hibernate(); 388 bridge->hibernate();
389 } else { 389 } else {
390 Canvas2DLayerBridge::Logger localLogger; 390 Canvas2DLayerBridge::Logger localLogger;
391 localLogger.reportHibernationEvent(Canvas2DLayerBridge::HibernationAbort edDueToDestructionWhileHibernatePending); 391 localLogger.reportHibernationEvent(Canvas2DLayerBridge::HibernationAbort edDueToDestructionWhileHibernatePending);
392 } 392 }
393 } 393 }
394 394
395 void Canvas2DLayerBridge::hibernate() 395 void Canvas2DLayerBridge::hibernate()
396 { 396 {
397 ASSERT(!isHibernating()); 397 DCHECK(!isHibernating());
398 ASSERT(m_hibernationScheduled); 398 DCHECK(m_hibernationScheduled);
399 399
400 m_hibernationScheduled = false; 400 m_hibernationScheduled = false;
401 401
402 if (m_destructionInProgress) { 402 if (m_destructionInProgress) {
403 m_logger->reportHibernationEvent(HibernationAbortedDueToPendingDestructi on); 403 m_logger->reportHibernationEvent(HibernationAbortedDueToPendingDestructi on);
404 return; 404 return;
405 } 405 }
406 406
407 if (!m_surface) { 407 if (!m_surface) {
408 m_logger->reportHibernationEvent(HibernationAbortedBecauseNoSurface); 408 m_logger->reportHibernationEvent(HibernationAbortedBecauseNoSurface);
(...skipping 22 matching lines...) Expand all
431 return; 431 return;
432 } 432 }
433 // No HibernationEvent reported on success. This is on purppose to avoid 433 // No HibernationEvent reported on success. This is on purppose to avoid
434 // non-complementary stats. Each HibernationScheduled event is paired with 434 // non-complementary stats. Each HibernationScheduled event is paired with
435 // exactly one failure or exit event. 435 // exactly one failure or exit event.
436 flushRecordingOnly(); 436 flushRecordingOnly();
437 // The following checks that the flush succeeded, which should always be the 437 // The following checks that the flush succeeded, which should always be the
438 // case because flushRecordingOnly should only fail it it fails to allocate 438 // case because flushRecordingOnly should only fail it it fails to allocate
439 // a surface, and we have an early exit at the top of this function for when 439 // a surface, and we have an early exit at the top of this function for when
440 // 'this' does not already have a surface. 440 // 'this' does not already have a surface.
441 ASSERT(!m_haveRecordedDrawCommands); 441 DCHECK(!m_haveRecordedDrawCommands);
442 SkPaint copyPaint; 442 SkPaint copyPaint;
443 copyPaint.setXfermodeMode(SkXfermode::kSrc_Mode); 443 copyPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
444 m_surface->draw(tempHibernationSurface->getCanvas(), 0, 0, &copyPaint); // G PU readback 444 m_surface->draw(tempHibernationSurface->getCanvas(), 0, 0, &copyPaint); // G PU readback
445 m_hibernationImage = adoptRef(tempHibernationSurface->newImageSnapshot()); 445 m_hibernationImage = adoptRef(tempHibernationSurface->newImageSnapshot());
446 m_surface.clear(); // destroy the GPU-backed buffer 446 m_surface.clear(); // destroy the GPU-backed buffer
447 m_layer->clearTexture(); 447 m_layer->clearTexture();
448 #if USE_IOSURFACE_FOR_2D_CANVAS 448 #if USE_IOSURFACE_FOR_2D_CANVAS
449 clearCHROMIUMImageCache(); 449 clearCHROMIUMImageCache();
450 #endif // USE_IOSURFACE_FOR_2D_CANVAS 450 #endif // USE_IOSURFACE_FOR_2D_CANVAS
451 m_logger->didStartHibernating(); 451 m_logger->didStartHibernating();
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 580
581 if (m_layer) { 581 if (m_layer) {
582 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 582 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
583 m_layer->clearTexture(); 583 m_layer->clearTexture();
584 // Orphaning the layer is required to trigger the recration of a new lay er 584 // Orphaning the layer is required to trigger the recration of a new lay er
585 // in the case where destruction is caused by a canvas resize. Test: 585 // in the case where destruction is caused by a canvas resize. Test:
586 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html 586 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html
587 m_layer->layer()->removeFromParent(); 587 m_layer->layer()->removeFromParent();
588 } 588 }
589 589
590 ASSERT(!m_bytesAllocated); 590 DCHECK(!m_bytesAllocated);
591 } 591 }
592 592
593 void Canvas2DLayerBridge::unregisterTaskObserver() 593 void Canvas2DLayerBridge::unregisterTaskObserver()
594 { 594 {
595 if (m_isRegisteredTaskObserver) { 595 if (m_isRegisteredTaskObserver) {
596 Platform::current()->currentThread()->removeTaskObserver(this); 596 Platform::current()->currentThread()->removeTaskObserver(this);
597 m_isRegisteredTaskObserver = false; 597 m_isRegisteredTaskObserver = false;
598 } 598 }
599 } 599 }
600 600
601 void Canvas2DLayerBridge::setFilterQuality(SkFilterQuality filterQuality) 601 void Canvas2DLayerBridge::setFilterQuality(SkFilterQuality filterQuality)
602 { 602 {
603 ASSERT(!m_destructionInProgress); 603 DCHECK(!m_destructionInProgress);
604 m_filterQuality = filterQuality; 604 m_filterQuality = filterQuality;
605 if (m_layer) 605 if (m_layer)
606 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); 606 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
607 } 607 }
608 608
609 void Canvas2DLayerBridge::setIsHidden(bool hidden) 609 void Canvas2DLayerBridge::setIsHidden(bool hidden)
610 { 610 {
611 bool newHiddenValue = hidden || m_destructionInProgress; 611 bool newHiddenValue = hidden || m_destructionInProgress;
612 if (m_isHidden == newHiddenValue) 612 if (m_isHidden == newHiddenValue)
613 return; 613 return;
(...skipping 28 matching lines...) Expand all
642 642
643 bool Canvas2DLayerBridge::writePixels(const SkImageInfo& origInfo, const void* p ixels, size_t rowBytes, int x, int y) 643 bool Canvas2DLayerBridge::writePixels(const SkImageInfo& origInfo, const void* p ixels, size_t rowBytes, int x, int y)
644 { 644 {
645 if (!getOrCreateSurface()) 645 if (!getOrCreateSurface())
646 return false; 646 return false;
647 if (x <= 0 && y <= 0 && x + origInfo.width() >= m_size.width() && y + origIn fo.height() >= m_size.height()) { 647 if (x <= 0 && y <= 0 && x + origInfo.width() >= m_size.width() && y + origIn fo.height() >= m_size.height()) {
648 skipQueuedDrawCommands(); 648 skipQueuedDrawCommands();
649 } else { 649 } else {
650 flush(); 650 flush();
651 } 651 }
652 ASSERT(!m_haveRecordedDrawCommands); 652 DCHECK(!m_haveRecordedDrawCommands);
653 // call write pixels on the surface, not the recording canvas. 653 // call write pixels on the surface, not the recording canvas.
654 // No need to call beginDirectSurfaceAccessModeIfNeeded() because writePixel s 654 // No need to call beginDirectSurfaceAccessModeIfNeeded() because writePixel s
655 // ignores the matrix and clip state. 655 // ignores the matrix and clip state.
656 return getOrCreateSurface()->getCanvas()->writePixels(origInfo, pixels, rowB ytes, x, y); 656 return getOrCreateSurface()->getCanvas()->writePixels(origInfo, pixels, rowB ytes, x, y);
657 } 657 }
658 658
659 void Canvas2DLayerBridge::skipQueuedDrawCommands() 659 void Canvas2DLayerBridge::skipQueuedDrawCommands()
660 { 660 {
661 if (m_haveRecordedDrawCommands) { 661 if (m_haveRecordedDrawCommands) {
662 m_recorder->finishRecordingAsPicture(); 662 m_recorder->finishRecordingAsPicture();
663 startRecording(); 663 startRecording();
664 m_haveRecordedDrawCommands = false; 664 m_haveRecordedDrawCommands = false;
665 } 665 }
666 666
667 if (m_isDeferralEnabled) { 667 if (m_isDeferralEnabled) {
668 unregisterTaskObserver(); 668 unregisterTaskObserver();
669 if (m_rateLimiter) 669 if (m_rateLimiter)
670 m_rateLimiter->reset(); 670 m_rateLimiter->reset();
671 } 671 }
672 } 672 }
673 673
674 void Canvas2DLayerBridge::flushRecordingOnly() 674 void Canvas2DLayerBridge::flushRecordingOnly()
675 { 675 {
676 ASSERT(!m_destructionInProgress); 676 DCHECK(!m_destructionInProgress);
677 677
678 if (m_haveRecordedDrawCommands && getOrCreateSurface()) { 678 if (m_haveRecordedDrawCommands && getOrCreateSurface()) {
679 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly"); 679 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecordingOnly");
680 m_recorder->finishRecordingAsPicture()->playback(getOrCreateSurface()->g etCanvas()); 680 m_recorder->finishRecordingAsPicture()->playback(getOrCreateSurface()->g etCanvas());
681 if (m_isDeferralEnabled) 681 if (m_isDeferralEnabled)
682 startRecording(); 682 startRecording();
683 m_haveRecordedDrawCommands = false; 683 m_haveRecordedDrawCommands = false;
684 } 684 }
685 } 685 }
686 686
(...skipping 23 matching lines...) Expand all
710 if (m_layer && !m_destructionInProgress) { 710 if (m_layer && !m_destructionInProgress) {
711 // Call checkSurfaceValid to ensure rate limiter is disabled if context is lost. 711 // Call checkSurfaceValid to ensure rate limiter is disabled if context is lost.
712 if (!checkSurfaceValid()) 712 if (!checkSurfaceValid())
713 return nullptr; 713 return nullptr;
714 } 714 }
715 return m_contextProvider ? m_contextProvider->contextGL() : nullptr; 715 return m_contextProvider ? m_contextProvider->contextGL() : nullptr;
716 } 716 }
717 717
718 bool Canvas2DLayerBridge::checkSurfaceValid() 718 bool Canvas2DLayerBridge::checkSurfaceValid()
719 { 719 {
720 ASSERT(!m_destructionInProgress); 720 DCHECK(!m_destructionInProgress);
721 if (m_destructionInProgress) 721 if (m_destructionInProgress)
722 return false; 722 return false;
723 if (isHibernating()) 723 if (isHibernating())
724 return true; 724 return true;
725 if (!m_layer) 725 if (!m_layer)
726 return true; 726 return true;
727 if (!m_surface) 727 if (!m_surface)
728 return false; 728 return false;
729 if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERR OR) { 729 if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERR OR) {
730 m_surface.clear(); 730 m_surface.clear();
731 for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes. end(); ++mailboxInfo) { 731 for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes. end(); ++mailboxInfo) {
732 if (mailboxInfo->m_image) 732 if (mailboxInfo->m_image)
733 mailboxInfo->m_image.clear(); 733 mailboxInfo->m_image.clear();
734 } 734 }
735 if (m_imageBuffer) 735 if (m_imageBuffer)
736 m_imageBuffer->notifySurfaceInvalid(); 736 m_imageBuffer->notifySurfaceInvalid();
737 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanva sGPUContextLost); 737 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanva sGPUContextLost);
738 } 738 }
739 return m_surface; 739 return m_surface;
740 } 740 }
741 741
742 bool Canvas2DLayerBridge::restoreSurface() 742 bool Canvas2DLayerBridge::restoreSurface()
743 { 743 {
744 ASSERT(!m_destructionInProgress); 744 DCHECK(!m_destructionInProgress);
745 if (m_destructionInProgress) 745 if (m_destructionInProgress)
746 return false; 746 return false;
747 ASSERT(isAccelerated() && !m_surface); 747 DCHECK(isAccelerated() && !m_surface);
748 748
749 gpu::gles2::GLES2Interface* sharedGL = nullptr; 749 gpu::gles2::GLES2Interface* sharedGL = nullptr;
750 m_layer->clearTexture(); 750 m_layer->clearTexture();
751 m_contextProvider = adoptPtr(Platform::current()->createSharedOffscreenGraph icsContext3DProvider()); 751 m_contextProvider = adoptPtr(Platform::current()->createSharedOffscreenGraph icsContext3DProvider());
752 if (m_contextProvider) 752 if (m_contextProvider)
753 sharedGL = m_contextProvider->contextGL(); 753 sharedGL = m_contextProvider->contextGL();
754 754
755 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { 755 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) {
756 GrContext* grCtx = m_contextProvider->grContext(); 756 GrContext* grCtx = m_contextProvider->grContext();
757 bool surfaceIsAccelerated; 757 bool surfaceIsAccelerated;
(...skipping 19 matching lines...) Expand all
777 bool Canvas2DLayerBridge::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExternalBitmap* bitmap) 777 bool Canvas2DLayerBridge::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExternalBitmap* bitmap)
778 { 778 {
779 if (m_destructionInProgress) { 779 if (m_destructionInProgress) {
780 // It can be hit in the following sequence. 780 // It can be hit in the following sequence.
781 // 1. Canvas draws something. 781 // 1. Canvas draws something.
782 // 2. The compositor begins the frame. 782 // 2. The compositor begins the frame.
783 // 3. Javascript makes a context be lost. 783 // 3. Javascript makes a context be lost.
784 // 4. Here. 784 // 4. Here.
785 return false; 785 return false;
786 } 786 }
787 ASSERT(isAccelerated() || isHibernating() || m_softwareRenderingWhileHidden) ; 787 DCHECK(isAccelerated() || isHibernating() || m_softwareRenderingWhileHidden) ;
788 788
789 // if hibernating but not hidden, we want to wake up from 789 // if hibernating but not hidden, we want to wake up from
790 // hibernation 790 // hibernation
791 if ((isHibernating() || m_softwareRenderingWhileHidden) && isHidden()) 791 if ((isHibernating() || m_softwareRenderingWhileHidden) && isHidden())
792 return false; 792 return false;
793 793
794 if (bitmap) { 794 if (bitmap) {
795 // Using accelerated 2d canvas with software renderer, which 795 // Using accelerated 2d canvas with software renderer, which
796 // should only happen in tests that use fake graphics contexts 796 // should only happen in tests that use fake graphics contexts
797 // or in Android WebView in software mode. In this case, we do 797 // or in Android WebView in software mode. In this case, we do
(...skipping 12 matching lines...) Expand all
810 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) 810 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter)
811 return false; 811 return false;
812 m_lastImageId = image->uniqueID(); 812 m_lastImageId = image->uniqueID();
813 m_lastFilter = filter; 813 m_lastFilter = filter;
814 814
815 return prepareMailboxFromImage(image.release(), outMailbox); 815 return prepareMailboxFromImage(image.release(), outMailbox);
816 } 816 }
817 817
818 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailb ox, bool lostResource) 818 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailb ox, bool lostResource)
819 { 819 {
820 ASSERT(isAccelerated() || isHibernating()); 820 DCHECK(isAccelerated() || isHibernating());
821 bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->con textGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR); 821 bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->con textGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR);
822 ASSERT(m_mailboxes.last().m_parentLayerBridge.get() == this); 822 DCHECK(m_mailboxes.last().m_parentLayerBridge.get() == this);
823 823
824 // Mailboxes are typically released in FIFO order, so we iterate 824 // Mailboxes are typically released in FIFO order, so we iterate
825 // from the end of m_mailboxes. 825 // from the end of m_mailboxes.
826 auto releasedMailboxInfo = m_mailboxes.end(); 826 auto releasedMailboxInfo = m_mailboxes.end();
827 auto firstMailbox = m_mailboxes.begin(); 827 auto firstMailbox = m_mailboxes.begin();
828 828
829 while (true) { 829 while (true) {
830 --releasedMailboxInfo; 830 --releasedMailboxInfo;
831 if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) { 831 if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) {
832 break; 832 break;
833 } 833 }
834 ASSERT(releasedMailboxInfo != firstMailbox); 834 DCHECK(releasedMailboxInfo != firstMailbox);
835 } 835 }
836 836
837 if (!contextLost) { 837 if (!contextLost) {
838 // Invalidate texture state in case the compositor altered it since the copy-on-write. 838 // Invalidate texture state in case the compositor altered it since the copy-on-write.
839 if (releasedMailboxInfo->m_image) { 839 if (releasedMailboxInfo->m_image) {
840 #if USE_IOSURFACE_FOR_2D_CANVAS 840 #if USE_IOSURFACE_FOR_2D_CANVAS
841 ASSERT(releasedMailboxInfo->m_imageInfo.empty()); 841 DCHECK(releasedMailboxInfo->m_imageInfo.empty());
842 #endif // USE_IOSURFACE_FOR_2D_CANVAS 842 #endif // USE_IOSURFACE_FOR_2D_CANVAS
843 if (mailbox.validSyncToken) { 843 if (mailbox.validSyncToken) {
844 contextGL()->WaitSyncTokenCHROMIUM(mailbox.syncToken); 844 contextGL()->WaitSyncTokenCHROMIUM(mailbox.syncToken);
845 } 845 }
846 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); 846 GrTexture* texture = releasedMailboxInfo->m_image->getTexture();
847 if (texture) { 847 if (texture) {
848 if (lostResource) { 848 if (lostResource) {
849 texture->abandon(); 849 texture->abandon();
850 } else { 850 } else {
851 texture->textureParamsModified(); 851 texture->textureParamsModified();
(...skipping 18 matching lines...) Expand all
870 // The destruction of 'releasedMailboxInfo' will: 870 // The destruction of 'releasedMailboxInfo' will:
871 // 1) Release the self reference held by the mailboxInfo, which may trigger 871 // 1) Release the self reference held by the mailboxInfo, which may trigger
872 // the self-destruction of this Canvas2DLayerBridge 872 // the self-destruction of this Canvas2DLayerBridge
873 // 2) Release the SkImage, which will return the texture to skia's scratch 873 // 2) Release the SkImage, which will return the texture to skia's scratch
874 // texture pool. 874 // texture pool.
875 m_mailboxes.remove(releasedMailboxInfo); 875 m_mailboxes.remove(releasedMailboxInfo);
876 } 876 }
877 877
878 WebLayer* Canvas2DLayerBridge::layer() const 878 WebLayer* Canvas2DLayerBridge::layer() const
879 { 879 {
880 ASSERT(!m_destructionInProgress); 880 DCHECK(!m_destructionInProgress);
881 ASSERT(m_layer); 881 DCHECK(m_layer);
882 return m_layer->layer(); 882 return m_layer->layer();
883 } 883 }
884 884
885 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) 885 void Canvas2DLayerBridge::didDraw(const FloatRect& rect)
886 { 886 {
887 if (m_isDeferralEnabled) { 887 if (m_isDeferralEnabled) {
888 m_haveRecordedDrawCommands = true; 888 m_haveRecordedDrawCommands = true;
889 IntRect pixelBounds = enclosingIntRect(rect); 889 IntRect pixelBounds = enclosingIntRect(rect);
890 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height(); 890 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height();
891 if (m_recordingPixelCount >= (m_size.width() * m_size.height() * Expensi veCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) { 891 if (m_recordingPixelCount >= (m_size.width() * m_size.height() * Expensi veCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) {
892 disableDeferral(DisableDeferralReasonExpensiveOverdrawHeuristic); 892 disableDeferral(DisableDeferralReasonExpensiveOverdrawHeuristic);
893 } 893 }
894 } 894 }
895 if (!m_isRegisteredTaskObserver) { 895 if (!m_isRegisteredTaskObserver) {
896 Platform::current()->currentThread()->addTaskObserver(this); 896 Platform::current()->currentThread()->addTaskObserver(this);
897 m_isRegisteredTaskObserver = true; 897 m_isRegisteredTaskObserver = true;
898 } 898 }
899 } 899 }
900 900
901 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() 901 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded()
902 { 902 {
903 getOrCreateSurface(PreferAcceleration); 903 getOrCreateSurface(PreferAcceleration);
904 } 904 }
905 905
906 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect) 906 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect)
907 { 907 {
908 ASSERT(!m_destructionInProgress); 908 DCHECK(!m_destructionInProgress);
909 if (m_layer) 909 if (m_layer)
910 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect)); 910 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect));
911 if (m_rateLimiter) 911 if (m_rateLimiter)
912 m_rateLimiter->reset(); 912 m_rateLimiter->reset();
913 m_renderingTaskCompletedForCurrentFrame = false; 913 m_renderingTaskCompletedForCurrentFrame = false;
914 } 914 }
915 915
916 void Canvas2DLayerBridge::didProcessTask() 916 void Canvas2DLayerBridge::didProcessTask()
917 { 917 {
918 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask"); 918 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask");
919 ASSERT(m_isRegisteredTaskObserver); 919 DCHECK(m_isRegisteredTaskObserver);
920 // If m_renderTaskProcessedForCurrentFrame is already set to true, 920 // If m_renderTaskProcessedForCurrentFrame is already set to true,
921 // it means that rendering tasks are not synchronized with the compositor 921 // it means that rendering tasks are not synchronized with the compositor
922 // (i.e. not using requestAnimationFrame), so we are at risk of posting 922 // (i.e. not using requestAnimationFrame), so we are at risk of posting
923 // a multi-frame backlog to the GPU 923 // a multi-frame backlog to the GPU
924 if (m_renderingTaskCompletedForCurrentFrame) { 924 if (m_renderingTaskCompletedForCurrentFrame) {
925 if (isAccelerated()) { 925 if (isAccelerated()) {
926 flushGpu(); 926 flushGpu();
927 if (!m_rateLimiter) { 927 if (!m_rateLimiter) {
928 m_rateLimiter = SharedContextRateLimiter::create(MaxCanvasAnimat ionBacklog); 928 m_rateLimiter = SharedContextRateLimiter::create(MaxCanvasAnimat ionBacklog);
929 } 929 }
930 } else { 930 } else {
931 flush(); 931 flush();
932 } 932 }
933 } 933 }
934 934
935 if (m_rateLimiter) { 935 if (m_rateLimiter) {
936 m_rateLimiter->tick(); 936 m_rateLimiter->tick();
937 } 937 }
938 938
939 m_renderingTaskCompletedForCurrentFrame = true; 939 m_renderingTaskCompletedForCurrentFrame = true;
940 unregisterTaskObserver(); 940 unregisterTaskObserver();
941 } 941 }
942 942
943 void Canvas2DLayerBridge::willProcessTask() 943 void Canvas2DLayerBridge::willProcessTask()
944 { 944 {
945 ASSERT_NOT_REACHED(); 945 NOTREACHED();
946 } 946 }
947 947
948 PassRefPtr<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint, SnapshotReason) 948 PassRefPtr<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint, SnapshotReason)
949 { 949 {
950 if (isHibernating()) 950 if (isHibernating())
951 return m_hibernationImage; 951 return m_hibernationImage;
952 if (!checkSurfaceValid()) 952 if (!checkSurfaceValid())
953 return nullptr; 953 return nullptr;
954 if (!getOrCreateSurface(hint)) 954 if (!getOrCreateSurface(hint))
955 return nullptr; 955 return nullptr;
(...skipping 10 matching lines...) Expand all
966 { 966 {
967 skipQueuedDrawCommands(); 967 skipQueuedDrawCommands();
968 } 968 }
969 969
970 #if USE_IOSURFACE_FOR_2D_CANVAS 970 #if USE_IOSURFACE_FOR_2D_CANVAS
971 Canvas2DLayerBridge::ImageInfo::ImageInfo(GLuint imageId, GLuint textureId, GLin t gpuMemoryBufferId) 971 Canvas2DLayerBridge::ImageInfo::ImageInfo(GLuint imageId, GLuint textureId, GLin t gpuMemoryBufferId)
972 : m_imageId(imageId) 972 : m_imageId(imageId)
973 , m_textureId(textureId) 973 , m_textureId(textureId)
974 , m_gpuMemoryBufferId(gpuMemoryBufferId) 974 , m_gpuMemoryBufferId(gpuMemoryBufferId)
975 { 975 {
976 ASSERT(imageId); 976 DCHECK(imageId);
977 ASSERT(textureId); 977 DCHECK(textureId);
978 DCHECK_NE(-1, gpuMemoryBufferId); 978 DCHECK_NE(-1, gpuMemoryBufferId);
979 } 979 }
980 980
981 bool Canvas2DLayerBridge::ImageInfo::empty() 981 bool Canvas2DLayerBridge::ImageInfo::empty()
982 { 982 {
983 return m_imageId == 0; 983 return m_imageId == 0;
984 } 984 }
985 #endif // USE_IOSURFACE_FOR_2D_CANVAS 985 #endif // USE_IOSURFACE_FOR_2D_CANVAS
986 986
987 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) 987 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other)
988 { 988 {
989 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); 989 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox));
990 m_image = other.m_image; 990 m_image = other.m_image;
991 m_parentLayerBridge = other.m_parentLayerBridge; 991 m_parentLayerBridge = other.m_parentLayerBridge;
992 #if USE_IOSURFACE_FOR_2D_CANVAS 992 #if USE_IOSURFACE_FOR_2D_CANVAS
993 m_imageInfo = other.m_imageInfo; 993 m_imageInfo = other.m_imageInfo;
994 #endif // USE_IOSURFACE_FOR_2D_CANVAS 994 #endif // USE_IOSURFACE_FOR_2D_CANVAS
995 } 995 }
996 996
997 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) 997 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event)
998 { 998 {
999 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount)); 999 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib ernationEvents", HibernationEventCount));
1000 hibernationHistogram.count(event); 1000 hibernationHistogram.count(event);
1001 } 1001 }
1002 1002
1003 } // namespace blink 1003 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698