| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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, ©Paint); // G
PU readback | 444 m_surface->draw(tempHibernationSurface->getCanvas(), 0, 0, ©Paint); // 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |