| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 namespace { | 51 namespace { |
| 52 enum { | 52 enum { |
| 53 InvalidMailboxIndex = -1, | 53 InvalidMailboxIndex = -1, |
| 54 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t
wo animation frames behind. | 54 MaxCanvasAnimationBacklog = 2, // Make sure the the GPU is never more than t
wo animation frames behind. |
| 55 }; | 55 }; |
| 56 } // namespace | 56 } // namespace |
| 57 | 57 |
| 58 namespace blink { | 58 namespace blink { |
| 59 | 59 |
| 60 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size,
int msaaSampleCount, OpacityMode opacityMode, bool* surfaceIsAccelerated) | 60 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size,
int msaaSampleCount, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace, b
ool* surfaceIsAccelerated) |
| 61 { | 61 { |
| 62 if (gr) | 62 if (gr) |
| 63 gr->resetContext(); | 63 gr->resetContext(); |
| 64 | 64 |
| 65 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre
mul_SkAlphaType; | 65 SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPre
mul_SkAlphaType; |
| 66 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy
pe); | 66 SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaTy
pe, colorSpace); |
| 67 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); | 67 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); |
| 68 sk_sp<SkSurface> surface; | 68 sk_sp<SkSurface> surface; |
| 69 | 69 |
| 70 if (gr) { | 70 if (gr) { |
| 71 *surfaceIsAccelerated = true; | 71 *surfaceIsAccelerated = true; |
| 72 surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSam
pleCount, Opaque == opacityMode ? 0 : &disableLCDProps); | 72 surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSam
pleCount, Opaque == opacityMode ? 0 : &disableLCDProps); |
| 73 } | 73 } |
| 74 | 74 |
| 75 if (!surface) { | 75 if (!surface) { |
| 76 *surfaceIsAccelerated = false; | 76 *surfaceIsAccelerated = false; |
| 77 surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disab
leLCDProps); | 77 surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disab
leLCDProps); |
| 78 } | 78 } |
| 79 | 79 |
| 80 if (surface) { | 80 if (surface) { |
| 81 if (opacityMode == Opaque) { | 81 if (opacityMode == Opaque) { |
| 82 surface->getCanvas()->clear(SK_ColorBLACK); | 82 surface->getCanvas()->clear(SK_ColorBLACK); |
| 83 } else { | 83 } else { |
| 84 surface->getCanvas()->clear(SK_ColorTRANSPARENT); | 84 surface->getCanvas()->clear(SK_ColorTRANSPARENT); |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 return fromSkSp(surface); | 87 return fromSkSp(surface); |
| 88 } | 88 } |
| 89 | 89 |
| 90 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size,
int msaaSampleCount, OpacityMode opacityMode, AccelerationMode accelerationMode
) | 90 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size,
int msaaSampleCount, OpacityMode opacityMode, AccelerationMode accelerationMode
, sk_sp<SkColorSpace> colorSpace) |
| 91 { | 91 { |
| 92 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_
SCOPE_GLOBAL); | 92 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_
SCOPE_GLOBAL); |
| 93 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P
latform::current()->createSharedOffscreenGraphicsContext3DProvider()); | 93 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(P
latform::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| 94 if (!contextProvider) | 94 if (!contextProvider) |
| 95 return nullptr; | 95 return nullptr; |
| 96 RefPtr<Canvas2DLayerBridge> layerBridge; | 96 RefPtr<Canvas2DLayerBridge> layerBridge; |
| 97 layerBridge = adoptRef(new Canvas2DLayerBridge(std::move(contextProvider), s
ize, msaaSampleCount, opacityMode, accelerationMode)); | 97 layerBridge = adoptRef(new Canvas2DLayerBridge(std::move(contextProvider), s
ize, msaaSampleCount, opacityMode, accelerationMode, std::move(colorSpace))); |
| 98 return layerBridge.release(); | 98 return layerBridge.release(); |
| 99 } | 99 } |
| 100 | 100 |
| 101 Canvas2DLayerBridge::Canvas2DLayerBridge(std::unique_ptr<WebGraphicsContext3DPro
vider> contextProvider, const IntSize& size, int msaaSampleCount, OpacityMode op
acityMode, AccelerationMode accelerationMode) | 101 Canvas2DLayerBridge::Canvas2DLayerBridge(std::unique_ptr<WebGraphicsContext3DPro
vider> contextProvider, const IntSize& size, int msaaSampleCount, OpacityMode op
acityMode, AccelerationMode accelerationMode, sk_sp<SkColorSpace> colorSpace) |
| 102 : m_contextProvider(std::move(contextProvider)) | 102 : m_contextProvider(std::move(contextProvider)) |
| 103 , m_logger(wrapUnique(new Logger)) | 103 , m_logger(wrapUnique(new Logger)) |
| 104 , m_weakPtrFactory(this) | 104 , m_weakPtrFactory(this) |
| 105 , m_imageBuffer(0) | 105 , m_imageBuffer(0) |
| 106 , m_msaaSampleCount(msaaSampleCount) | 106 , m_msaaSampleCount(msaaSampleCount) |
| 107 , m_bytesAllocated(0) | 107 , m_bytesAllocated(0) |
| 108 , m_haveRecordedDrawCommands(false) | 108 , m_haveRecordedDrawCommands(false) |
| 109 , m_destructionInProgress(false) | 109 , m_destructionInProgress(false) |
| 110 , m_filterQuality(kLow_SkFilterQuality) | 110 , m_filterQuality(kLow_SkFilterQuality) |
| 111 , m_isHidden(false) | 111 , m_isHidden(false) |
| 112 , m_isDeferralEnabled(true) | 112 , m_isDeferralEnabled(true) |
| 113 , m_isRegisteredTaskObserver(false) | 113 , m_isRegisteredTaskObserver(false) |
| 114 , m_renderingTaskCompletedForCurrentFrame(false) | 114 , m_renderingTaskCompletedForCurrentFrame(false) |
| 115 , m_softwareRenderingWhileHidden(false) | 115 , m_softwareRenderingWhileHidden(false) |
| 116 , m_lastImageId(0) | 116 , m_lastImageId(0) |
| 117 , m_lastFilter(GL_LINEAR) | 117 , m_lastFilter(GL_LINEAR) |
| 118 , m_accelerationMode(accelerationMode) | 118 , m_accelerationMode(accelerationMode) |
| 119 , m_opacityMode(opacityMode) | 119 , m_opacityMode(opacityMode) |
| 120 , m_size(size) | 120 , m_size(size) |
| 121 , m_colorSpace(colorSpace) |
| 121 { | 122 { |
| 122 DCHECK(m_contextProvider); | 123 DCHECK(m_contextProvider); |
| 123 // Used by browser tests to detect the use of a Canvas2DLayerBridge. | 124 // Used by browser tests to detect the use of a Canvas2DLayerBridge. |
| 124 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_
SCOPE_GLOBAL); | 125 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_
SCOPE_GLOBAL); |
| 125 startRecording(); | 126 startRecording(); |
| 126 } | 127 } |
| 127 | 128 |
| 128 Canvas2DLayerBridge::~Canvas2DLayerBridge() | 129 Canvas2DLayerBridge::~Canvas2DLayerBridge() |
| 129 { | 130 { |
| 130 DCHECK(m_destructionInProgress); | 131 DCHECK(m_destructionInProgress); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 return false; | 210 return false; |
| 210 | 211 |
| 211 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu
reHandle(true))->fID; | 212 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu
reHandle(true))->fID; |
| 212 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0,
m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 213 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0,
m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); |
| 213 | 214 |
| 214 MailboxInfo& info = m_mailboxes.first(); | 215 MailboxInfo& info = m_mailboxes.first(); |
| 215 info.m_mailbox.textureTarget = GC3D_TEXTURE_RECTANGLE_ARB; | 216 info.m_mailbox.textureTarget = GC3D_TEXTURE_RECTANGLE_ARB; |
| 216 gl->GenMailboxCHROMIUM(info.m_mailbox.name); | 217 gl->GenMailboxCHROMIUM(info.m_mailbox.name); |
| 217 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, info.m_mailbox.textu
reTarget, info.m_mailbox.name); | 218 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, info.m_mailbox.textu
reTarget, info.m_mailbox.name); |
| 218 info.m_mailbox.allowOverlay = true; | 219 info.m_mailbox.allowOverlay = true; |
| 220 info.m_mailbox.colorSpace = m_colorSpace; |
| 219 | 221 |
| 220 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 222 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| 221 gl->Flush(); | 223 gl->Flush(); |
| 222 gl->GenSyncTokenCHROMIUM(fenceSync, info.m_mailbox.syncToken); | 224 gl->GenSyncTokenCHROMIUM(fenceSync, info.m_mailbox.syncToken); |
| 223 info.m_mailbox.validSyncToken = true; | 225 info.m_mailbox.validSyncToken = true; |
| 224 | 226 |
| 225 info.m_imageInfo = imageInfo; | 227 info.m_imageInfo = imageInfo; |
| 226 *outMailbox = info.m_mailbox; | 228 *outMailbox = info.m_mailbox; |
| 227 | 229 |
| 228 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); | 230 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode)
; | 325 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode)
; |
| 324 | 326 |
| 325 // Need to flush skia's internal queue because texture is about to be access
ed directly | 327 // Need to flush skia's internal queue because texture is about to be access
ed directly |
| 326 grContext->flush(); | 328 grContext->flush(); |
| 327 | 329 |
| 328 // Because of texture sharing with the compositor, we must invalidate | 330 // Because of texture sharing with the compositor, we must invalidate |
| 329 // the state cached in skia so that the deferred copy on write | 331 // the state cached in skia so that the deferred copy on write |
| 330 // in SkSurface_Gpu does not make any false assumptions. | 332 // in SkSurface_Gpu does not make any false assumptions. |
| 331 mailboxInfo.m_image->getTexture()->textureParamsModified(); | 333 mailboxInfo.m_image->getTexture()->textureParamsModified(); |
| 332 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D; | 334 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D; |
| 335 mailboxInfo.m_mailbox.colorSpace = m_colorSpace.get(); |
| 333 | 336 |
| 334 gpu::gles2::GLES2Interface* gl = contextGL(); | 337 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 335 if (!gl) | 338 if (!gl) |
| 336 return false; | 339 return false; |
| 337 | 340 |
| 338 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag
e->getTextureHandle(true))->fID; | 341 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag
e->getTextureHandle(true))->fID; |
| 339 gl->BindTexture(GL_TEXTURE_2D, textureID); | 342 gl->BindTexture(GL_TEXTURE_2D, textureID); |
| 340 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter()); | 343 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter()); |
| 341 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter()); | 344 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter()); |
| 342 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 345 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 return nullptr; // re-creation will happen through restore() | 473 return nullptr; // re-creation will happen through restore() |
| 471 } | 474 } |
| 472 | 475 |
| 473 bool wantAcceleration = shouldAccelerate(hint); | 476 bool wantAcceleration = shouldAccelerate(hint); |
| 474 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati
on) { | 477 if (CANVAS2D_BACKGROUND_RENDER_SWITCH_TO_CPU && isHidden() && wantAccelerati
on) { |
| 475 wantAcceleration = false; | 478 wantAcceleration = false; |
| 476 m_softwareRenderingWhileHidden = true; | 479 m_softwareRenderingWhileHidden = true; |
| 477 } | 480 } |
| 478 | 481 |
| 479 bool surfaceIsAccelerated; | 482 bool surfaceIsAccelerated; |
| 480 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext(
) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, &surfaceIsAccelerated); | 483 m_surface = createSkSurface(wantAcceleration ? m_contextProvider->grContext(
) : nullptr, m_size, m_msaaSampleCount, m_opacityMode, m_colorSpace, &surfaceIsA
ccelerated); |
| 481 | 484 |
| 482 if (!m_surface) | 485 if (!m_surface) |
| 483 reportSurfaceCreationFailure(); | 486 reportSurfaceCreationFailure(); |
| 484 | 487 |
| 485 if (m_surface && surfaceIsAccelerated && !m_layer) { | 488 if (m_surface && surfaceIsAccelerated && !m_layer) { |
| 486 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt
ernalTextureLayer(this)); | 489 m_layer = wrapUnique(Platform::current()->compositorSupport()->createExt
ernalTextureLayer(this)); |
| 487 m_layer->setOpaque(m_opacityMode == Opaque); | 490 m_layer->setOpaque(m_opacityMode == Opaque); |
| 488 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); | 491 m_layer->setBlendBackgroundColor(m_opacityMode != Opaque); |
| 489 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 492 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
| 490 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 493 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 | 750 |
| 748 gpu::gles2::GLES2Interface* sharedGL = nullptr; | 751 gpu::gles2::GLES2Interface* sharedGL = nullptr; |
| 749 m_layer->clearTexture(); | 752 m_layer->clearTexture(); |
| 750 m_contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGra
phicsContext3DProvider()); | 753 m_contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGra
phicsContext3DProvider()); |
| 751 if (m_contextProvider) | 754 if (m_contextProvider) |
| 752 sharedGL = m_contextProvider->contextGL(); | 755 sharedGL = m_contextProvider->contextGL(); |
| 753 | 756 |
| 754 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { | 757 if (sharedGL && sharedGL->GetGraphicsResetStatusKHR() == GL_NO_ERROR) { |
| 755 GrContext* grCtx = m_contextProvider->grContext(); | 758 GrContext* grCtx = m_contextProvider->grContext(); |
| 756 bool surfaceIsAccelerated; | 759 bool surfaceIsAccelerated; |
| 757 RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCou
nt, m_opacityMode, &surfaceIsAccelerated)); | 760 RefPtr<SkSurface> surface(createSkSurface(grCtx, m_size, m_msaaSampleCou
nt, m_opacityMode, m_colorSpace, &surfaceIsAccelerated)); |
| 758 | 761 |
| 759 if (!m_surface) | 762 if (!m_surface) |
| 760 reportSurfaceCreationFailure(); | 763 reportSurfaceCreationFailure(); |
| 761 | 764 |
| 762 // Current paradigm does support switching from accelerated to non-accel
erated, which would be tricky | 765 // Current paradigm does support switching from accelerated to non-accel
erated, which would be tricky |
| 763 // due to changes to the layer tree, which can only happen at specific t
imes during the document lifecycle. | 766 // due to changes to the layer tree, which can only happen at specific t
imes during the document lifecycle. |
| 764 // Therefore, we can only accept the restored surface if it is accelerat
ed. | 767 // Therefore, we can only accept the restored surface if it is accelerat
ed. |
| 765 if (surface && surfaceIsAccelerated) { | 768 if (surface && surfaceIsAccelerated) { |
| 766 m_surface = surface.release(); | 769 m_surface = surface.release(); |
| 767 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 | 770 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 995 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 993 } | 996 } |
| 994 | 997 |
| 995 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) | 998 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) |
| 996 { | 999 { |
| 997 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib
ernationEvents", HibernationEventCount)); | 1000 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib
ernationEvents", HibernationEventCount)); |
| 998 hibernationHistogram.count(event); | 1001 hibernationHistogram.count(event); |
| 999 } | 1002 } |
| 1000 | 1003 |
| 1001 } // namespace blink | 1004 } // namespace blink |
| OLD | NEW |