Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Unified Diff: third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp

Issue 2026803002: Avoid GPU readback in tex(Sub)Image2D(ImageBitmap) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address kbr@'s comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698