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...) 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...) 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...) 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...) 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...) 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 |