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

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: should work Created 4 years, 7 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
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 ac88b3d3d8c066136131b2f7aa9719f45976c96e..c20d35c3fa2705c36e700a2aeadb782cf56a0184 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"
namespace blink {
@@ -42,6 +43,8 @@ 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());
}
@@ -66,28 +69,21 @@ void StaticBitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const Float
observer->didDraw(this);
}
-PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame()
+void StaticBitmapImage::consumeTextureMailbox(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.
- OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
if (!provider)
- return nullptr;
+ return;
GrContext* grContext = provider->grContext();
if (!grContext)
- return nullptr;
+ return;
gpu::gles2::GLES2Interface* gl = provider->contextGL();
if (!gl)
- return nullptr;
+ return;
gl->WaitSyncTokenCHROMIUM(m_mailbox.syncToken);
- GLuint textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
+ m_textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
Ken Russell (switch to Gerrit) 2016/06/01 22:55:09 Is it legal to cache this value in StaticBitmapIma
xidachen 2016/06/02 13:52:52 I re-organized the structure of the imageForCurren
GrGLTextureInfo textureInfo;
textureInfo.fTarget = GL_TEXTURE_2D;
- textureInfo.fID = textureId;
+ textureInfo.fID = m_textureId;
GrBackendTextureDesc backendTexture;
backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
backendTexture.fWidth = m_mailbox.textureSize.width;
@@ -96,6 +92,74 @@ PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame()
backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textureInfo);
sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendTexture);
m_image = fromSkSp(skImage);
+}
+
+void StaticBitmapImage::copyTexture(WebGraphicsContext3DProvider* provider, GLuint texture, GLenum internalFormat, GLenum destType)
+{
+ gpu::gles2::GLES2Interface* gl = provider->contextGL();
+ if (!gl)
+ return;
+ gl->CopyTextureCHROMIUM(m_textureId, texture, internalFormat, destType, false, false, false);
+ const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
+ gl->Flush();
+ GLbyte syncToken[24];
+ gl->GenSyncTokenCHROMIUM(fenceSync, syncToken);
+}
+
+bool StaticBitmapImage::prepareMailboxForSkImage(WebGraphicsContext3DProvider* provider)
+{
+ m_mailbox.textureSize = WebSize(m_image->width(), m_image->height());
+ GrContext* grContext = m_provider->grContext();
+ if (!grContext)
+ return false;
+ grContext->flush();
+ m_image->getTexture()->textureParamsModified();
+ m_mailbox.textureTarget = GL_TEXTURE_2D;
+ gpu::gles2::GLES2Interface* gl = m_provider->contextGL();
+ if (!gl)
+ return false;
+ GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true))->fID;
+ gl->BindTexture(GL_TEXTURE_2D, textureID);
+
+ // Re-use the texture's existing mailbox, if there is one.
+ if (m_image->getTexture()->getCustomData()) {
+ DCHECK(m_image->getTexture()->getCustomData()->size() == sizeof(m_mailbox.name));
+ memcpy(&m_mailbox.name[0], m_image->getTexture()->getCustomData()->data(), sizeof(m_mailbox.name));
+ } else {
+ gl->GenMailboxCHROMIUM(m_mailbox.name);
+ RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&m_mailbox.name[0], sizeof(m_mailbox.name)));
+ m_image->getTexture()->setCustomData(mailboxNameData.get());
+ 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;
+}
+
+// There are four cases depending on whether m_image == nullptr && contextProvider == nullptr.
+PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame(WebGraphicsContext3DProvider* contextProvider)
+{
+ if (m_image && (!m_image->isTextureBacked() || !contextProvider || !m_provider))
+ return m_image;
+ if (!m_image) {
+ if (!contextProvider) {
+ DCHECK(isMainThread());
+ // TODO(xidachen): make this work on a worker thread.
+ OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+ consumeTextureMailbox(provider.get());
+ m_provider = std::move(provider);
+ } else {
+ consumeTextureMailbox(contextProvider);
+ }
+ return m_image;
+ }
+ if (!prepareMailboxForSkImage(contextProvider))
+ return m_image;
+ consumeTextureMailbox(contextProvider);
return m_image;
}

Powered by Google App Engine
This is Rietveld 408576698