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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 if (bitmap) { | 595 if (bitmap) { |
595 // Using accelerated 2d canvas with software renderer, which | 596 // Using accelerated 2d canvas with software renderer, which |
596 // should only happen in tests that use fake graphics contexts | 597 // should only happen in tests that use fake graphics contexts |
597 // or in Android WebView in software mode. In this case, we do | 598 // or in Android WebView in software mode. In this case, we do |
598 // not care about producing any results for this canvas. | 599 // not care about producing any results for this canvas. |
599 skipQueuedDrawCommands(); | 600 skipQueuedDrawCommands(); |
600 m_lastImageId = 0; | 601 m_lastImageId = 0; |
601 return false; | 602 return false; |
602 } | 603 } |
603 | 604 |
604 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration); | 605 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration, SnapshotReasonU
nknown); |
605 if (!image || !image->getTexture()) | 606 if (!image || !image->getTexture()) |
606 return false; | 607 return false; |
607 | 608 |
608 WebGraphicsContext3D* webContext = context(); | 609 WebGraphicsContext3D* webContext = context(); |
609 | 610 |
610 // Early exit if canvas was not drawn to since last prepareMailbox | 611 // Early exit if canvas was not drawn to since last prepareMailbox |
611 GLenum filter = m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_L
INEAR; | 612 GLenum filter = m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_L
INEAR; |
612 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) | 613 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) |
613 return false; | 614 return false; |
614 m_lastImageId = image->uniqueID(); | 615 m_lastImageId = image->uniqueID(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 return m_layer->layer(); | 732 return m_layer->layer(); |
732 } | 733 } |
733 | 734 |
734 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) | 735 void Canvas2DLayerBridge::didDraw(const FloatRect& rect) |
735 { | 736 { |
736 if (m_isDeferralEnabled) { | 737 if (m_isDeferralEnabled) { |
737 m_haveRecordedDrawCommands = true; | 738 m_haveRecordedDrawCommands = true; |
738 IntRect pixelBounds = enclosingIntRect(rect); | 739 IntRect pixelBounds = enclosingIntRect(rect); |
739 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height(); | 740 m_recordingPixelCount += pixelBounds.width() * pixelBounds.height(); |
740 if (m_recordingPixelCount >= (m_size.width() * m_size.height() * Expensi
veCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) { | 741 if (m_recordingPixelCount >= (m_size.width() * m_size.height() * Expensi
veCanvasHeuristicParameters::ExpensiveOverdrawThreshold)) { |
741 disableDeferral(); | 742 disableDeferral(DisableDeferralReasonExpensiveOverdrawHeuristic); |
742 } | 743 } |
743 } | 744 } |
744 if (!m_isRegisteredTaskObserver) { | 745 if (!m_isRegisteredTaskObserver) { |
745 Platform::current()->currentThread()->addTaskObserver(this); | 746 Platform::current()->currentThread()->addTaskObserver(this); |
746 m_isRegisteredTaskObserver = true; | 747 m_isRegisteredTaskObserver = true; |
747 } | 748 } |
748 } | 749 } |
749 | 750 |
750 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() | 751 void Canvas2DLayerBridge::prepareSurfaceForPaintingIfNeeded() |
751 { | 752 { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 | 788 |
788 m_renderingTaskCompletedForCurrentFrame = true; | 789 m_renderingTaskCompletedForCurrentFrame = true; |
789 unregisterTaskObserver(); | 790 unregisterTaskObserver(); |
790 } | 791 } |
791 | 792 |
792 void Canvas2DLayerBridge::willProcessTask() | 793 void Canvas2DLayerBridge::willProcessTask() |
793 { | 794 { |
794 ASSERT_NOT_REACHED(); | 795 ASSERT_NOT_REACHED(); |
795 } | 796 } |
796 | 797 |
797 PassRefPtr<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint) | 798 PassRefPtr<SkImage> Canvas2DLayerBridge::newImageSnapshot(AccelerationHint hint,
SnapshotReason) |
798 { | 799 { |
799 if (!checkSurfaceValid()) | 800 if (!checkSurfaceValid()) |
800 return nullptr; | 801 return nullptr; |
801 if (!getOrCreateSurface(hint)) | 802 if (!getOrCreateSurface(hint)) |
802 return nullptr; | 803 return nullptr; |
803 flush(); | 804 flush(); |
804 // A readback operation may alter the texture parameters, which may affect | 805 // A readback operation may alter the texture parameters, which may affect |
805 // the compositor's behavior. Therefore, we must trigger copy-on-write | 806 // the compositor's behavior. Therefore, we must trigger copy-on-write |
806 // even though we are not technically writing to the texture, only to its | 807 // even though we are not technically writing to the texture, only to its |
807 // parameters. | 808 // parameters. |
(...skipping 12 matching lines...) Expand all Loading... |
820 m_image = other.m_image; | 821 m_image = other.m_image; |
821 m_parentLayerBridge = other.m_parentLayerBridge; | 822 m_parentLayerBridge = other.m_parentLayerBridge; |
822 } | 823 } |
823 | 824 |
824 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) | 825 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) |
825 { | 826 { |
826 blink::Platform::current()->histogramEnumeration("Canvas.HibernationEvents",
event, HibernationEventCount); | 827 blink::Platform::current()->histogramEnumeration("Canvas.HibernationEvents",
event, HibernationEventCount); |
827 } | 828 } |
828 | 829 |
829 } // namespace blink | 830 } // namespace blink |
OLD | NEW |