| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 324 |
| 325 SkCanvas* Canvas2DLayerBridge::canvas() | 325 SkCanvas* Canvas2DLayerBridge::canvas() |
| 326 { | 326 { |
| 327 if (!m_isDeferralEnabled) { | 327 if (!m_isDeferralEnabled) { |
| 328 SkSurface* s = getOrCreateSurface(); | 328 SkSurface* s = getOrCreateSurface(); |
| 329 return s ? s->getCanvas() : nullptr; | 329 return s ? s->getCanvas() : nullptr; |
| 330 } | 330 } |
| 331 return m_recorder->getRecordingCanvas(); | 331 return m_recorder->getRecordingCanvas(); |
| 332 } | 332 } |
| 333 | 333 |
| 334 void Canvas2DLayerBridge::disableDeferral() | 334 void Canvas2DLayerBridge::disableDeferral(DisableDeferralReason reason) |
| 335 { | 335 { |
| 336 // Disabling deferral is permanent: once triggered by disableDeferral() | 336 // Disabling deferral is permanent: once triggered by disableDeferral() |
| 337 // we stay in immediate mode indefinitely. This is a performance heuristic | 337 // we stay in immediate mode indefinitely. This is a performance heuristic |
| 338 // that significantly helps a number of use cases. The rationale is that if | 338 // that significantly helps a number of use cases. The rationale is that if |
| 339 // immediate rendering was needed once, it is likely to be needed at least | 339 // immediate rendering was needed once, it is likely to be needed at least |
| 340 // once per frame, which eliminates the possibility for inter-frame | 340 // once per frame, which eliminates the possibility for inter-frame |
| 341 // overdraw optimization. Furthermore, in cases where immediate mode is | 341 // overdraw optimization. Furthermore, in cases where immediate mode is |
| 342 // required multiple times per frame, the repeated flushing of deferred | 342 // required multiple times per frame, the repeated flushing of deferred |
| 343 // commands would cause significant overhead, so it is better to just stop | 343 // commands would cause significant overhead, so it is better to just stop |
| 344 // trying to defer altogether. | 344 // trying to defer altogether. |
| 345 if (!m_isDeferralEnabled) | 345 if (!m_isDeferralEnabled) |
| 346 return; | 346 return; |
| 347 | 347 |
| 348 Platform::current()->histogramEnumeration("Canvas.GPUAccelerated2DCanvasDisa
bleDeferralReason", reason, DisableDeferralReasonCount); |
| 348 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvas
DeferralDisabled); | 349 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvas
DeferralDisabled); |
| 349 flushRecordingOnly(); | 350 flushRecordingOnly(); |
| 350 // Because we will be discarding the recorder, if the flush failed | 351 // Because we will be discarding the recorder, if the flush failed |
| 351 // content will be lost -> force m_haveRecordedDrawCommands to false | 352 // content will be lost -> force m_haveRecordedDrawCommands to false |
| 352 m_haveRecordedDrawCommands = false; | 353 m_haveRecordedDrawCommands = false; |
| 353 | 354 |
| 354 m_isDeferralEnabled = false; | 355 m_isDeferralEnabled = false; |
| 355 m_recorder.clear(); | 356 m_recorder.clear(); |
| 356 // install the current matrix/clip stack onto the immediate canvas | 357 // install the current matrix/clip stack onto the immediate canvas |
| 357 SkSurface* surface = getOrCreateSurface(); | 358 SkSurface* surface = getOrCreateSurface(); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 if (bitmap) { | 593 if (bitmap) { |
| 593 // Using accelerated 2d canvas with software renderer, which | 594 // Using accelerated 2d canvas with software renderer, which |
| 594 // should only happen in tests that use fake graphics contexts | 595 // should only happen in tests that use fake graphics contexts |
| 595 // or in Android WebView in software mode. In this case, we do | 596 // or in Android WebView in software mode. In this case, we do |
| 596 // not care about producing any results for this canvas. | 597 // not care about producing any results for this canvas. |
| 597 skipQueuedDrawCommands(); | 598 skipQueuedDrawCommands(); |
| 598 m_lastImageId = 0; | 599 m_lastImageId = 0; |
| 599 return false; | 600 return false; |
| 600 } | 601 } |
| 601 | 602 |
| 602 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration); | 603 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration, SnapshotReasonU
nknown); |
| 603 if (!image) | 604 if (!image) |
| 604 return false; | 605 return false; |
| 605 | 606 |
| 606 WebGraphicsContext3D* webContext = context(); | 607 WebGraphicsContext3D* webContext = context(); |
| 607 | 608 |
| 608 // Early exit if canvas was not drawn to since last prepareMailbox | 609 // Early exit if canvas was not drawn to since last prepareMailbox |
| 609 GLenum filter = m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_L
INEAR; | 610 GLenum filter = m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_L
INEAR; |
| 610 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) | 611 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) |
| 611 return false; | 612 return false; |
| 612 m_lastImageId = image->uniqueID(); | 613 m_lastImageId = image->uniqueID(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 return m_layer->layer(); | 731 return m_layer->layer(); |
| 731 } | 732 } |
| 732 | 733 |
| 733 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) | 734 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) |
| 734 { | 735 { |
| 735 if (m_isDeferralEnabled) { | 736 if (m_isDeferralEnabled) { |
| 736 m_haveRecordedDrawCommands = true; | 737 m_haveRecordedDrawCommands = true; |
| 737 IntRect pixelBounds = enclosingIntRect(rect); | 738 IntRect pixelBounds = enclosingIntRect(rect); |
| 738 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height(); | 739 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height(); |
| 739 if (m_recordingPixelCount >= (m_size.width() * m_size.height() * Expensi
veCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) { | 740 if (m_recordingPixelCount >= (m_size.width() * m_size.height() * Expensi
veCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) { |
| 740 disableDeferral(); | 741 disableDeferral(DisableDeferralReasonExpensiveOverdrawHeuristic); |
| 741 } | 742 } |
| 742 } | 743 } |
| 743 if (!m_isRegisteredTaskObserver) { | 744 if (!m_isRegisteredTaskObserver) { |
| 744 Platform::current()->currentThread()->addTaskObserver(this); | 745 Platform::current()->currentThread()->addTaskObserver(this); |
| 745 m_isRegisteredTaskObserver = true; | 746 m_isRegisteredTaskObserver = true; |
| 746 } | 747 } |
| 747 } | 748 } |
| 748 | 749 |
| 749 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() | 750 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() |
| 750 { | 751 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 | 787 |
| 787 m_renderingTaskCompletedForCurrentFrame = true; | 788 m_renderingTaskCompletedForCurrentFrame = true; |
| 788 unregisterTaskObserver(); | 789 unregisterTaskObserver(); |
| 789 } | 790 } |
| 790 | 791 |
| 791 void Canvas2DLayerBridge::willProcessTask() | 792 void Canvas2DLayerBridge::willProcessTask() |
| 792 { | 793 { |
| 793 ASSERT_NOT_REACHED(); | 794 ASSERT_NOT_REACHED(); |
| 794 } | 795 } |
| 795 | 796 |
| 796 PassRefPtr<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint) | 797 PassRefPtr<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint,
SnapshotReason) |
| 797 { | 798 { |
| 798 if (!checkSurfaceValid()) | 799 if (!checkSurfaceValid()) |
| 799 return nullptr; | 800 return nullptr; |
| 800 if (!getOrCreateSurface(hint)) | 801 if (!getOrCreateSurface(hint)) |
| 801 return nullptr; | 802 return nullptr; |
| 802 flush(); | 803 flush(); |
| 803 // A readback operation may alter the texture parameters, which may affect | 804 // A readback operation may alter the texture parameters, which may affect |
| 804 // the compositor's behavior. Therefore, we must trigger copy-on-write | 805 // the compositor's behavior. Therefore, we must trigger copy-on-write |
| 805 // even though we are not technically writing to the texture, only to its | 806 // even though we are not technically writing to the texture, only to its |
| 806 // parameters. | 807 // parameters. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 819 m_image = other.m_image; | 820 m_image = other.m_image; |
| 820 m_parentLayerBridge = other.m_parentLayerBridge; | 821 m_parentLayerBridge = other.m_parentLayerBridge; |
| 821 } | 822 } |
| 822 | 823 |
| 823 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) | 824 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) |
| 824 { | 825 { |
| 825 blink::Platform::current()->histogramEnumeration("Canvas.HibernationEvents",
event, HibernationEventCount); | 826 blink::Platform::current()->histogramEnumeration("Canvas.HibernationEvents",
event, HibernationEventCount); |
| 826 } | 827 } |
| 827 | 828 |
| 828 } // namespace blink | 829 } // namespace blink |
| OLD | NEW |