| 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..3d85460343ee69b82b0ae05d01995c03eb727b2f 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,85 @@ 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 destinationTexture, GLenum internalFormat, GLenum destType, bool flipY)
|
| +{
|
| + GLuint textureId = textureIdForWebGL(provider);
|
| + 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());
|
| + if (!switchStorageToSkImage(sharedProvider.get()))
|
| + return nullptr;
|
| return m_image;
|
| }
|
|
|
|
|