Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp |
| index aa45be3a01e44effe6753dd2faabf2521862b325..36262d30efc748ca4d507e89ad355d1b2588fcd4 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp |
| @@ -14,6 +14,7 @@ |
| #include "third_party/skia/include/core/SkImage.h" |
| #include "third_party/skia/include/core/SkPaint.h" |
| #include "third_party/skia/include/core/SkShader.h" |
| +#include "third_party/skia/include/gpu/GrContext.h" |
| #include "wtf/PtrUtil.h" |
| #include <memory> |
| @@ -44,9 +45,16 @@ StaticBitmapImage::~StaticBitmapImage() { } |
| IntSize StaticBitmapImage::size() const |
| { |
| + if (!m_image) |
| + return IntSize(m_mailbox.textureSize.width, m_mailbox.textureSize.height); |
| return IntSize(m_image->width(), m_image->height()); |
| } |
| +bool StaticBitmapImage::isTextureBacked() |
| +{ |
| + return m_image && m_image->isTextureBacked(); |
| +} |
| + |
| bool StaticBitmapImage::currentFrameKnownToBeOpaque(MetadataMode) |
| { |
| return m_image->isOpaque(); |
| @@ -68,23 +76,16 @@ void StaticBitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const Float |
| observer->didDraw(this); |
| } |
| -PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame() |
| +GLuint StaticBitmapImage::switchStorageToSkImage(WebGraphicsContext3DProvider* provider) |
| { |
| - if (m_image) |
| - return m_image; |
| - DCHECK(isMainThread()); |
| - // In the place when we consume an ImageBitmap that is gpu texture backed, |
| - // create a new SkImage from that texture. |
| - // TODO(xidachen): make this work on a worker thread. |
| - std::unique_ptr<WebGraphicsContext3DProvider> provider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| if (!provider) |
| - return nullptr; |
| + return 0; |
| GrContext* grContext = provider->grContext(); |
| if (!grContext) |
| - return nullptr; |
| + return 0; |
| gpu::gles2::GLES2Interface* gl = provider->contextGL(); |
| if (!gl) |
| - return nullptr; |
| + return 0; |
| gl->WaitSyncTokenCHROMIUM(m_mailbox.syncToken); |
| GLuint textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| GrGLTextureInfo textureInfo; |
| @@ -98,6 +99,83 @@ PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame() |
| backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textureInfo); |
| sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendTexture); |
| m_image = fromSkSp(skImage); |
| + return textureId; |
| +} |
| + |
| +void StaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* provider, GLuint textureId, GLuint destinationTexture, GLenum internalFormat, GLenum destType, bool flipY) |
| +{ |
| + gpu::gles2::GLES2Interface* gl = provider->contextGL(); |
| + if (!gl) |
| + return; |
| + gl->CopyTextureCHROMIUM(textureId, destinationTexture, internalFormat, destType, flipY, false, false); |
| + const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| + gl->Flush(); |
| + GLbyte syncToken[24]; |
| + gl->GenSyncTokenCHROMIUM(fenceSync, syncToken); |
| +} |
| + |
| +bool StaticBitmapImage::switchStorageToMailbox(WebGraphicsContext3DProvider* provider) |
| +{ |
| + m_mailbox.textureSize = WebSize(m_image->width(), m_image->height()); |
| + GrContext* grContext = provider->grContext(); |
| + if (!grContext) |
| + return false; |
| + grContext->flush(); |
| + m_mailbox.textureTarget = GL_TEXTURE_2D; |
| + gpu::gles2::GLES2Interface* gl = provider->contextGL(); |
| + if (!gl) |
| + return false; |
| + GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true))->fID; |
| + gl->BindTexture(GL_TEXTURE_2D, textureID); |
| + |
| + gl->GenMailboxCHROMIUM(m_mailbox.name); |
| + gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| + const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| + gl->Flush(); |
| + gl->GenSyncTokenCHROMIUM(fenceSync, m_mailbox.syncToken); |
| + m_mailbox.validSyncToken = true; |
| + gl->BindTexture(GL_TEXTURE_2D, 0); |
| + grContext->resetContext(kTextureBinding_GrGLBackendState); |
| + return true; |
| +} |
| + |
| +// This function is called only in the case that m_image is texture backed. |
| +GLuint StaticBitmapImage::textureIdForWebGL(WebGraphicsContext3DProvider* contextProvider) |
| +{ |
| + DCHECK(!m_image || m_image->isTextureBacked()); |
| + GLuint textureId = 0; |
| + if (m_image) { |
| + // SkImage is texture-backed on the shared context |
| + if (!hasMailbox()) { |
| + std::unique_ptr<WebGraphicsContext3DProvider> sharedProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| + if (!switchStorageToMailbox(sharedProvider.get())) |
| + return 0; |
| + textureId = switchStorageToSkImage(contextProvider); |
| + // Get a new mailbox because we cannot retain a texture in the WebGL context. |
| + if (!switchStorageToMailbox(contextProvider)) |
| + return 0; |
| + return textureId; |
| + } |
| + } |
| + DCHECK(hasMailbox()); |
| + textureId = switchStorageToSkImage(contextProvider); |
| + if (!switchStorageToMailbox(contextProvider)) |
| + return 0; |
| + return textureId; |
| +} |
| + |
| +PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame() |
| +{ |
| + if (m_image) |
| + return m_image; |
| + // No mailbox, return null; |
| + if (!hasMailbox()) |
| + return nullptr; |
| + // Has mailbox, consume mailbox, prepare a new mailbox if contextProvider is not null (3D). |
| + DCHECK(isMainThread()); |
| + // TODO(xidachen): make this work on a worker thread. |
| + std::unique_ptr<WebGraphicsContext3DProvider> sharedProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| + switchStorageToSkImage(sharedProvider.get()); |
|
Ken Russell (switch to Gerrit)
2016/06/24 01:25:10
What happens if switchStorageToSkImage returns 0?
xidachen
2016/06/24 14:36:07
Change it to return nullptr in that case.
|
| return m_image; |
| } |