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 |