| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 #include "third_party/skia/include/core/SkPictureRecorder.h" | 48 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 49 #include "third_party/skia/include/core/SkSurface.h" | 49 #include "third_party/skia/include/core/SkSurface.h" |
| 50 #include "third_party/skia/include/gpu/GrContext.h" | 50 #include "third_party/skia/include/gpu/GrContext.h" |
| 51 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" | 51 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" |
| 52 #include "wtf/PtrUtil.h" | 52 #include "wtf/PtrUtil.h" |
| 53 #include <memory> | 53 #include <memory> |
| 54 | 54 |
| 55 namespace { | 55 namespace { |
| 56 enum { | 56 enum { |
| 57 InvalidMailboxIndex = -1, | 57 InvalidMailboxIndex = -1, |
| 58 MaxCanvasAnimationBacklog = | 58 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than |
| 59 2, // Make sure the the GPU is never more than two animation frames behin
d. | 59 // two animation frames behind. |
| 60 }; | 60 }; |
| 61 } // namespace | 61 } // namespace |
| 62 | 62 |
| 63 namespace blink { | 63 namespace blink { |
| 64 | 64 |
| 65 #if USE_IOSURFACE_FOR_2D_CANVAS | 65 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 66 struct Canvas2DLayerBridge::ImageInfo : public RefCounted<ImageInfo> { | 66 struct Canvas2DLayerBridge::ImageInfo : public RefCounted<ImageInfo> { |
| 67 ImageInfo(std::unique_ptr<gfx::GpuMemoryBuffer>, | 67 ImageInfo(std::unique_ptr<gfx::GpuMemoryBuffer>, |
| 68 GLuint imageId, | 68 GLuint imageId, |
| 69 GLuint textureId); | 69 GLuint textureId); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 return accelerate; | 198 return accelerate; |
| 199 } | 199 } |
| 200 | 200 |
| 201 bool Canvas2DLayerBridge::isAccelerated() const { | 201 bool Canvas2DLayerBridge::isAccelerated() const { |
| 202 if (m_accelerationMode == DisableAcceleration) | 202 if (m_accelerationMode == DisableAcceleration) |
| 203 return false; | 203 return false; |
| 204 if (isHibernating()) | 204 if (isHibernating()) |
| 205 return false; | 205 return false; |
| 206 if (m_softwareRenderingWhileHidden) | 206 if (m_softwareRenderingWhileHidden) |
| 207 return false; | 207 return false; |
| 208 if (m_layer) // We don't check m_surface, so this returns true if context was
lost (m_surface is null) with restoration pending. | 208 if (m_layer) { |
| 209 // We don't check |m_surface|, so this returns true if context was lost |
| 210 // (|m_surface| is null) with restoration pending. |
| 209 return true; | 211 return true; |
| 212 } |
| 210 if (m_surface) // && !m_layer is implied | 213 if (m_surface) // && !m_layer is implied |
| 211 return false; | 214 return false; |
| 212 | 215 |
| 213 // Whether or not to accelerate is not yet resolved, determine whether immedia
te presentation | 216 // Whether or not to accelerate is not yet resolved. Determine whether |
| 214 // of the canvas would result in the canvas being accelerated. Presentation is
assumed to be | 217 // immediate presentation of the canvas would result in the canvas being |
| 215 // a 'PreferAcceleration' operation. | 218 // accelerated. Presentation is assumed to be a 'PreferAcceleration' |
| 219 // operation. |
| 216 return shouldAccelerate(PreferAcceleration); | 220 return shouldAccelerate(PreferAcceleration); |
| 217 } | 221 } |
| 218 | 222 |
| 219 GLenum Canvas2DLayerBridge::getGLFilter() { | 223 GLenum Canvas2DLayerBridge::getGLFilter() { |
| 220 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; | 224 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; |
| 221 } | 225 } |
| 222 | 226 |
| 223 #if USE_IOSURFACE_FOR_2D_CANVAS | 227 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 224 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage( | 228 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage( |
| 225 SkImage* image, | 229 SkImage* image, |
| 226 cc::TextureMailbox* outMailbox) { | 230 cc::TextureMailbox* outMailbox) { |
| 227 // Need to flush skia's internal queue because texture is about to be accessed
directly | 231 // Need to flush skia's internal queue, because the texture is about to be |
| 232 // accessed directly. |
| 228 GrContext* grContext = m_contextProvider->grContext(); | 233 GrContext* grContext = m_contextProvider->grContext(); |
| 229 grContext->flush(); | 234 grContext->flush(); |
| 230 | 235 |
| 231 RefPtr<ImageInfo> imageInfo = createIOSurfaceBackedTexture(); | 236 RefPtr<ImageInfo> imageInfo = createIOSurfaceBackedTexture(); |
| 232 if (!imageInfo) | 237 if (!imageInfo) |
| 233 return false; | 238 return false; |
| 234 | 239 |
| 235 gpu::gles2::GLES2Interface* gl = contextGL(); | 240 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 236 if (!gl) | 241 if (!gl) |
| 237 return false; | 242 return false; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 | 360 |
| 356 bool Canvas2DLayerBridge::prepareMailboxFromImage( | 361 bool Canvas2DLayerBridge::prepareMailboxFromImage( |
| 357 sk_sp<SkImage> image, | 362 sk_sp<SkImage> image, |
| 358 cc::TextureMailbox* outMailbox) { | 363 cc::TextureMailbox* outMailbox) { |
| 359 createMailboxInfo(); | 364 createMailboxInfo(); |
| 360 MailboxInfo& mailboxInfo = m_mailboxes.first(); | 365 MailboxInfo& mailboxInfo = m_mailboxes.first(); |
| 361 | 366 |
| 362 GrContext* grContext = m_contextProvider->grContext(); | 367 GrContext* grContext = m_contextProvider->grContext(); |
| 363 if (!grContext) { | 368 if (!grContext) { |
| 364 mailboxInfo.m_image = std::move(image); | 369 mailboxInfo.m_image = std::move(image); |
| 365 return true; // for testing: skip gl stuff when using a mock graphics conte
xt. | 370 // For testing, skip GL stuff when using a mock graphics context. |
| 371 return true; |
| 366 } | 372 } |
| 367 | 373 |
| 368 #if USE_IOSURFACE_FOR_2D_CANVAS | 374 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 369 if (RuntimeEnabledFeatures::canvas2dImageChromiumEnabled()) { | 375 if (RuntimeEnabledFeatures::canvas2dImageChromiumEnabled()) { |
| 370 if (prepareIOSurfaceMailboxFromImage(image.get(), outMailbox)) | 376 if (prepareIOSurfaceMailboxFromImage(image.get(), outMailbox)) |
| 371 return true; | 377 return true; |
| 372 // Note: if IOSurface backed texture creation failed we fall back to the | 378 // Note: if IOSurface backed texture creation failed we fall back to the |
| 373 // non-IOSurface path. | 379 // non-IOSurface path. |
| 374 } | 380 } |
| 375 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 381 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 376 | 382 |
| 377 mailboxInfo.m_image = std::move(image); | 383 mailboxInfo.m_image = std::move(image); |
| 378 | 384 |
| 379 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled()) | 385 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled()) |
| 380 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode); | 386 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode); |
| 381 | 387 |
| 382 // Need to flush skia's internal queue because texture is about to be accessed
directly | 388 // Need to flush skia's internal queue, because the texture is about to be |
| 389 // accessed directly. |
| 383 grContext->flush(); | 390 grContext->flush(); |
| 384 | 391 |
| 385 // Because of texture sharing with the compositor, we must invalidate | 392 // Because of texture sharing with the compositor, we must invalidate |
| 386 // the state cached in skia so that the deferred copy on write | 393 // the state cached in skia so that the deferred copy on write |
| 387 // in SkSurface_Gpu does not make any false assumptions. | 394 // in SkSurface_Gpu does not make any false assumptions. |
| 388 mailboxInfo.m_image->getTexture()->textureParamsModified(); | 395 mailboxInfo.m_image->getTexture()->textureParamsModified(); |
| 389 | 396 |
| 390 gpu::gles2::GLES2Interface* gl = contextGL(); | 397 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 391 if (!gl) | 398 if (!gl) |
| 392 return false; | 399 return false; |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 gpu::gles2::GLES2Interface* gl = contextGL(); | 783 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 777 if (isAccelerated() && gl) | 784 if (isAccelerated() && gl) |
| 778 gl->Flush(); | 785 gl->Flush(); |
| 779 } | 786 } |
| 780 | 787 |
| 781 gpu::gles2::GLES2Interface* Canvas2DLayerBridge::contextGL() { | 788 gpu::gles2::GLES2Interface* Canvas2DLayerBridge::contextGL() { |
| 782 // Check on m_layer is necessary because contextGL() may be called during | 789 // Check on m_layer is necessary because contextGL() may be called during |
| 783 // the destruction of m_layer | 790 // the destruction of m_layer |
| 784 if (m_layer && m_accelerationMode != DisableAcceleration && | 791 if (m_layer && m_accelerationMode != DisableAcceleration && |
| 785 !m_destructionInProgress) { | 792 !m_destructionInProgress) { |
| 786 // Call checkSurfaceValid to ensure rate limiter is disabled if context is l
ost. | 793 // Call checkSurfaceValid to ensure the rate limiter is disabled if the |
| 794 // context is lost. |
| 787 if (!checkSurfaceValid()) | 795 if (!checkSurfaceValid()) |
| 788 return nullptr; | 796 return nullptr; |
| 789 } | 797 } |
| 790 return m_contextProvider ? m_contextProvider->contextGL() : nullptr; | 798 return m_contextProvider ? m_contextProvider->contextGL() : nullptr; |
| 791 } | 799 } |
| 792 | 800 |
| 793 bool Canvas2DLayerBridge::checkSurfaceValid() { | 801 bool Canvas2DLayerBridge::checkSurfaceValid() { |
| 794 DCHECK(!m_destructionInProgress); | 802 DCHECK(!m_destructionInProgress); |
| 795 if (m_destructionInProgress) | 803 if (m_destructionInProgress) |
| 796 return false; | 804 return false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { | 840 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { |
| 833 GrContext* grCtx = m_contextProvider->grContext(); | 841 GrContext* grCtx = m_contextProvider->grContext(); |
| 834 bool surfaceIsAccelerated; | 842 bool surfaceIsAccelerated; |
| 835 sk_sp<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCount, | 843 sk_sp<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCount, |
| 836 m_opacityMode, m_colorSpace, | 844 m_opacityMode, m_colorSpace, |
| 837 &surfaceIsAccelerated)); | 845 &surfaceIsAccelerated)); |
| 838 | 846 |
| 839 if (!m_surface) | 847 if (!m_surface) |
| 840 reportSurfaceCreationFailure(); | 848 reportSurfaceCreationFailure(); |
| 841 | 849 |
| 842 // Current paradigm does support switching from accelerated to non-accelerat
ed, which would be tricky | 850 // The current paradigm does not support switching from accelerated to |
| 843 // due to changes to the layer tree, which can only happen at specific times
during the document lifecycle. | 851 // non-accelerated, which would be tricky due to changes to the layer tree, |
| 852 // which can only happen at specific times during the document lifecycle. |
| 844 // Therefore, we can only accept the restored surface if it is accelerated. | 853 // Therefore, we can only accept the restored surface if it is accelerated. |
| 845 if (surface && surfaceIsAccelerated) { | 854 if (surface && surfaceIsAccelerated) { |
| 846 m_surface = std::move(surface); | 855 m_surface = std::move(surface); |
| 847 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 | 856 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 |
| 848 } | 857 } |
| 849 } | 858 } |
| 850 if (m_imageBuffer) | 859 if (m_imageBuffer) |
| 851 m_imageBuffer->updateGPUMemoryUsage(); | 860 m_imageBuffer->updateGPUMemoryUsage(); |
| 852 | 861 |
| 853 return m_surface.get(); | 862 return m_surface.get(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 auto firstMailbox = m_mailboxes.begin(); | 955 auto firstMailbox = m_mailboxes.begin(); |
| 947 | 956 |
| 948 while (true) { | 957 while (true) { |
| 949 --releasedMailboxInfo; | 958 --releasedMailboxInfo; |
| 950 if (releasedMailboxInfo->m_mailbox == mailbox) | 959 if (releasedMailboxInfo->m_mailbox == mailbox) |
| 951 break; | 960 break; |
| 952 DCHECK(releasedMailboxInfo != firstMailbox); | 961 DCHECK(releasedMailboxInfo != firstMailbox); |
| 953 } | 962 } |
| 954 | 963 |
| 955 if (!contextLost) { | 964 if (!contextLost) { |
| 956 // Invalidate texture state in case the compositor altered it since the copy
-on-write. | 965 // Invalidate texture state in case the compositor altered it since the |
| 966 // copy-on-write. |
| 957 if (releasedMailboxInfo->m_image) { | 967 if (releasedMailboxInfo->m_image) { |
| 958 #if USE_IOSURFACE_FOR_2D_CANVAS | 968 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 959 DCHECK(!releasedMailboxInfo->m_imageInfo); | 969 DCHECK(!releasedMailboxInfo->m_imageInfo); |
| 960 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 970 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 961 if (syncToken.HasData()) { | 971 if (syncToken.HasData()) { |
| 962 contextGL()->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); | 972 contextGL()->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); |
| 963 } | 973 } |
| 964 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); | 974 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); |
| 965 if (texture) { | 975 if (texture) { |
| 966 if (lostResource) { | 976 if (lostResource) { |
| 967 texture->abandon(); | 977 texture->abandon(); |
| 968 } else { | 978 } else { |
| 969 texture->textureParamsModified(); | 979 texture->textureParamsModified(); |
| 970 // Break the mailbox association to avoid leaking mailboxes every time
skia recycles a texture. | 980 // Break the mailbox association to avoid leaking mailboxes every time |
| 981 // skia recycles a texture. |
| 971 gpu::gles2::GLES2Interface* gl = contextGL(); | 982 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 972 if (gl) | 983 if (gl) |
| 973 gl->ProduceTextureDirectCHROMIUM( | 984 gl->ProduceTextureDirectCHROMIUM( |
| 974 0, GL_TEXTURE_2D, releasedMailboxInfo->m_mailbox.name); | 985 0, GL_TEXTURE_2D, releasedMailboxInfo->m_mailbox.name); |
| 975 } | 986 } |
| 976 } | 987 } |
| 977 } | 988 } |
| 978 | 989 |
| 979 #if USE_IOSURFACE_FOR_2D_CANVAS | 990 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 980 if (releasedMailboxInfo->m_imageInfo && !lostResource) { | 991 if (releasedMailboxInfo->m_imageInfo && !lostResource) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 default; | 1122 default; |
| 1112 | 1123 |
| 1113 void Canvas2DLayerBridge::Logger::reportHibernationEvent( | 1124 void Canvas2DLayerBridge::Logger::reportHibernationEvent( |
| 1114 HibernationEvent event) { | 1125 HibernationEvent event) { |
| 1115 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, | 1126 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, |
| 1116 ("Canvas.HibernationEvents", HibernationEventCount)); | 1127 ("Canvas.HibernationEvents", HibernationEventCount)); |
| 1117 hibernationHistogram.count(event); | 1128 hibernationHistogram.count(event); |
| 1118 } | 1129 } |
| 1119 | 1130 |
| 1120 } // namespace blink | 1131 } // namespace blink |
| OLD | NEW |