| 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 else | 164 else |
| 165 accelerate = hint == PreferAcceleration || hint == PreferAccelerationAft
erVisibilityChange; | 165 accelerate = hint == PreferAcceleration || hint == PreferAccelerationAft
erVisibilityChange; |
| 166 | 166 |
| 167 if (accelerate && (!m_contextProvider || m_contextProvider->contextGL()->Get
GraphicsResetStatusKHR() != GL_NO_ERROR)) | 167 if (accelerate && (!m_contextProvider || m_contextProvider->contextGL()->Get
GraphicsResetStatusKHR() != GL_NO_ERROR)) |
| 168 accelerate = false; | 168 accelerate = false; |
| 169 return accelerate; | 169 return accelerate; |
| 170 } | 170 } |
| 171 | 171 |
| 172 bool Canvas2DLayerBridge::isAccelerated() const | 172 bool Canvas2DLayerBridge::isAccelerated() const |
| 173 { | 173 { |
| 174 if (m_accelerationMode == DisableAcceleration) |
| 175 return false; |
| 174 if (isHibernating()) | 176 if (isHibernating()) |
| 175 return false; | 177 return false; |
| 176 if (m_softwareRenderingWhileHidden) | 178 if (m_softwareRenderingWhileHidden) |
| 177 return false; | 179 return false; |
| 178 if (m_layer) // We don't check m_surface, so this returns true if context wa
s lost (m_surface is null) with restoration pending. | 180 if (m_layer) // We don't check m_surface, so this returns true if context wa
s lost (m_surface is null) with restoration pending. |
| 179 return true; | 181 return true; |
| 180 if (m_surface) // && !m_layer is implied | 182 if (m_surface) // && !m_layer is implied |
| 181 return false; | 183 return false; |
| 182 | 184 |
| 183 // Whether or not to accelerate is not yet resolved, determine whether immed
iate presentation | 185 // Whether or not to accelerate is not yet resolved, determine whether immed
iate presentation |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 { | 459 { |
| 458 if (!m_surfaceCreationFailedAtLeastOnce) { | 460 if (!m_surfaceCreationFailedAtLeastOnce) { |
| 459 // Only count the failure once per instance so that the histogram may | 461 // Only count the failure once per instance so that the histogram may |
| 460 // reflect the proportion of Canvas2DLayerBridge instances with surface | 462 // reflect the proportion of Canvas2DLayerBridge instances with surface |
| 461 // allocation failures. | 463 // allocation failures. |
| 462 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa
nvasSurfaceCreationFailed); | 464 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCa
nvasSurfaceCreationFailed); |
| 463 m_surfaceCreationFailedAtLeastOnce = true; | 465 m_surfaceCreationFailedAtLeastOnce = true; |
| 464 } | 466 } |
| 465 } | 467 } |
| 466 | 468 |
| 469 void Canvas2DLayerBridge::disableAcceleration() |
| 470 { |
| 471 DCHECK(isAccelerated()); |
| 472 bool surfaceIsAccelerated; |
| 473 RefPtr<SkSurface> newSurface = createSkSurface(nullptr, m_size, m_msaaSample
Count, m_opacityMode, &surfaceIsAccelerated); |
| 474 if (newSurface) { |
| 475 DCHECK(!surfaceIsAccelerated); |
| 476 flush(); |
| 477 SkPaint copyPaint; |
| 478 copyPaint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 479 m_surface->draw(newSurface->getCanvas(), 0, 0, ©Paint); // GPU readb
ack here |
| 480 m_accelerationMode = DisableAcceleration; // Acceleration gets permanent
ly disabled |
| 481 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 482 m_layer->clearTexture(); |
| 483 m_layer->layer()->removeFromParent(); |
| 484 m_surface = newSurface; |
| 485 if (m_imageBuffer) |
| 486 m_imageBuffer->didDisableAcceleration(); |
| 487 } |
| 488 } |
| 489 |
| 467 SkSurface* Canvas2DLayerBridge::getOrCreateSurface(AccelerationHint hint) | 490 SkSurface* Canvas2DLayerBridge::getOrCreateSurface(AccelerationHint hint) |
| 468 { | 491 { |
| 469 if (m_surface) | 492 if (m_surface) { |
| 493 // Note: in layout tests, canvas2dFixedRenderingMode is set to true to i
nhibit |
| 494 // mode switching so that we continue to get test coverage for GPU accel
eration |
| 495 // despite the use of getImageData in tests |
| 496 if (hint == ForceNoAcceleration && isAccelerated() && !RuntimeEnabledFea
tures::canvas2dFixedRenderingModeEnabled()) |
| 497 disableAcceleration(); |
| 470 return m_surface.get(); | 498 return m_surface.get(); |
| 499 } |
| 471 | 500 |
| 472 if (m_layer && !isHibernating() && hint == PreferAcceleration) { | 501 if (m_layer && !isHibernating() && hint == PreferAcceleration && m_accelerat
ionMode != DisableAcceleration) { |
| 473 return nullptr; // re-creation will happen through restore() | 502 return nullptr; // re-creation will happen through restore() |
| 474 } | 503 } |
| 475 | 504 |
| 476 bool wantAcceleration = shouldAccelerate(hint); | 505 bool wantAcceleration = shouldAccelerate(hint); |
| 477 bool surfaceIsAccelerated; | |
| 478 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati
on) { | 506 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati
on) { |
| 479 wantAcceleration = false; | 507 wantAcceleration = false; |
| 480 m_softwareRenderingWhileHidden = true; | 508 m_softwareRenderingWhileHidden = true; |
| 481 } | 509 } |
| 482 | 510 |
| 511 bool surfaceIsAccelerated; |
| 483 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext(
) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated); | 512 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext(
) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated); |
| 484 | 513 |
| 485 if (!m_surface) | 514 if (!m_surface) |
| 486 reportSurfaceCreationFailure(); | 515 reportSurfaceCreationFailure(); |
| 487 | 516 |
| 488 if (m_surface && surfaceIsAccelerated && !m_layer) { | 517 if (m_surface && surfaceIsAccelerated && !m_layer) { |
| 489 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt
ernalTextureLayer(this)); | 518 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt
ernalTextureLayer(this)); |
| 490 m_layer->setOpaque(m_opacityMode == Opaque); | 519 m_layer->setOpaque(m_opacityMode == Opaque); |
| 491 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); | 520 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); |
| 492 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 521 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 m_logger->reportHibernationEvent(HibernationEndedWithTeardown); | 602 m_logger->reportHibernationEvent(HibernationEndedWithTeardown); |
| 574 m_hibernationImage.clear(); | 603 m_hibernationImage.clear(); |
| 575 m_recorder.reset(); | 604 m_recorder.reset(); |
| 576 m_imageBuffer = nullptr; | 605 m_imageBuffer = nullptr; |
| 577 m_destructionInProgress = true; | 606 m_destructionInProgress = true; |
| 578 setIsHidden(true); | 607 setIsHidden(true); |
| 579 m_surface.clear(); | 608 m_surface.clear(); |
| 580 | 609 |
| 581 unregisterTaskObserver(); | 610 unregisterTaskObserver(); |
| 582 | 611 |
| 583 if (m_layer) { | 612 if (m_layer && m_accelerationMode != DisableAcceleration) { |
| 584 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 613 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 585 m_layer->clearTexture(); | 614 m_layer->clearTexture(); |
| 586 // Orphaning the layer is required to trigger the recration of a new lay
er | 615 // Orphaning the layer is required to trigger the recration of a new lay
er |
| 587 // in the case where destruction is caused by a canvas resize. Test: | 616 // in the case where destruction is caused by a canvas resize. Test: |
| 588 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html | 617 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html |
| 589 m_layer->layer()->removeFromParent(); | 618 m_layer->layer()->removeFromParent(); |
| 590 } | 619 } |
| 591 | 620 |
| 592 DCHECK(!m_bytesAllocated); | 621 DCHECK(!m_bytesAllocated); |
| 593 } | 622 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 gpu::gles2::GLES2Interface* gl = contextGL(); | 731 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 703 if (isAccelerated() && gl) | 732 if (isAccelerated() && gl) |
| 704 gl->Flush(); | 733 gl->Flush(); |
| 705 } | 734 } |
| 706 | 735 |
| 707 | 736 |
| 708 gpu::gles2::GLES2Interface* Canvas2DLayerBridge::contextGL() | 737 gpu::gles2::GLES2Interface* Canvas2DLayerBridge::contextGL() |
| 709 { | 738 { |
| 710 // Check on m_layer is necessary because contextGL() may be called during | 739 // Check on m_layer is necessary because contextGL() may be called during |
| 711 // the destruction of m_layer | 740 // the destruction of m_layer |
| 712 if (m_layer && !m_destructionInProgress) { | 741 if (m_layer && m_accelerationMode != DisableAcceleration && !m_destructionIn
Progress) { |
| 713 // Call checkSurfaceValid to ensure rate limiter is disabled if context
is lost. | 742 // Call checkSurfaceValid to ensure rate limiter is disabled if context
is lost. |
| 714 if (!checkSurfaceValid()) | 743 if (!checkSurfaceValid()) |
| 715 return nullptr; | 744 return nullptr; |
| 716 } | 745 } |
| 717 return m_contextProvider ? m_contextProvider->contextGL() : nullptr; | 746 return m_contextProvider ? m_contextProvider->contextGL() : nullptr; |
| 718 } | 747 } |
| 719 | 748 |
| 720 bool Canvas2DLayerBridge::checkSurfaceValid() | 749 bool Canvas2DLayerBridge::checkSurfaceValid() |
| 721 { | 750 { |
| 722 DCHECK(!m_destructionInProgress); | 751 DCHECK(!m_destructionInProgress); |
| 723 if (m_destructionInProgress) | 752 if (m_destructionInProgress) |
| 724 return false; | 753 return false; |
| 725 if (isHibernating()) | 754 if (isHibernating()) |
| 726 return true; | 755 return true; |
| 727 if (!m_layer) | 756 if (!m_layer || m_accelerationMode == DisableAcceleration) |
| 728 return true; | 757 return true; |
| 729 if (!m_surface) | 758 if (!m_surface) |
| 730 return false; | 759 return false; |
| 731 if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERR
OR) { | 760 if (m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERR
OR) { |
| 732 m_surface.clear(); | 761 m_surface.clear(); |
| 733 for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes.
end(); ++mailboxInfo) { | 762 for (auto mailboxInfo = m_mailboxes.begin(); mailboxInfo != m_mailboxes.
end(); ++mailboxInfo) { |
| 734 if (mailboxInfo->m_image) | 763 if (mailboxInfo->m_image) |
| 735 mailboxInfo->m_image.clear(); | 764 mailboxInfo->m_image.clear(); |
| 736 } | 765 } |
| 737 if (m_imageBuffer) | 766 if (m_imageBuffer) |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 // to postpone destruction until the end of this function. | 897 // to postpone destruction until the end of this function. |
| 869 selfRef = this; | 898 selfRef = this; |
| 870 } | 899 } |
| 871 | 900 |
| 872 // The destruction of 'releasedMailboxInfo' will: | 901 // The destruction of 'releasedMailboxInfo' will: |
| 873 // 1) Release the self reference held by the mailboxInfo, which may trigger | 902 // 1) Release the self reference held by the mailboxInfo, which may trigger |
| 874 // the self-destruction of this Canvas2DLayerBridge | 903 // the self-destruction of this Canvas2DLayerBridge |
| 875 // 2) Release the SkImage, which will return the texture to skia's scratch | 904 // 2) Release the SkImage, which will return the texture to skia's scratch |
| 876 // texture pool. | 905 // texture pool. |
| 877 m_mailboxes.remove(releasedMailboxInfo); | 906 m_mailboxes.remove(releasedMailboxInfo); |
| 907 |
| 908 if (m_mailboxes.isEmpty() && m_accelerationMode == DisableAcceleration) |
| 909 m_layer.reset(); |
| 878 } | 910 } |
| 879 | 911 |
| 880 WebLayer* Canvas2DLayerBridge::layer() const | 912 WebLayer* Canvas2DLayerBridge::layer() const |
| 881 { | 913 { |
| 882 DCHECK(!m_destructionInProgress); | 914 DCHECK(!m_destructionInProgress); |
| 883 DCHECK(m_layer); | 915 DCHECK(m_layer); |
| 884 return m_layer->layer(); | 916 return m_layer->layer(); |
| 885 } | 917 } |
| 886 | 918 |
| 887 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) | 919 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 901 } | 933 } |
| 902 | 934 |
| 903 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() | 935 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() |
| 904 { | 936 { |
| 905 getOrCreateSurface(PreferAcceleration); | 937 getOrCreateSurface(PreferAcceleration); |
| 906 } | 938 } |
| 907 | 939 |
| 908 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect) | 940 void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect) |
| 909 { | 941 { |
| 910 DCHECK(!m_destructionInProgress); | 942 DCHECK(!m_destructionInProgress); |
| 911 if (m_layer) | 943 if (m_layer && m_accelerationMode != DisableAcceleration) |
| 912 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect)); | 944 m_layer->layer()->invalidateRect(enclosingIntRect(dirtyRect)); |
| 913 if (m_rateLimiter) | 945 if (m_rateLimiter) |
| 914 m_rateLimiter->reset(); | 946 m_rateLimiter->reset(); |
| 915 m_renderingTaskCompletedForCurrentFrame = false; | 947 m_renderingTaskCompletedForCurrentFrame = false; |
| 916 } | 948 } |
| 917 | 949 |
| 918 void Canvas2DLayerBridge::didProcessTask() | 950 void Canvas2DLayerBridge::didProcessTask() |
| 919 { | 951 { |
| 920 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask"); | 952 TRACE_EVENT0("cc", "Canvas2DLayerBridge::didProcessTask"); |
| 921 DCHECK(m_isRegisteredTaskObserver); | 953 DCHECK(m_isRegisteredTaskObserver); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 1028 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 997 } | 1029 } |
| 998 | 1030 |
| 999 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) | 1031 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) |
| 1000 { | 1032 { |
| 1001 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib
ernationEvents", HibernationEventCount)); | 1033 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib
ernationEvents", HibernationEventCount)); |
| 1002 hibernationHistogram.count(event); | 1034 hibernationHistogram.count(event); |
| 1003 } | 1035 } |
| 1004 | 1036 |
| 1005 } // namespace blink | 1037 } // namespace blink |
| OLD | NEW |